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

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

이 공격 벡터는 public-facing PR workflow가 약한 webhook 제어를 가진 privileged CodeBuild project에 연결되어 있을 때 발생합니다.

외부 공격자가 CodeBuild로 하여금 자신의 pull request를 실행하게 만들 수 있다면, 일반적으로 arbitrary code execution inside the build (build scripts, dependency hooks, test scripts 등)을 얻고, 이후 secrets, IAM credentials, 또는 source-provider credentials로 피벗할 수 있습니다.

왜 이것이 위험한가

CodeBuild webhook 필터는 regex 패턴으로 평가됩니다 (non-EVENT 필터의 경우). ACTOR_ACCOUNT_ID 필터에서는 약한 패턴이 의도보다 더 많은 사용자를 매치할 수 있습니다. 신뢰할 수 없는 PR이 권한 있는 AWS role 권한 또는 GitHub 자격증명을 가진 프로젝트에서 빌드되면, 이는 전체 공급망(supply-chain) 침해로 이어질 수 있습니다.

Wiz는 다음과 같은 실전 체인을 보여주었습니다:

  1. 웹훅 actor allowlist가 unanchored regex를 사용했다.
  2. 공격자가 신뢰된 ID의 superstring으로 매치되는 GitHub ID를 등록했다.
  3. 악성 PR이 CodeBuild를 트리거했다.
  4. 빌드 코드 실행을 이용해 메모리를 덤프하고 source-provider credentials/tokens를 복구했다.

외부 PR 코드 실행을 허용하는 잘못된 구성

다음은 고위험 실수들과 공격자가 각 실수를 악용하는 방식입니다:

  1. EVENT filters allow untrusted triggers
  • 일반적으로 위험한 이벤트: PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, PULL_REQUEST_REOPENED.
  • 권한 있는 빌드에 연결되면 위험해질 수 있는 기타 이벤트: PUSH, PULL_REQUEST_CLOSED, PULL_REQUEST_MERGED, RELEASED, PRERELEASED, WORKFLOW_JOB_QUEUED.
  • Bad: EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED" (권한 있는 프로젝트에서).
  • Better: 권한 있는 프로젝트의 경우 PR 코멘트 승인 사용 및 트리거 이벤트 최소화.
  • Abuse: 공격자는 자신이 제어하는 브랜치에 대해 PR을 열거나 업데이트하거나 푸시하여 CodeBuild에서 자신의 코드를 실행시킵니다.
  1. ACTOR_ACCOUNT_ID regex is weak
  • Bad: 123456|7890123 같은 unanchored 패턴.
  • Better: 정확히 매치하도록 앵커 사용 ^(123456|7890123)$.
  • Abuse: regex의 과도한 매치로 인해 권한 없는 GitHub ID가 allowlist를 통과합니다.
  1. Other regex filters are weak or missing
  • HEAD_REF
    • Bad: refs/heads/.*
    • Better: ^refs/heads/main$ (또는 명시적 신뢰 목록)
  • BASE_REF
    • Bad: .*
    • Better: ^refs/heads/main$
  • FILE_PATH
    • Bad: 경로 제한 없음
    • Better: ^buildspec\\.yml$, ^\\.github/workflows/.*, (^|/)package(-lock)?\\.json$와 같이 위험한 파일 제외
  • COMMIT_MESSAGE
    • Bad: 느슨한 매치로 신뢰 마커 사용 (예: trusted)
    • Better: 커밋 메시지를 PR 실행의 신뢰 경계로 사용하지 않음
  • REPOSITORY_NAME / ORGANIZATION_NAME
    • Bad: org/global webhook에 .*
    • Better: 오직 정확한 repo/org 매치만 허용
  • WORKFLOW_NAME
    • Bad: .*
    • Better: 정확한 workflow 이름 매치만 허용 (또는 이를 신뢰 제어로 사용하지 않음)
  • Abuse: 공격자는 permissive한 regex를 통과하도록 ref/path/message/repo 컨텍스트를 조작하여 빌드를 트리거합니다.
  1. excludeMatchedPattern is misused
  • 이 플래그를 잘못 설정하면 의도한 논리가 반전될 수 있습니다.
  • Bad: FILE_PATH '^buildspec\\.yml$'에 대해 의도는 buildspec 편집을 차단하는 것인데 excludeMatchedPattern=false로 설정한 경우.
  • Better: 같은 패턴에 excludeMatchedPattern=true로 설정하여 buildspec.yml을 건드리는 빌드를 거부.
  • Abuse: 방어자는 위험한 이벤트/경로/액터를 차단한다고 생각하지만 실제로는 허용하고 있을 수 있습니다.
  1. Multiple filterGroups create accidental bypasses
  • CodeBuild는 그룹을 OR로 평가합니다 (하나의 그룹만 통과하면 충분).
  • Bad: 엄격한 그룹 하나 + 완화된 폴백 그룹 하나(예: EVENT=PULL_REQUEST_UPDATED만 있음).
  • Better: 액터/레퍼런스/경로 제약을 시행하지 않는 폴백 그룹 제거.
  • Abuse: 공격자는 가장 약한 그룹만 만족시키면 됩니다.
  1. Comment approval gate disabled or too permissive
  • pullRequestBuildPolicy.requiresCommentApproval=DISABLED는 가장 안전하지 않습니다.
  • 지나치게 넓은 승인자 역할은 통제를 약화시킵니다.
  • Bad: requiresCommentApproval=DISABLED.
  • Better: ALL_PULL_REQUESTS 또는 FORK_PULL_REQUESTS와 최소한의 승인자 역할 사용.
  • Abuse: 포크/드라이브바이 PR이 신뢰된 유지보수자의 승인 없이 자동 실행됩니다.
  1. No restrictive branch/path strategy for PR builds
  • HEAD_REF + BASE_REF + FILE_PATH로 방어층을 구성하지 않음.
  • Bad: EVENT + ACTOR_ACCOUNT_ID만 있고 ref/path 제약 없음.
  • Better: 정확한 ACTOR_ACCOUNT_ID + BASE_REF + HEAD_REF + FILE_PATH 제한을 조합.
  • Abuse: 공격자는 build inputs(buildspec/CI/dependencies 등)을 수정하여 임의의 명령 실행을 얻습니다.
  1. Public visibility + status URL exposure
  • 공개된 빌드/체크 URL은 공격자에게 리컨(recon) 및 반복 테스트 기회를 제공합니다.
  • Bad: projectVisibility=PUBLIC_READ에 민감한 로그/구성이 공개된 경우.
  • Better: 비즈니스 요구가 강력하지 않다면 프로젝트를 비공개로 유지하고, 로그/아티팩트를 정리(sanitize)합니다.
  • Abuse: 공격자는 프로젝트 패턴/동작을 발견하고 페이로드와 우회 시도를 조정합니다.

