무슨 일이 일어났나
2026년 3월 말, 기존 Trivy 공급망 공격(trivy-supply-chain-attack-teampcp-2026)의 후속 사건이 발생했습니다. 위협 그룹 TeamPCP가 Trivy 침해 과정에서 탈취한 PyPI 퍼블리싱 크리덴셜을 이용해, 인기 AI 프록시 라이브러리 LiteLLM의 악성 버전 두 개(v1.82.7, v1.82.8)를 PyPI에 업로드했습니다.
LiteLLM은 하루 약 340만 건 다운로드를 기록하는 대규모 패키지입니다. Sonatype에 따르면, 악성 버전은 약 3~5시간 동안 라이브 상태였다가 PyPI 보안팀에 의해 격리됐습니다. 짧은 시간이었지만, 자동화된 CI/CD 파이프라인에서 pip install --upgrade를 실행하는 환경이라면 충분히 감염될 수 있는 창이었습니다.
공격 체인 — Trivy에서 LiteLLM까지
이번 공격의 핵심은 연쇄 공급망 공격(cascading supply chain attack)입니다. 한 프로젝트의 침해가 다른 프로젝트로 전파되는 구조입니다.
- Trivy 침해 — TeamPCP가 Trivy GitHub Actions를 태그 포이즈닝으로 장악
- CI/CD 크리덴셜 탈취 — Trivy를 사용하는 프로젝트의 환경변수와 시크릿 수집
- PyPI 퍼블리싱 키 획득 — 탈취한 크리덴셜 중 LiteLLM 메인테이너의 PyPI 인증 정보 발견
- 백도어 업로드 — v1.82.7과 v1.82.8에 악성 페이로드 삽입 후 정식 릴리스로 배포
Kaspersky 분석에 따르면, 정상 기능은 그대로 유지하면서 초기화 단계에서 악성 코드를 실행하는 방식입니다. import litellm만 해도 페이로드가 작동합니다.
3단계 페이로드 분석
악성 코드는 세 단계로 동작합니다.
Stage 1 — 수집(Collection)
시스템 전체를 스캔하여 민감한 정보를 수집합니다.
| 대상 | 경로/방식 |
|------|----------|
| SSH 키 | ~/.ssh/ 디렉토리 전체 |
| 환경변수 파일 | .env, .env.local, .env.production |
| 클라우드 크리덴셜 | AWS(~/.aws/), GCP(~/.config/gcloud/), Azure(~/.azure/) |
| K8s 설정 | ~/.kube/config |
| DB 비밀번호 | 환경변수 내 DATABASE_URL, DB_PASSWORD 패턴 |
| 암호화폐 지갑 | 주요 지갑 파일 및 시드 구문 |
Stage 2 — 유출(Exfiltration)
수집한 데이터를 AES-256-CBC로 암호화한 뒤, 하드코딩된 4096비트 RSA 공개키로 AES 키를 래핑합니다. 복호화는 공격자의 개인키 없이 불가능합니다.
암호화된 데이터는 두 곳으로 전송됩니다.
models.litellm[.]cloud— 정상 LiteLLM 도메인을 모방한 피싱 도메인checkmarx[.]zone— 보안 기업 Checkmarx를 사칭한 도메인
Stage 3 — 지속성(Persistence)
~/.config/sysmon/sysmon.py 경로에 지속성 모듈을 설치합니다. 이 모듈은 50분마다 C2 서버에 접속하여 추가 페이로드를 폴링합니다. Kubernetes 환경에서는 kube-system 네임스페이스에 권한 있는 alpine:latest 파드 배포를 시도합니다.
악성코드의 버그 — 포크 폭탄
Help Net Security에 따르면, 악성 페이로드에는 흥미로운 버그가 있었습니다. .pth 런처 파일(litellm_init.pth)이 Python 시작 시 자동으로 로드되는데, 구현 실수로 지수적 포크 폭탄(exponential fork bomb)이 발생했습니다. 시스템 리소스가 급격히 소모되면서 오히려 감염 사실이 드러나는 아이러니한 결과를 낳았습니다.
지금 할 수 있는 대응법
- LiteLLM 버전 확인 —
pip show litellm으로 현재 버전을 확인합니다. v1.82.7 또는 v1.82.8이면 즉시 제거 후 안전한 버전으로 재설치합니다 - IOC 점검 — 다음 흔적이 있는지 확인합니다
litellm_init.pth파일이 Python site-packages에 존재하는지~/.config/sysmon/sysmon.py파일 존재 여부/tmp/pglog또는/tmp/.pg_state파일 존재 여부
- 네트워크 로그 감사 —
models.litellm[.]cloud또는checkmarx[.]zone으로의 아웃바운드 트래픽이 있었는지 방화벽·프록시 로그를 점검합니다 - 모든 크리덴셜 로테이션 — 감염이 의심되면 AWS/GCP/Azure 키, SSH 키, DB 비밀번호, PyPI 토큰을 모두 교체합니다
- K8s 환경 점검 —
kube-system네임스페이스에alpine:latest이미지를 사용하는 비인가 파드가 있는지 확인합니다 - pip install 고정 —
requirements.txt에 정확한 버전을 명시하고,--require-hashes옵션으로 패키지 무결성을 검증합니다
참고