Il pacchetto malevolo LiteLLM 1.107.0 ha rubato credenziali
Il pacchetto malevolo LiteLLM distribuito come versione 1.107.0 raccoglieva credenziali e installava una backdoor in grado di recuperare ed eseguire codice Python ogni ora. Mercoledì LiteLLM ha comunicato che gli autori dell'attacco avevano aggirato diversi controlli di sicurezza indipendenti e compromesso la sua release pipeline, il processo automatizzato utilizzato per compilare e pubblicare il software.
La release avvelenata è stata pubblicata il 21 ottobre 2026, intorno alle 4:00 PST. È apparsa come LiteLLM v1.107.0 sul Python Package Index (PyPI), il principale repository pubblico per il software Python. Docker Hub e GitHub Container Registry (GHCR) hanno ricevuto container image con i tag v1.107.0, latest, main-latest e main-stable. LiteLLM ha dichiarato che i clienti enterprise che utilizzavano il suo image registry privato non sono stati colpiti e che la versione compromessa è stata rimossa entro tre ore.
Sono considerati coinvolti gli utenti che hanno installato tramite pip un pacchetto LiteLLM unpinned tra le 11:39 e le 13:23 UTC oppure che hanno scaricato una delle container image elencate tra le 11:46 e le 14:20 UTC. Un'installazione unpinned consente al gestore dei pacchetti di selezionare una versione disponibile invece di richiedere una release precisa. Poiché erano stati avvelenati tag di uso comune come latest, i team potrebbero aver ricevuto la build malevola senza richiedere esplicitamente la versione 1.107.0.
Il codice malevolo raccoglieva segreti associati al sistema operativo, ai browser, agli strumenti di sviluppo, ai servizi cloud e agli strumenti di intelligenza artificiale. Inviava i dati rubati tramite una richiesta HTTP POST a litellm[.]dev/healthcheck. Creava inoltre un remote access trojan (RAT), un malware che consente a un operatore esterno di eseguire codice sul sistema compromesso.
L'infezione era incorporata nel pacchetto anziché nel codice sorgente dell'applicazione LiteLLM. Endor Labs ha riferito che un'unica aggiunta alla configurazione di build di Maturin inseriva cook.pth, cook.py e sitecustomize.py nella directory della libreria Python. Python elabora i file di configurazione .pth e importa sitecustomize durante l'avvio, quindi il payload poteva attivarsi ogni volta che Python veniva avviato in quell'ambiente, anche quando l'applicazione in esecuzione non utilizzava LiteLLM. Il file cook.pth importava cook.py, che decodificava sé stesso e avviava una routine chiamata privcollect per raccogliere e trasmettere segreti.
Su Linux e macOS, sitecustomize.py tentava inoltre di recuperare domain.txt da un account GitHub ora rimosso, all'indirizzo github[.]com/letters9813. Se il file forniva un indirizzo utilizzabile, il malware scaricava un secondo programma Python da /codepy e lo eseguiva. Aikido ha scoperto che il loader avviava un processo in background, utilizzava /tmp/remote_code_loader.lock per evitare copie duplicate e controllava ripetutamente raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain[.]txt per individuare il server di comando corrente dell'autore dell'attacco. Richiedeva quindi ed eseguiva un nuovo payload ogni ora. Wiz ha dichiarato che il file conteneva soltanto valori di test iniziali prima che GitHub lo rimuovesse intorno alle 13:30 UTC. Wiz ha descritto l'uso simultaneo di .pth e sitecustomize.py come la prima combinazione documentata di questi due metodi di avvio di Python in un malware attivo.
Successivamente, Wiz ha osservato l'utilizzo di credenziali AWS instance role rubate da CI runner di continuous integration (CI) compromessi, ossia sistemi che compilano e testano automaticamente il software, e da nodi Kubernetes. L'attività è iniziata circa 4,5 ore dopo la trasmissione dei segreti. Tra le 16:20 e le 17:01 UTC, connessioni provenienti da 168.100.8[.]57 e 165.227.201[.]8 hanno verificato le credenziali con sts:GetCallerIdentity, quindi hanno chiamato bedrock:ListFoundationModels e ListModels. Wiz ha affermato che tale sequenza era coerente con il LLMjacking, l'uso non autorizzato dell'accesso cloud di un'altra organizzazione per consumare servizi di intelligenza artificiale. In un numero limitato di ambienti, l'autore dell'attacco ha inoltre elencato ruoli AWS, utenti e credenziali di accesso e ha interrogato gli account e le impostazioni degli audit trail.
LiteLLM aveva già modificato il proprio processo di release dopo un incidente distinto avvenuto nel marzo 2026. Le misure adottate includevano lo spostamento delle release in un repository privato, la trasformazione dei tag delle release Docker in elementi immutabili, così che non potessero essere riassegnati, e la firma crittografica delle container image. Il 19 ottobre, tuttavia, i maintainer hanno esteso temporaneamente i permessi di release a due tecnici interni che dovevano pubblicare ogni giorno backport di correzioni di bug per i clienti. L'autore dell'attacco aveva ottenuto tre set di credenziali da riga di comando GitHub appartenenti agli sviluppatori, incluso un set in grado di avviare workflow GitHub.
Secondo l'indagine di LiteLLM, una credenziale appartenente al proprietario di un'organizzazione GitHub è stata utilizzata per disabilitare le protezioni dei branch e imporre modifiche malevole al progetto. L'autore dell'attacco ha quindi eseguito il workflow su un repository dall'aspetto simile, denominato Berri-AI/litellm, invece che sul repository legittimo BerriAI/litellm. Ciò ha fatto sì che i pacchetti e le container image compromessi passassero attraverso il processo di firma e pubblicazione del progetto.
LiteLLM ha dichiarato di aver osservato situazioni in cui Claude Code inseriva l'OAuth token della GitHub CLI di un utente in un response body. Un OAuth token è una credenziale riutilizzabile dell'account che consente al software di agire con i permessi concessi dall'utente. Se i response body venivano registrati, il token poteva di conseguenza comparire nei log di LiteLLM. I maintainer hanno inoltre individuato un account utente inatteso, dall'aspetto innocuo, in un deployment interno di LiteLLM raggiungibile dalla rete internet pubblica. Sospettano che l'autore dell'attacco abbia avuto accesso a quel sistema e recuperato le credenziali GitHub dai relativi log. Non è ancora chiaro come il deployment sia diventato pubblico né come sia stato ottenuto l'accesso. LiteLLM ha suggerito che potrebbe essere stata coinvolta una vulnerabilità corretta di recente, ma l'indagine sulla root cause è ancora in corso.
L'uso di un file .pth ricorda la tecnica osservata nell'attacco di marzo attribuito a TeamPCP, ma Socket ha dichiarato che le prove disponibili non consentono di stabilire un collegamento. Socket ha rilevato differenze nelle chiavi pubbliche crittografiche RSA incorporate, nell'implementazione del furto di dati e nel comportamento della backdoor. Non è stato inoltre verificato se le credenziali rubate durante l'incidente di marzo abbiano contribuito alla compromissione di ottobre.
Le organizzazioni che hanno eseguito LiteLLM 1.107.0 dovrebbero rimuoverlo, disconnettere gli host coinvolti dagli altri sistemi, cercare i tre file Python malevoli, bloccare il dominio usato per la raccolta dei dati e indagare su qualsiasi esecuzione di /codepy. Tutte le credenziali raggiungibili da un ambiente coinvolto dovrebbero essere revocate e sostituite, inclusi i segreti cloud, quelli degli sviluppatori e quelli memorizzati nei browser. JFrog ha consigliato di ricostruire i sistemi coinvolti e verificare l'esatto Python wheel, ossia il file di pacchetto installabile, anziché presumere che un repository sorgente pulito garantisca un artifact pubblicato pulito. Endor Labs ha inoltre raccomandato di esaminare i registri di rete e di effettuare il pinning di ogni container image tramite digest, un identificatore fisso del contenuto esatto dell'image, anziché tramite un tag modificabile.
Per le organizzazioni che necessitano di assistenza nella più ampia risposta infrastrutturale a incidenti di questo tipo, AEU-I offre servizi IT, infrastruttura e consulenza orientati prioritariamente alla sicurezza.