LiteLLM 1.107.0 var forgiftet på PyPI og Docker: pin til 1.106.2 og roter nøklene
torsdag 22. oktober · KI-generert · Kilde: LiteLLM
Regn ethvert miljø som startet LiteLLM 1.107.0 som kompromittert, slett skadevarefilene, installer 1.106.2 på nytt og roter alle nøkler maskinen kunne nå.
Etter angrepet i mars flyttet LiteLLM releasene til et privat repo, gjorde Docker-taggene uforanderlige og begynte å signere imagene. 21. oktober kom angriperen likevel gjennom: releasepipelinen publiserte versjon 1.107.0 med kompilert skadevare til PyPI og Docker, ifølge LiteLLMs egen hendelsesrapport. PyPI-pakken lå ute fra 11:39 til 13:23 UTC, og Docker Hub-taggene v1.107.0, latest, main-latest og main-stable pekte på det forgiftede imaget fra 11:46 til 14:20 UTC. Enterprise-kunder på det private registeret ble ikke rammet.
Angriperen hadde GitHub CLI-tokens fra tre utviklere. Ett tilhørte en av organisasjonens to eiere, og det ble brukt til å slå av branch protection og force-pushe en endring som pekte release-workflowen mot lookalike-repoet Berri-AI/litellm i stedet for BerriAI/litellm. En annen konto godkjente produksjonsporten, og en tredje slettet workflow-loggene etterpå. Release-rettighetene var midlertidig utvidet på mandag for å slippe daglige bugfix-backports.
Hvor tokenene kom fra, angår alle som kjører en egen LiteLLM-proxy. LiteLLM fant en ukjent bruker med et uskyldig navn i sin interne LiteLLM-instans, som var eksponert mot internett, og tror angriperen hentet tokenene fra loggene der.
«Vi har observert spesifikke situasjoner der Claude Code legger brukerens GitHub CLI OAuth-token inn i en respons-body, og der respons-bodyer logges, kan disse tokenene havne i LiteLLM-loggene.» — LiteLLM, i hendelsesrapporten
Hvordan angriperen kom inn i den interne instansen, er ikke bekreftet. LiteLLM mistenker en nylig lappet sårbarhet.
Skadevaren er en credential stealer kalt privcollect med 16 moduler, skriver Wiz. Den tar nettleserpassord og cookies, AWS-, GCP- og Azure-nøkler, API-nøkler til OpenAI, Anthropic og andre leverandører, SSH- og GPG-nøkler og shell-historikk. På en LiteLLM-proxy spør den i tillegg Postgres-databasen direkte etter opptil 500 rader fra LiteLLM_CredentialsTable, altså upstream-nøklene du har lagt inn. Wiz anslår rundt 49 000 nedlastinger av 1.107.0 ut fra ClickPy-data, og så misbruk av stjålne AWS-roller omtrent 4,5 timer etter eksfiltreringen: først sts:GetCallerIdentity, deretter bedrock:ListFoundationModels, et mønster Wiz knytter til LLMjacking.
Filene cook.pth, cook.py og sitecustomize.py legges rett i site-packages og kjøres hver gang en Python-tolk starter. Derfor advarer LiteLLM mot å begynne oppryddingen med pip install: også pip starter Python og kjører skadevaren på nytt.
«Den doble teknikken, med både .pth-filer og sitecustomize.py samtidig, ser ut til å være det første dokumenterte tilfellet i praksis.» — Wiz
Hva bør du gjøre?
- Kjør pip show litellm i alle miljøer, og let etter litellm-1.107.0.dist-info, cook.pth og sitecustomize.py i site-packages. Treff bekrefter eksponering, men fravær beviser ikke at miljøet er rent.
- Er du rammet, slett cook.pth, cook.py, sitecustomize.py og tilhørende .pyc-filer fra skallet før du kjører noe Python, drep daemonen som holder /tmp/remote_code_loader.lock, og bygg venv eller image på nytt med litellm==1.106.2.
- Roter alt verten nådde: IAM-rollen, alle leverandørnøkler i proxy-databasen pluss master- og virtuelle nøkler, DATABASE_URL-passordet og alle hemmeligheter i miljøet. Sjekk CloudTrail for GetCallerIdentity fra instansrollen rundt installasjonstidspunktet.
- Pin Docker-imaget på digest i stedet for latest eller main-stable, og sjekk om proxyen din logger respons-bodyer.