COMMENTS (0)
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
보안 스캐너 Trivy가 인포스틸러로 변했다. GitHub Actions 76개 태그를 오염시킨 TeamPCP의 공급망 공격 5일간의 연쇄 감염.
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
취약점 스캐너 Trivy는 GitHub 스타 33,800개, Docker Hub 다운로드 1억 회를 기록한 클라우드 네이티브 보안의 표준 도구다. 2026년 3월 19일, 이 도구가 인포스틸러로 변했다. 위협 그룹 TeamPCP가 Trivy의 GitHub Actions 태그 76개를 악성 커밋으로 덮어쓰고, Docker Hub와 PyPI까지 감염을 확산시킨 것이다.
보안을 위해 신뢰한 도구가 보안을 무너뜨린 도구가 됐다. 3월 24일 Microsoft가 탐지 및 대응 가이드를 공개했고, (CVSS 9.4)가 부여됐다.
사건의 시작은 2026년 2월 28일이다. hackerbot-claw라는 자율 봇이 Trivy 저장소의 pull_request_target 워크플로우 취약 설정을 악용했다. fork 저장소에서 PR을 열면 base 저장소의 시크릿에 접근할 수 있는 이 설정을 통해, Aqua Security의 aqua-bot 서비스 계정 PAT(Personal Access Token)를 탈취했다.
Aqua Security는 3월 1일 초기 대응으로 크리덴셜 로테이션을 수행했다. 그러나 이 로테이션은 비원자적(non-atomic)으로 진행됐다. 일부 자격증명이 유효한 상태로 남았고, TeamPCP는 3월 19일 이 잔존 PAT로 재공격에 성공했다.
| 날짜 | 침해 대상 |
|---|---|
| 3월 19일 | trivy-action 76개 태그 + setup-trivy 7개 태그 force-push |
| 3월 19일 | Trivy v0.69.4 악성 바이너리 GitHub Release 게시 |
| 3월 22일 | Docker Hub에 v0.69.5, v0.69.6 악성 이미지 푸시 |
| 3월 22일 | Aqua Security 내부 저장소 44개 삭제 및 훼손 |
| 3월 23일 | Checkmarx KICS GitHub Action 태그 35개 탈취 |
| 3월 24일 | LiteLLM 1.82.7, 1.82.8 악성 버전 PyPI 업로드 |
각 침해가 다음 침해의 열쇠가 됐다. Trivy CI 러너에서 Checkmarx 서비스 계정 PAT를 탈취하고, LiteLLM의 CI/CD 파이프라인이 버전 고정 없이 Trivy를 설치하면서 PYPI_PUBLISH 토큰이 유출됐다.
악성화된 Trivy는 정상적인 취약점 스캔을 완료하면서, 백그라운드에서 자격증명을 수집했다. 사용자는 스캔 결과를 정상적으로 받았기 때문에 이상을 감지할 수 없었다.
수집 — CI 러너의 Runner.Worker 프로세스 메모리에서 /proc/<pid>/mem을 직접 읽어 {"value":"<secret>","isSecret":true} 패턴을 추출했다. GitHub Actions의 로그 마스킹을 우회하는 기법이다. SSH 키, AWS/GCP/Azure 토큰, Kubernetes 서비스 계정, Docker 설정, Terraform state, Git 크리덴셜 등 50개 이상 경로를 스캔했다.
암호화 — AES-256-CBC + RSA-4096 OAEP 하이브리드 암호화로 tpcp.tar.gz에 아카이브했다.
유출 (1차로 HTTPS를 통해 C2 서버 scan.aquasecurtiy[.]org) 오타가 의도적)로 전송했다. 실패하면 피해자의 GitHub 계정에 tpcp-docs-* 이름의 공개 저장소를 자동 생성하고, 암호화된 자격증명을 릴리스 에셋으로 업로드했다.
TeamPCP는 개발자 머신에 영구 백도어도 설치했다. sysmon.service라는 이름의 systemd 유닛이 ICP(Internet Computer Protocol) 블록체인 캐니스터를 5~50분 간격으로 폴링했다. 공개적으로 문서화된 최초의 ICP 캐니스터 C2 악용 사례다. 블록체인 기반이라 기존 도메인 차단 방식으로는 무력화할 수 없다.
Kubernetes 페이로드에는 지정학적 요소도 포함되어 있었다. Asia/Tehran 시간대 또는 fa_IR 로케일이 감지되면 rm -rf / --no-preserve-root를 실행해 클러스터 전체를 삭제하는 와이퍼가 내장되어 있었다. 자격증명 절도 캠페인에 파괴 페이로드를 내장한 것은 TeamPCP의 동기가 단순한 금전적 이익을 넘어선다는 점을 시사한다.
Microsoft는 3월 24일 탐지 및 방어 가이드를 공개하며 핵심 권고사항을 제시했다.
| 권고사항 | 이유 |
|---|---|
| GitHub Actions를 태그가 아닌 full commit SHA로 고정 | 태그는 force-push로 악성 커밋을 가리킬 수 있음 |
| 3월 19~24일 노출된 모든 시크릿 즉시 로테이션 | 잔존 크리덴셜이 재공격의 원인 |
tpcp-docs-* 저장소 존재 여부 확인 | 유출 성공 여부 판단 지표 |
| C2 IP 45.148.10.212, 83.142.209.11 차단 | TeamPCP 인프라 |
Aqua Security는 안전 버전을 공지했다. trivy v0.69.3 이하, trivy-action v0.35.0(57a97c7 SHA), setup-trivy v0.2.6(3fb12ec SHA)으로 고정해야 한다. LiteLLM은 1.82.6 이하가 안전하며, 악성 1.82.7/1.82.8은 PyPI에서 격리 처리됐다.
이 사건의 핵심 교훈은 두 가지다. 첫째, 크리덴셜 로테이션은 원자적으로 수행해야 한다. 일부만 교체하면 잔존 자격증명이 재공격 경로가 된다. 둘째, CI/CD 파이프라인에서 의존성을 태그로 참조하는 관행은 공급망 공격의 진입점이 된다. commit SHA 고정은 선택이 아니라 필수다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.