AWS CodeBuild - Untrusted PR Webhook Bypass (CodeBreach-style)

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks

Ten wektor ataku występuje, gdy public-facing PR workflow jest powiązany z uprzywilejowanym CodeBuild project przy słabej kontroli webhooków.

Jeśli zewnętrzny atakujący może spowodować, że CodeBuild wykona ich pull request, zazwyczaj uzyskuje arbitrary code execution inside the build (skrypty builda, hooki zależności, skrypty testowe itp.), a następnie pivotuje do sekretów, poświadczeń IAM lub poświadczeń dostawcy źródła.

Why this is dangerous

Filtry webhooków CodeBuild są ewaluowane przy użyciu wzorców regex (dla filtrów innych niż EVENT). W filtrze ACTOR_ACCOUNT_ID słaby wzorzec może dopasować więcej użytkowników niż zamierzono. Jeśli niezaufane PR są budowane w projekcie, który ma uprzywilejowane uprawnienia roli AWS lub poświadczenia GitHub, może to prowadzić do pełnego kompromisu łańcucha dostaw.

Wiz pokazał praktyczny łańcuch, gdzie:

  1. Whitelist aktorów webhooka używała unanchored regex.
  2. Atakujący zarejestrował GitHub ID, które dopasowywało się jako superstring zaufanego ID.
  3. Złośliwy PR wywołał CodeBuild.
  4. Wykorzystano wykonanie kodu w buildzie do zrzutu pamięci i odzyskania poświadczeń/tokens dostawcy źródła.

Misconfigurations that allow external PR code execution

Poniżej wysokiego ryzyka błędy konfiguracji i jak atakujący je wykorzystują:

  1. EVENT filters allow untrusted triggers
  • Często ryzykowne zdarzenia: PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, PULL_REQUEST_REOPENED.
  • Inne zdarzenia, które też mogą stać się niebezpieczne, jeśli powiązane z uprzywilejowanymi buildami: PUSH, PULL_REQUEST_CLOSED, PULL_REQUEST_MERGED, RELEASED, PRERELEASED, WORKFLOW_JOB_QUEUED.
  • Złe: EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED" w uprzywilejowanym projekcie.
  • Lepiej: używać akceptacji PR przez komentarz i minimalizować zdarzenia wyzwalające dla uprzywilejowanych projektów.
  • Nadużycie: atakujący otwiera/aktualizuje PR lub pushuje do gałęzi, którą kontroluje, i jego kod wykonuje się w CodeBuild.
  1. ACTOR_ACCOUNT_ID regex is weak
  • Złe: niezakotwiczone wzorce jak 123456|7890123.
  • Lepiej: exact-match anchoring ^(123456|7890123)$.
  • Nadużycie: nadmiarowe dopasowanie regex pozwala nieautoryzowanym GitHub ID przejść przez allowlistę.
  1. Other regex filters are weak or missing
  • HEAD_REF
    • Złe: refs/heads/.*
    • Lepiej: ^refs/heads/main$ (lub explicite lista zaufanych)
  • BASE_REF
    • Złe: .*
    • Lepiej: ^refs/heads/main$
  • FILE_PATH
    • Złe: brak ograniczeń ścieżek
    • Lepiej: wykluczać ryzykowne pliki, np. ^buildspec\\.yml$, ^\\.github/workflows/.*, (^|/)package(-lock)?\\.json$
  • COMMIT_MESSAGE
    • Złe: poleganie na marce zaufania z luźnym dopasowaniem jak trusted
    • Lepiej: nie używać wiadomości commit jako granicy zaufania dla wykonania PR
  • REPOSITORY_NAME / ORGANIZATION_NAME
    • Złe: .* w webhookach org/global
    • Lepiej: tylko dokładne dopasowania repo/org
  • WORKFLOW_NAME
    • Złe: .*
    • Lepiej: dokładne dopasowanie nazwy workflow (lub unikać tego jako mechanizmu kontroli zaufania)
  • Nadużycie: atakujący przygotowuje ref/path/message/repo context, który spełnia permisywne regexy i wyzwala buildy.
  1. excludeMatchedPattern is misused
  • Nieprawidłowe ustawienie tej flagi może odwrócić zamierzoną logikę.
  • Złe: FILE_PATH '^buildspec\\.yml$' z excludeMatchedPattern=false gdy intencją było zablokowanie edycji buildspec.
  • Lepiej: ten sam wzorzec z excludeMatchedPattern=true aby odmówić buildów dotykających buildspec.yml.
  • Nadużycie: obrońcy myślą, że zabraniają ryzykownych zdarzeń/ścieżek/aktorów, ale w rzeczywistości je zezwalają.
  1. Multiple filterGroups create accidental bypasses
  • CodeBuild ewaluował grupy jako OR (przejście jednej grupy wystarcza).
  • Złe: jedna restrykcyjna grupa + jedna permisywna grupa zapasowa (np. tylko EVENT=PULL_REQUEST_UPDATED).
  • Lepiej: usuń grupy zapasowe, które nie wymuszają ograniczeń aktora/ref/ścieżki.
  • Nadużycie: atakujący musi spełnić najsłabszą grupę.
  1. Comment approval gate disabled or too permissive
  • pullRequestBuildPolicy.requiresCommentApproval=DISABLED jest najmniej bezpieczne.
  • Zbyt szerokie role zatwierdzające redukują kontrolę.
  • Złe: requiresCommentApproval=DISABLED.
  • Lepiej: ALL_PULL_REQUESTS lub FORK_PULL_REQUESTS z minimalnymi rolami zatwierdzającymi.
  • Nadużycie: fork/drive-by PRy uruchamiają się automatycznie bez zatwierdzenia zaufanego maintenera.
  1. No restrictive branch/path strategy for PR builds
  • Brak defense-in-depth z HEAD_REF + BASE_REF + FILE_PATH.
  • Złe: tylko EVENT + ACTOR_ACCOUNT_ID, bez kontroli ref/path.
  • Lepiej: łączyć dokładne ACTOR_ACCOUNT_ID + BASE_REF + HEAD_REF + ograniczenia FILE_PATH.
  • Nadużycie: atakujący modyfikuje wejścia builda (buildspec/CI/zależności) i uzyskuje arbitrary command execution.
  1. Public visibility + status URL exposure
  • Public build/check URLs ułatwiają atakującemu rekonesans i iteracyjne testy.
  • Złe: projectVisibility=PUBLIC_READ z wrażliwymi logami/konfigiem w publicznych buildach.
  • Lepiej: trzymaj projekty prywatne, chyba że istnieje silna potrzeba biznesowa, i sanitize’uj logi/artefakty.
  • Nadużycie: atakujący odkrywa wzorce/behawior projektu, a następnie dopracowuje payloady i próby bypassu.