Token leakage from memory

Wiz의 글은 source-provider credentials가 빌드 런타임 컨텍스트에 존재하며 빌드가 손상된 이후(예: memory dumping을 통해) 탈취될 수 있다는 점을 설명합니다. 권한 범위가 넓다면 이는 리포지토리 takeover로 이어질 수 있습니다.

AWS는 공개 이후 하드닝을 도입했지만, 핵심 교훈은 변하지 않습니다: never execute untrusted PR code in privileged build contexts 그리고 공격자가 제어하는 빌드 코드는 자격증명 탈취를 시도할 것이라고 가정하십시오.

추가적인 CodeBuild 내 자격증명 절취 기법은 다음을 참조하세요:

AWS Codebuild - Token Leakage

Finding CodeBuild URLs in GitHub PRs

CodeBuild가 커밋 상태를 GitHub에 리포트하는 경우, CodeBuild 빌드 URL은 보통 다음 위치에 나타납니다:

  1. PR page -> Checks 탭 (또는 Conversation/Commits의 상태 라인).
  2. Commit page -> status/checks 섹션 -> Details 링크.
  3. PR commits list -> 커밋에 붙은 체크 컨텍스트를 클릭.

공개 프로젝트의 경우, 이 링크는 인증되지 않은 사용자에게 빌드 메타데이터/구성을 노출할 수 있습니다.

스크립트: PR에서 CodeBuild URL을 감지하고 공개 여부를 테스트 ```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”

다음에서 테스트됨:
```bash
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1

빠른 감사 체크리스트

# 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

각 프로젝트에 대해 다음을 검토하세요:

  • webhook.filterGroups에 PR 이벤트가 포함되어 있는지.
  • ACTOR_ACCOUNT_ID 패턴이 ^...$로 앵커되어 있지 않은지.
  • pullRequestBuildPolicy.requiresCommentApprovalDISABLED로 설정되어 있는지.
  • 브랜치/경로 제한이 누락되어 있는지.
  • 권한이 높은 serviceRole 사용 여부.
  • 위험한 소스 자격증명 범위 및 재사용 여부.

하드닝 지침

  1. PR 빌드에 대해 코멘트 승인 요구 (ALL_PULL_REQUESTS 또는 FORK_PULL_REQUESTS).
  2. actor 허용 목록을 사용하는 경우, 정규식에 앵커(^...$)를 추가하고 정확히 일치시키세요.
  3. 신뢰할 수 없는 수정이 buildspec.yml 및 CI 스크립트에 반영되는 것을 방지하기 위해 FILE_PATH 제한을 추가하세요.
  4. 신뢰된 릴리스 빌드를 신뢰할 수 없는 PR 빌드와 별도의 프로젝트/역할로 분리하세요.
  5. 세분화된 최소권한의 source-provider 토큰을 사용하세요(전용 저권한 계정 권장).
  6. webhook 필터와 소스 자격증명 사용을 지속적으로 감사하세요.

References

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기