# Trivy가 다시 공격받다: 광범위한 GitHub Actions 태그 변조로 비밀정보 유출

> Clean Markdown view of GeekNews topic #27791. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=27791](https://news.hada.io/topic?id=27791)
- GeekNews Markdown: [https://news.hada.io/topic/27791.md](https://news.hada.io/topic/27791.md)
- Type: GN+
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2026-03-24T09:36:57+09:00
- Updated: 2026-03-24T09:36:57+09:00
- Original source: [socket.dev](https://socket.dev/blog/trivy-under-attack-again-github-actions-compromise)
- Points: 2
- Comments: 1

## Topic Body

- 공식 GitHub Action이 **태그 강제 업데이트**로 변조되어 **악성코드가 배포된 공급망 공격** 발생
- 공격자는 **76개 중 75개 태그를 악성 커밋으로 교체**, 약 **1만 개 이상의 워크플로**가 영향을 받음
- 변조된 스크립트는 **비밀정보 수집·암호화·유출**의 3단계로 동작하며, **TeamPCP Cloud stealer** 코드가 포함됨
- 감염된 태그는 여전히 활성 상태로, **@0.35.0 또는 특정 commit SHA만 안전**한 것으로 확인됨
- 모든 자격 증명 교체와 **commit SHA 고정 사용**이 필수이며, Docker Hub 이미지도 동일한 오염이 확인됨

---

### Trivy GitHub Actions 공급망 공격 개요
- **Trivy**의 공식 GitHub Action(`aquasecurity/trivy-action`)이 공격자에 의해 **태그 강제 업데이트(force-push)** 방식으로 변조되어 악성코드가 배포된 사건
- 공격자는 76개 버전 태그 중 **75개를 악성 커밋으로 교체**, CI/CD 파이프라인에서 자동 실행되도록 조작
- 약 **10,000개 이상의 GitHub 워크플로 파일**이 해당 액션을 참조하고 있어 피해 범위가 광범위함
- 감염된 태그는 여전히 활성 상태이며, **@0.35.0**만이 유일하게 안전한 버전으로 확인됨
- Socket은 19:15 UTC부터 실시간으로 182건의 악성 GitHub Action 이벤트를 탐지, **Backdoor**, **Infostealer**, **Reconnaissance** 유형으로 분류

### 공격의 원인과 진행 방식
- Trivy 유지관리자에 따르면, 이번 공격은 **쓰기 권한이 있는 자격 증명 탈취**로 인해 발생
  - 3월 초 발생한 이전 침해에서 CI 환경의 비밀이 유출되었으며, 회전(rotating) 과정이 완전하지 않아 새 자격 증명 일부가 공격자에게 남음
  - 공격자는 이 자격 증명을 이용해 GitHub 자체 취약점 없이 **인증된 태그 업데이트**를 수행
- 공격자는 브랜치 푸시나 릴리스 생성 대신, **기존 태그를 강제로 새 커밋으로 덮어씀**
  - 각 태그는 원래 커밋의 메타데이터(작성자, 이메일, 타임스탬프, 커밋 메시지)를 복제해 정상처럼 보이게 위조
  - 단, 원본 커밋은 GPG 서명되어 있었으나 공격자의 커밋은 **서명 누락**, 부모 커밋 날짜가 2026년으로 불일치
- GitHub의 **Immutable Release** 표시가 있더라도, 공격자가 악성 상태로 게시 후 잠금 처리했을 가능성 있음
  - 따라서 “Immutable” 배지에 의존하지 말고 **commit SHA 고정(pinning)** 방식만이 안전한 소비 방법임

### 태그 변조 구조
- 공격자는 `master` 브랜치의 최신 커밋(`57a97c7e`)을 기반으로 새 커밋을 생성
  - `entrypoint.sh` 파일만 악성 버전으로 교체하고 나머지 파일은 그대로 유지
  - 각 태그는 원래의 PR 번호, 커밋 메시지, 작성자 정보를 그대로 복제해 위조
- GitHub 릴리스 페이지에서 “0 commits to master since this release”로 표시되는 경우, **변조된 태그의 시각적 지표**로 확인 가능
- `0.35.0` 태그만 변조되지 않은 이유는 이미 `master` HEAD를 가리키고 있었기 때문

### 악성 페이로드 구조
- 변조된 `entrypoint.sh`는 총 204줄이며, **4~105줄에 Infostealer 코드**, 이후 정상 Trivy 스캔 코드 포함
- 악성코드는 세 단계로 구성됨
  - **1단계: 수집(Collection)** — 런너 프로세스 메모리 및 파일시스템에서 비밀정보 추출
  - **2단계: 암호화(Encryption)** — AES-256-CBC 및 RSA-4096으로 수집 데이터 암호화
  - **3단계: 유출(Exfiltration)** — 공격자 제어 도메인 또는 피해자 GitHub 계정으로 전송
- ## 1단계: 비밀정보 수집
  - GitHub Actions 런너 프로세스(`Runner.Worker`, `Runner.Listener`, `runsvc`, `run.sh`)의 환경변수를 `/proc/&lt;pid&gt;/environ`에서 읽어 `env`, `ssh` 키워드 포함 항목을 추출
  - GitHub 호스팅 런너에서는 **Python 기반 메모리 덤프 스크립트**를 `sudo`로 실행, Runner.Worker 프로세스 메모리에서 `"isSecret":true` 패턴을 검색
  - 자체 호스팅 런너에서는 **TeamPCP Cloud stealer**로 식별되는 파일시스템 크리덴셜 수집기 실행
    - SSH 키, AWS/GCP/Azure 자격 증명, Kubernetes 토큰, Docker 설정, DB 비밀번호, 환경파일, TLS 키, VPN 설정, Webhook URL, 지갑 키 등 광범위한 대상 포함
- ## 2단계: 암호화
  - `openssl rand`로 32바이트 세션 키 생성 후, AES-256-CBC로 데이터 암호화
  - 세션 키는 RSA-4096 공개키로 OAEP 패딩을 적용해 암호화
  - 암호화된 데이터(`payload.enc`)와 세션 키(`session.key.enc`)를 `tpcp.tar.gz`로 묶음
- ## 3단계: 데이터 유출
  - 1차 채널: `https://scan[.]aquasecurtiy[.]org`로 HTTPS POST 전송 (`aquasecurity` 오타 도메인 사용)
  - 2차 채널: 실패 시 피해자의 **GitHub Personal Access Token**을 이용해 `tpcp-docs`라는 공개 저장소 생성
    - 릴리스 자산으로 `tpcp.tar.gz` 업로드 → 공격자는 GitHub 검색으로 해당 저장소를 찾아 데이터 수집
  - GitHub 인프라를 이용해 방화벽 우회를 시도, 탐지 회피 가능성 높음
  - 마지막으로 임시 파일 삭제, 흔적 최소화

### 공격자 및 배후
- 악성 코드 내 주석에 **“TeamPCP Cloud stealer”** 명시
  - TeamPCP(DeadCatx3, PCPcat, ShellForce)는 **클라우드 네이티브 환경 공격 그룹**으로, Docker API·Kubernetes·Redis·Ray 대시보드 취약점 악용 사례 존재
  - 2026년 2월 Flare와 The Hacker News에서 **랜섬웨어·데이터 탈취·암호화폐 채굴 캠페인**으로 보고된 바 있음
- Solana 검증자 키 및 암호화폐 지갑 수집 기능은 재정적 동기와 일치

### 대응 및 권고
- **모든 Trivy Action 버전 태그 사용 중단**, 오직 **commit SHA `57a97c7e7821a5776cebc9bb87c984fa69cba8f1`** 또는 **태그 `0.35.0`** 만 사용
- 감염된 파이프라인은 **완전한 비밀 유출로 간주**, 모든 클라우드 자격 증명·SSH 키·API 토큰·DB 비밀번호·Docker 토큰 즉시 교체 필요
- GitHub 조직 내 `tpcp-docs` 저장소 존재 여부 점검 및 3월 19일 19:00 UTC 이후 실행된 `trivy-action` 로그 검토 권장

### 침해 지표 (IOCs)
- **네트워크 지표**: `scan[.]aquasecurtiy[.]org`
- **파일 해시**: `18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a` (`entrypoint.sh`)
- **감염된 GitHub Actions**: `aquasecurity/trivy-action@0.0.1` ~ `@0.34.2` 전 버전 포함 (총 75개 태그)

### 추가 업데이트 (3월 22일)
- Docker Hub에서도 **Trivy 이미지(`0.69.4`, `0.69.5`, `0.69.6`, `latest`)** 가 동일한 Infostealer 페이로드로 오염된 사실 확인
- `latest` 태그가 악성 이미지로 지정되어 노출 기간 동안 사용자에게 배포됨
- 관련 상세 내용은 Socket의 별도 보고서 *“Trivy Docker Images Compromised”*에서 확인 가능

## Comments



### Comment 53688

- Author: neo
- Created: 2026-03-24T09:36:58+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47475888) 
- GitHub이 Actions의 **불변 버전 관리(immutable versioning)** 를 강제하지 않는 이유가 궁금함  
  보안 가이드는 커밋 SHA로 고정(pin)하라고 하지만, 아예 고정하지 않으면 Action을 게시할 수 없게 만들면 이런 문제를 줄일 수 있을 것 같음
  - 이런 논의에는 항상 **양면성**이 있음  
    보안팀 입장에서는 고정 버전이 안전하지만, 동시에 **보안 업데이트 자동 반영**이 안 되면 위험함  
    결국 생산성을 해치지 않으면서 두 가지를 모두 만족시키는 해법이 필요함  
    이걸 “**Pinning의 역설**”이라 부르고 싶음
  - GitHub Actions가 **git 태그 모델**을 따르고 있어서 지금 구조를 바꾸기 어렵다고 생각함  
    그래도 언젠가는 바꾸는 작업을 시작해야 함
  - 만약 고정한 버전이 이미 **오염된 상태**였다면 어떨까?  
    업데이트를 허용해야 오히려 보안이 강화될 수도 있음  
    이건 정적 링크 vs 동적 링크 논쟁과 비슷한 문제임  
    게다가 Trivy Action은 어차피 최신 버전을 가져오도록 되어 있었음

- 이번 사건은 “**공급망 보안(supply chain security)**” 제품들이 실제로는 자신들이 보호하려는 스택만큼이나 취약할 수 있음을 보여주는 경고임  
  특히 “모든 곳에서 실행되는(run us everywhere)” 보안 도구들은 한 번의 공격으로 수많은 사용자를 동시에 위험에 빠뜨릴 수 있는 새로운 공격 벡터를 제공함

- 처음엔 Trivy가 **자격 증명 회전(rotation)** 을 제대로 하지 않은 줄 알았음  
  하지만 그들은 “비원자적(non-atomic) 회전 과정에서 공격자가 새 토큰을 알아냈을 수도 있다”고 설명함  
  GitHub은 발급 후 토큰을 다시 보여주지 않는데, 어떤 인증 방식을 썼는지에 따라 다를 수 있음  
  - OpenClaw 제작자도 비슷한 경험을 했다고 함  
    새 GitHub 조직을 만들자마자 이름이 탈취되어, GitHub 측에 **원자적 생성 처리**를 요청해야 했다고 함

- “**취약점을 스캔해야지, 취약점이 되면 안 된다**”는 말이 절묘하게 들어맞는 사건임  
  - “**취약점을 들여다보면, 취약점도 너를 들여다본다**”는 농담이 나올 정도임

- 관련 사건으로 [Trivy 공급망 일시적 침해](https://news.ycombinator.com/item?id=47450142) 가 있었음  
  - “일시적”이라는 표현은 너무 완곡한 표현 같음

- 3월 22일 공격자는 탈취된 자격 증명으로 **악성 Trivy v0.69.5, v0.69.6 DockerHub 이미지**를 게시함  
  ([보안 공지 링크](https://github.com/aquasecurity/trivy/security/advisories/GH...))  
  3월 19일과 22일 두 번의 사건이 있었고, 공격자는 두 차례의 자격 증명 회전에도 불구하고 지속적으로 접근 권한을 유지한 것으로 보임  
  - 실제로는 2월부터 이미 **전체 리포지토리 침해**가 있었고, 이번이 같은 공격자에 의한 세 번째 성공적인 공격임

- “지난 2주가 최악이었음”  
  Trivy가 털린 탓에 수많은 **보안 보고서와 회의**를 처리해야 하는 상황임

- “보안 소프트웨어를 만든다고 해서 반드시 유능한 건 아니다”는 교훈임  
  우리 보안팀도 매달 새로운 스캐너를 도입하려고 하지만, 그들이 요구하는 **광범위한 접근 권한**을 허용했다면 이미 여러 번 털렸을 것임  
  - 예전에 Trivy의 GitHub Actions를 **감사(audit)** 해봤는데, `setup-trivy` Action이 메인 브랜치를 그대로 클론하고 쉘 스크립트를 실행하는 구조였음  
    즉, 모든 CI 워크플로에서 임의 코드 실행이 가능했음  
    Aqua는 이달 초 침해를 당했고, 두 번이나 **격리 실패** 후 Docker Hub 계정까지 뚫림  
    이제는 외부 전문가의 도움이 필요하다고 생각함
  - “보안 도구”에 **광범위한 접근 권한**을 주는 건 위험 감소가 아니라 위험 확산임  
    대부분은 시끄러운 리포트 생성기일 뿐이고, 공격자가 내부에 들어오면 아무런 방어도 못 함  
    새로운 스캐너는 **격리된 샌드박스**에서 읽기 전용 데이터만 접근하게 하고, 충분히 검증될 때까지 프로덕션 권한을 주지 말아야 함  
    그렇지 않으면 비밀키를 **pastebin에 올리는 것과 다를 바 없음**
  - 요즘 기업 보안은 모든 장비에 **엔드포인트 보안 솔루션**을 깔고, 모든 로그를 AI 대시보드로 보내는 식임  
    “빠르게 움직이며 모든 걸 부수는” 보안 문화가 되어버림
  - 보안 부서에는 “시장에 쓸 만한 제품이 없으니 아무것도 쓰지 않겠다”는 선택지가 사실상 없음  
    그래서 **품질이 낮은 보안 소프트웨어**라도 무조건 도입하는 문화가 생김  
    Trivy 자체는 나쁘지 않다고 생각하고, 우리 회사도 사용 중임  
    다만 우리는 **Nix로 버전을 고정**하고 직접 Actions 워크플로를 작성해서 이번 침해 영향을 받지 않았음

- 공격자가 인증된 상태로 **태그 강제 업데이트(force-update)** 를 수행할 수 있었음  
  GitHub의 오래된 설정인 “**태그 덮어쓰기 금지**”만 켜놨어도 막을 수 있었던 일임  
  이런 사건이 반복될수록 **소프트웨어 건축법(Software Building Code)** 같은 표준이 필요하다는 생각이 강해짐  
  2026년에 이런 이유가 몇 개나 더 생길지 궁금함