Token leakage from memory

Wiz’s write-up wyjaśnia, że poświadczenia dostawcy źródła są obecne w kontekście runtime builda i mogą zostać skradzione po kompromisie builda (na przykład poprzez zrzut pamięci), umożliwiając przejęcie repozytorium jeśli zakresy są szerokie.

AWS wprowadził hardening po ujawnieniu, ale główna lekcja pozostaje: nigdy nie wykonuj niezaufanego kodu PR w uprzywilejowanych kontekstach builda i zakładaj, że kod kontrolowany przez atakującego będzie próbował wykradać poświadczenia.

Dla dodatkowych technik kradzieży poświadczeń w CodeBuild, sprawdź także:

AWS Codebuild - Token Leakage

Finding CodeBuild URLs in GitHub PRs

Jeśli CodeBuild raportuje commit status z powrotem do GitHub, URL builda CodeBuild zwykle pojawia się w:

  1. PR page -> zakładka Checks (lub linia statusu w Conversation/Commits).
  2. Commit page -> sekcja status/checks -> link Details.
  3. PR commits list -> kliknij kontekst check przypięty do commita.

Dla publicznych projektów, ten link może ujawnić metadane/konfigurację builda nieautoryzowanym użytkownikom.

Script: detect CodeBuild URLs in a PR and test if they look public ```bash #!/usr/bin/env bash set -euo pipefail

Usage:

./check_pr_codebuild_urls.sh <pr_number>

Requirements: gh, jq, curl

OWNER=“${1:?owner}” REPO=“${2:?repo}” PR=“${3:?pr_number}”

for bin in gh jq curl timeout; do command -v “$bin” >/dev/null || { echo “[!] Missing dependency: $bin” >&2; exit 1; } done

tmp_commits=“$(mktemp)” tmp_urls=“$(mktemp)” trap ‘rm -f “$tmp_commits” “$tmp_urls”’ EXIT

gh_api() { timeout 20s gh api “$@” 2>/dev/null || true }

Get all commit SHAs in the PR (bounded call to avoid hangs)

gh_api “repos/${OWNER}/${REPO}/pulls/${PR}/commits” –paginate –jq ‘.[].sha’ > “$tmp_commits” if [ ! -s “$tmp_commits” ]; then echo “[!] No commits found (or API call timed out/failed).” >&2 exit 1 fi

echo “[*] PR commits:” cat “$tmp_commits” echo

echo “[*] Searching commit statuses/check-runs for CodeBuild URLs…”

while IFS= read -r sha; do [ -z “$sha” ] && continue

Classic commit statuses (target_url)

gh_api “repos/${OWNER}/${REPO}/commits/${sha}/status”
–jq ‘.statuses[]? | .target_url // empty’ 2>/dev/null || true

GitHub Checks API (details_url)

gh_api “repos/${OWNER}/${REPO}/commits/${sha}/check-runs”
–jq ‘.check_runs[]? | .details_url // empty’ 2>/dev/null || true done < “$tmp_commits” | sort -u > “$tmp_urls”

grep -Ei ‘codebuild|codebuild.aws.amazon.com|console.aws.amazon.com/.*/codebuild’ “$tmp_urls” || true

echo echo “[*] Public-access heuristic:” echo “ - If URL redirects to signin.aws.amazon.com -> likely not public“ echo “ - If URL is directly reachable (HTTP 200) without auth redirect -> potentially public“ echo

cb_urls=“$(grep -Ei ‘codebuild|codebuild.aws.amazon.com|console.aws.amazon.com/./codebuild’ “$tmp_urls” || true)“ if [ -z “$cb_urls” ]; then echo “[] No CodeBuild URLs found in PR statuses/check-runs.” exit 0 fi

while IFS= read -r url; do [ -z “$url” ] && continue final_url=“$(timeout 20s curl -4 -sS -L –connect-timeout 5 –max-time 20 -o /dev/null -w ‘%{url_effective}’ “$url” || true)“ code=“$(timeout 20s curl -4 -sS -L –connect-timeout 5 –max-time 20 -o /dev/null -w ‘%{http_code}’ “$url” || true)“

if echo “$final_url” | grep -qi ‘signin.aws.amazon.com’; then verdict=“NOT_PUBLIC_OR_AUTH_REQUIRED” elif [ “$code” = “200” ]; then verdict=“POTENTIALLY_PUBLIC” else verdict=“UNKNOWN_CHECK_MANUALLY” fi

printf ‘%s\t%s\t%s\n’ “$verdict” “$code” “$url” done <<< “$cb_urls”

Przetestowano z:
```bash
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1

