LiteLLM 공급망 공격에 대한 분 단위 대응 기록
(futuresearch.ai)- PyPI를 통해 배포된 LiteLLM 1.82.8 악성 패키지 감염을 실시간으로 탐지하고 분석한 분 단위 대응 일지
- 감염은 Cursor IDE 자동 업데이트 중 발생했으며,
litellm_init.pth파일이 실행되어 자격 증명 탈취와 시스템 감염을 유발 - 악성 코드는 SSH 키·클라우드 인증 정보 수집, Kubernetes 확산 시도, 포크 폭탄 생성 등 복합적 행위를 수행
- PyPI 보안팀과 LiteLLM 유지관리자에게 즉시 보고되어 패키지 격리 및 CVE 등록으로 이어짐
- Claude Code 등 AI 기반 코드 분석 도구가 공격 탐지에 핵심 역할을 하며, AI 생태계 공급망 보안 강화 필요성을 드러냄
LiteLLM 공급망 공격 대응 기록
- LiteLLM 1.82.8 버전이 PyPI를 통해 배포된 악성 패키지로 확인되어, 감염 탐지부터 격리까지의 과정을 분 단위로 기록한 대응 일지
- 감염은 Cursor IDE의 자동 업데이트 과정에서 발생했으며, Claude Code와 uv 패키지 관리자를 통해 설치된 의존성 중
litellm_init.pth파일이 실행되어 시스템 감염을 유발 - 공격은 자격 증명 탈취, 시스템 지속성 설치, Kubernetes 확산 시도, 포크 폭탄(fork bomb) 을 포함한 복합적 행위로 구성
- PyPI 보안팀과 LiteLLM 유지관리자에게 즉시 보고되어 패키지 격리 및 CVE 발급으로 이어짐
- AI 기반 코드 분석 도구가 실시간 악성 행위 탐지 및 분석에 핵심 역할을 수행
초기 탐지와 시스템 이상 징후
- 11:13 UTC경 macOS 노트북에서 11,000개 이상의 Python 프로세스가 생성되어 시스템이 정지 상태에 진입
-
exec(base64.b64decode('...'))형태의 명령이 반복 실행되며 CPU와 메모리를 포화시킴 - 강제 종료 후 재부팅 시 지속성(persistence) 관련 흔적은 발견되지 않음
-
- 초기에는 Claude Code의 내부 루프나
uv run스크립트 오류로 인한 비악성 루프 현상으로 판단 - 이후
htop스크린샷과 로그를 통해 base64 인코딩된 Python 스크립트가 반복 실행된 사실이 확인됨
감염 원인 규명
- 11:40경 설치된 Python 도구 내에서
litellm_init.pth파일이 발견되어 악성 행위로 판명-
.pth파일은 Python 시작 시 자동 실행되며 모든 Python 프로세스에서 동작 - SSH 키, 클라우드 자격 증명, 데이터베이스 비밀번호, 환경 변수, 쉘 히스토리 등을 수집
- 수집된 데이터는 RSA 암호화 후
https://models.litellm.cloud/로 전송 -
~/.config/sysmon/sysmon.py에 지속성 설치를 시도했으나 강제 재부팅으로 중단
-
- 감염은 Cursor IDE의 자동 업데이트(10:58 UTC) 중 발생
-
futuresearch-mcp-legacy확장이uvx를 통해 litellm 1.82.8을 다운로드 - 해당 버전은 PyPI에만 존재하며 GitHub 릴리스 태그가 없음
- PyPI 업로드 시각은 10:52 UTC로, 감염 직전 배포된 것으로 확인
-
악성 코드 구조
-
1단계(
litellm_init.pth): Python 시작 시 자동 실행되어 base64 인코딩된 페이로드를 디코딩 후 실행 - 2단계: RSA 공개키 포함, 탈취 데이터 암호화용
- 3단계(B64_SCRIPT): 실제 자격 증명 수집 및 전송 수행
-
지속성 설치:
sysmon.py를 systemd 서비스로 등록 시도 -
Kubernetes 확산 코드:
alpine:latest이미지를 이용해 각 노드에 privileged pod 생성 시도 -
포크 폭탄 원인:
subprocess.Popen([sys.executable, "-c", ...])호출이 자식 프로세스에서도.pth를 재실행하여 무한 루프 발생
피해 범위 및 대응 조치
-
노출된 자격 증명
- SSH 키, GCloud 및 Kubernetes 인증 정보,
.env파일 내 API 키, Supabase·ClickHouse·Grafana 비밀번호 등 - 즉각적 조치 권고
- 모든 SSH 및 클라우드 자격 증명 회전
-
.env및.mcp.json내 비밀키 재발급 -
~/.cache/uv캐시 삭제 - PyPI 보안팀(
security@pypi.org) 및 LiteLLM 유지관리자에 신고
- SSH 키, GCloud 및 Kubernetes 인증 정보,
-
Kubernetes 클러스터 점검 결과
- 악성 pod(
node-setup-*,sysmon) 미발견 - macOS 환경에서 실행되어 클러스터 내부 확산 실패
- 단,
~/.kube/config노출 가능성으로 인해 자격 증명 회전 필요
- 악성 pod(
PyPI 및 공개 대응
- 11:58 UTC, Docker 격리 환경에서 PyPI로부터 litellm 1.82.8 다운로드 후 악성
.pth파일 존재 재확인 - PyPI 보안팀과 BerriAI/litellm 저장소에 즉시 보고
- 이후 PYSEC-2026-2 (CVE) 로 등록
- 12:01 UTC, FutureSearch 블로그에 공급망 공격 공개 게시물 작성 및 배포
- 3분 내 PR 작성·병합 완료
- 12:04 UTC, r/Python, r/netsec, r/LocalLLaMA, r/MachineLearning, r/devops 커뮤니티에 공유 제안
- Python 및 보안 커뮤니티에서 빠른 대응 유도
사건의 의미
- AI 기반 코드 분석 도구 Claude Code가 실시간으로 악성 행위를 식별하고 보안 연구자 개입 전 단계에서 경고를 생성
- 공급망 공격이 AI 개발자 생태계를 직접 겨냥한 사례로, PyPI 계정 보안 및 자동 업데이트 검증 강화 필요성을 부각
- AI 도구가 단순 개발 보조를 넘어 사이버 위협 탐지 및 대응 자동화에 활용될 수 있음을 보여준 사례
Hacker News 의견들
-
나는 litellm 취약점을 처음 발견하고 보고한 개발자임
당시 상황을 그대로 기록한 실시간 분석 대화록을 공유했음
Claude가 누구에게 연락해야 하는지, 어떤 순서로 조치해야 하는지를 단계별로 안내해줘서 비보안 전문가에게도 큰 도움이 되는 경험이었음
이런 식으로 비전문가들이 취약점을 발견하고 보고하는 게 보안 커뮤니티에 도움이 되는 일인지, 아니면 혼란을 주는 일인지 궁금함- 보안 업계 종사자로서 Claude의 도움으로 이런 걸 발견한 건 인상적임
다만 “Cursor를 다시 열자마자 악성 패키지가 실행됐다”는 부분은 좀 위험해 보임
의심이 생긴 즉시 기기 격리와 보안팀 연락이 먼저였어야 함 - 나도 거의 같은 시점, 같은 방식으로 이 문제를 발견했음
.pth 파일이 포크 폭탄처럼 작동하지 않았다면 훨씬 늦게 발견됐을 수도 있음
Claude에게 연락 경로를 물어본 건 좋은 판단이었음
PyPI 관련 연락처를 몰라서 메인테이너에게 메일을 보내고 Hacker News에도 올렸음
보안 커뮤니티 소속이 아니더라도, 이런 심각한 취약점 보고는 누구나 할 수 있어야 함이라고 생각함 - 나는 여러 기업에서 취약점 공개 프로그램을 관리해온 경험이 있음
대부분의 문제는 돈을 노리고 아무거나 취약점이라 주장하는 사람들 때문임
하지만 네 보고서는 품질이 높았고, 이런 건 바로 패치 우선순위로 올림
비즈니스 중단 없이 해결 가능하면 즉시 조치하고, 심각할 경우 CISO나 CTO에게 바로 보고했음 - 글 잘 읽었음. Claude가 이런 상황에서 특히 유용하다고 느꼈음
네 보고 덕분에 더 큰 사고를 막은 셈임
우리도 관련 내용을 두 번에 걸쳐 블로그에 정리했음
grith.ai 블로그 글 - 최근 오픈소스 프로젝트들이 취약점 리포트와 PR 폭주로 힘들다는 얘기를 들었음
하지만 이번 사례는 AI의 도움으로 원인 분석과 보고가 훨씬 빨라진 좋은 예라고 생각함
- 보안 업계 종사자로서 Claude의 도움으로 이런 걸 발견한 건 인상적임
-
내 claude-code-transcripts 툴이 블로그 포스트에 데이터로 임베드된 건 처음 봄
평소엔 Gist의 HTML 페이지로 공유했는데, 이런 활용은 흥미로움- 우리 회사에서도 적극적으로 쓰고 있음
블로그 스타일에 맞추려다 실패했지만, 기본 경험의 중요성을 새삼 느꼈음
Claude가 내 컴퓨터 전체를 스캔하듯 로그를 긁어가서 자동 로그 편집 시스템이 필요하다고 느낌 - Claude Code 세션 간 정보 공유는 여전히 큰 문제임
긴급 디버깅 중 팀과 협업할 때 특히 불편함
- 우리 회사에서도 적극적으로 쓰고 있음
-
“악성 스크립트 내용을 실행하지 않고 출력할 수 있나?” 같은 요청은 위험함
LLM 에이전트는 책임 개념이 없기 때문에, 실수로 실행 명령을 내리면 큰 사고로 이어질 수 있음
PyPI에서 파일을 받을 땐 반드시 샌드박스 환경에서 해야 함- 나도 그 점이 걱정이었음
“하지 말라”고 하면 오히려 거기에 집착하는 경향이 있음
- 나도 그 점이 걱정이었음
-
PyPI가 “디지털 인증(digital attestation)”을 지원한다고 들었는데, 이 패키지는 서명돼 있었는지 궁금함
PyPI Trusted Publishers 문서 -
GitHub, npm, PyPI 같은 패키지 레지스트리들은 실시간 보안 분석용 이벤트 스트림(firehose) 을 제공해야 한다고 생각함
이런 공격은 자동 스캐너가 즉시 잡을 수 있었을 것임- PyPI는 이미 그런 기능을 제공 중임
보안 파트너가 패키지를 스캔하고, 초대 기반 API로 보고할 수 있음
PyPI 블로그 글 참고 - 나도 이번 사건 이후 dependency cooldown을 도입했음
관련 글
자동 스캐너가 .pth 파일 같은 이상 징후를 탐지할 시간을 벌어주는 게 목적임 - npm은 패키지 변경 피드를 제공하고, GitHub은 이벤트 firehose와 BigQuery 공개 데이터셋을 운영함
- 이런 인프라 제공은 법적 의무로 만들어야 한다고 생각함
경제적 피해가 너무 클 수 있고, litellm 감염자만 4만7천 명이 넘음
- PyPI는 이미 그런 기능을 제공 중임
-
“블로그 포스트 작성, PR, 머지까지 3분 이내”라는 부분이 가장 충격적이었음
읽는 시간보다 빠른 속도라 불안감이 듦 -
1만1천 개 프로세스의 포크 폭탄이 없었다면, 이 공격이 훨씬 오래 숨어 있었을지도 모름
- 나도 패키지를 설치하다가 바로 시스템이 멈춰서 감염은 피했음
만약 폭탄 속도를 늦췄다면 피해가 훨씬 컸을 것임 - 이번 세대의 인터넷 웜이라고 불러야 할지도 모르겠음
- 나도 패키지를 설치하다가 바로 시스템이 멈춰서 감염은 피했음
-
대기업이 신뢰할 수 없는 오픈소스 코드를 실행하는 방법은 두 가지임
- Google식으로 모든 걸 소스에서 직접 빌드
- 회사 내부 미러에서만 가져오고, 모든 패키지를 서명 검증
현실적으로 (1)이 가장 안전함
중소기업이나 개인은 의존성 고정(pinning) 과 충분한 대기 시간이 최선의 방어책임
Bazel을 쓰면 (1)에 가깝게 할 수 있지만, 대부분은 외부 소스에 의존할 수밖에 없음
-
PyPI가 보고 후 30분 만에 패키지를 격리한 건 정말 빠른 대응이었음
- 공급망 공격에 취약하다는 우려가 많지만, 이번엔 상당히 잘 처리된 사례라고 생각함
-
AI/LLM의 가장 좋은 점 중 하나는 리버스 엔지니어링의 민주화임
예전엔 배우기 어렵고 보람도 적은 기술이었는데, 이제는 AI가 방향을 잡아줌- 하지만 이번 건은 리버스 엔지니어링이 아니라 기본 시스템 관리 문제임
exec(base64.b64decode(...)) 패턴은 Python 도구들이 코드 전달 시 자주 쓰는 방식이지만,
기본적으로 /tmp나 /var/tmp, /dev/shm에서 실행되는 코드는 매우 의심스럽게 봐야 함
만약 Lulu나 LittleSnitch 같은 네트워크 모니터링 툴이 있었다면 이상 트래픽을 막았을 것임
단, Claude에 바이너리를 업로드해 분석시키는 건 또 다른 위험임 - 나도 CTF 영상 보며 흥미를 느끼긴 했지만, 현실 업무에서 이런 걸 직접 마주칠 일은 거의 없음
- 하지만 이번 건은 리버스 엔지니어링이 아니라 기본 시스템 관리 문제임