폐기 안 한 노출 키, LiteLLM 악성 배포로 이어졌다
3줄 요약
- LiteLLM의 23일 조사는 폐기하지 않은 마스터 키에서 시작된 침입 경로를 밝혔다.
- 10월 21일 배포된 1.107.0의 설치 파일에는 소스 압축본에 없는 악성 시작 훅이 들어 있었다.
- 오염된 배포물은 제거됐으며, 공지는 실행한 환경의 재구축과 자격 증명 교체를 안내한다.
LiteLLM은 10월 23일 조사에서 폐기하지 않은 노출 키를 악성 배포의 출발점으로 지목했다. 5월 27일 공개 저장소에 올라간 에이전트 플랫폼 마스터 키는 커밋을 덮어쓴 뒤에도 살아 있었으며, 공격자가 10월 10일 사용했다고 회사는 밝혔다.
피해 버전은 10월 21일 배포된 1.107.0이다. 공식 노출 구간은 PyPI가 이날 11시 39분~13시 23분, Docker Hub가 11시 46분~14시 20분 UTC다. 당시 latest 등 컨테이너 태그도 오염된 버전을 가리켰다. 별도 비공개 기업용 레지스트리는 영향받지 않았다고 회사는 밝혔다.
LiteLLM은 여러 AI 제공업체의 모델을 하나의 인터페이스로 연결하는 오픈소스 게이트웨이다. 앱마다 제공업체 키를 전달하는 대신 게이트웨이에 키를 보관하고, 앱과 사용자에게는 예산·호출 한도가 붙은 가상 키를 발급한다. 요청 비용도 같은 곳에서 기록한다.
에이전트 플랫폼은 GitHub에 코드 변경 요청을 올리는 실험 서비스였다. 공격자는 여기에 저장된 조직 소유자의 GitHub CLI 인증 정보를 얻고, CI 작업으로 엔지니어 두 명의 인증 정보도 빼냈다. 최종 조사는 인증 정보의 출처를 배포 로그로 추정했던 설명을 정정했다.
Datadog은 세 계정의 자격 증명이 빌드 실행·승인·기록 삭제에 쓰였다고 분석했다. 정상 BerriAI와 하이픈 하나 차이인 Berri-AI가 빌드 원본이 됐다. 악성 파일은 정식 배포 경로를 거쳤고 출처 기록에도 바뀐 저장소가 남았다.
JFrog이 비교한 일곱 플랫폼용 설치 파일 wheel에는 소스 압축본에 없는 파일 세 개가 들어 있었다. JFrog은 파일 타임스탬프와 메타데이터가 정상 wheel 구성 때 포함됐을 가능성을 뒷받침한다고 설명했다. 소스 압축본만 살피면 설치될 실행 코드를 놓칠 수 있었다.
Python 공식 문서에 따르면 통상 초기화 과정에서 .pth 파일의 import 줄이 실행되고 sitecustomize 모듈도 불러온다. 응용 코드가 특정 라이브러리를 사용할지와 관계없이 작동하는 경로다. 이번 악성 파일은 이 시작 훅을 이용했으며 LiteLLM을 직접 불러오지 않아도 실행됐다고 JFrog은 밝혔다.
Datadog이 확인한 수집 대상은 클라우드·개발 도구·AI 도구·브라우저 자격 증명이다. 데이터베이스가 연결된 프록시에서는 제공업체 키를 보관하는 테이블도 조회했다.
로더는 매시간 외부 파일을 확인해 후속 코드를 받을 수 있게 설계됐다. Datadog은 조사 당시 시험용 값만 확인했으며 실제 유포된 2단계 페이로드는 관측하지 못했다고 밝혔다. 수집기의 자격 증명 탈취 기능은 이 관측 한계와 별개다.
LiteLLM은 오염된 배포물을 PyPI·Docker Hub·GHCR에서 제거하거나 태그를 정상 산출물로 돌렸다. 공식 공지는 시작 훅이 남을 수 있어 패키지 폴더 삭제만으로는 부족하다고 설명한다. 이미 실행한 환경에는 새 환경 재구축과 접근 가능한 자격 증명 교체를 안내했다.
출처
- October 23 — causal investigation — LiteLLM
- October 21 — scope and response advisory — LiteLLM
- Independent wheel and startup-hook analysis — JFrog Security Research
- Independent credential and loader analysis — Datadog Security Labs
- Gateway and credential model — LiteLLM Docs
- Interpreter startup hooks — Python Docs
정정 내역
- GitHub 접근용 인증 정보의 표현을 명확히 했습니다.
- 인증 정보 표현을 바꾸는 과정에서 생긴 한국어 조사 오타를 바로잡았습니다.