Szybka lista kontrolna audytu

# Enumerate projects
aws codebuild list-projects

# Inspect source/webhook configuration
aws codebuild batch-get-projects --names <project-name>

# Inspect global source credentials configured in account
aws codebuild list-source-credentials

Sprawdź każdy projekt pod kątem:

  • webhook.filterGroups zawierające zdarzenia PR.
  • ACTOR_ACCOUNT_ID patterns that are not anchored with ^...$.
  • pullRequestBuildPolicy.requiresCommentApproval równe DISABLED.
  • Brak ograniczeń gałęzi/ścieżki.
  • serviceRole o wysokich uprawnieniach.
  • Ryzykowny zakres i ponowne użycie poświadczeń źródła.

Wytyczne utwardzania

  1. Wymagaj zatwierdzenia komentarzem dla buildów PR (ALL_PULL_REQUESTS lub FORK_PULL_REQUESTS).
  2. Jeśli używasz allowlist aktorów, zakotwicz regexy i trzymaj je dokładne.
  3. Dodaj ograniczenia FILE_PATH, aby uniknąć niezaufanych modyfikacji buildspec.yml i skryptów CI.
  4. Oddziel zaufane release builds od niezaufanych PR builds do różnych projektów/rol.
  5. Używaj drobnoziarnistych, najmniej uprzywilejowanych tokenów dostawcy źródła (preferuj dedykowane tożsamości o niskich uprawnieniach).
  6. Nieustannie audytuj filtry webhook i użycie poświadczeń źródła.

Referencje

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks