Un attento ricercatore del SANS ha recentemente scritto di un nuovo e piuttosto specifico tipo di attacco supply chain ai moduli software open source in Python e PHP.
A seguito di discussioni online su un modulo Python pubblico sospetto, Yee Ching Tok ha notato che un pacchetto chiamato ctx all’interno del popolare repository PyPi aveva improvvisamente ricevuto un “update”, nonostante non fosse più stato toccato altrimenti dalla fine del 2014.
In teoria, ovviamente, non c’è niente di sbagliato nel fatto che i vecchi pacchetti tornino improvvisamente in vita.
A volte, gli sviluppatori tornano sui vecchi progetti quando una pausa nella loro routine quotidiana (o un’e-mail che provoca sensi di colpa da un utente di lunga data) dà loro finalmente lo slancio per applicare alcune correzioni di bug attese da tempo.
In altri casi, nuovi manutentori si fanno avanti in buona fede per rilanciare i progetti “abandonware”.
Ma i pacchetti possono diventare vittime di attività segrete, in cui la password dell’account in questione viene violata, rubata, reimpostata o altrimenti compromessa, in modo che il pacchetto diventi una testa di ponte per una nuova ondata di attacchi alla supply chian.
In poche parole, alcuni “revival” di pacchetti sono condotti totalmente in malafede, per fornire ai criminali informatici un veicolo per diffondere malware con il pretesto di “aggiornamenti di sicurezza” o “miglioramenti delle funzionalità”.
Gli aggressori non prendono necessariamente di mira alcun utente specifico del pacchetto che compromettono: spesso, stanno semplicemente guardando e aspettando di vedere se qualcuno si innamora del loro specchietto per le allodole…
…a quel punto hanno un modo per prendere di mira gli utenti o le aziende che lo fanno.
Nuovo codice, vecchio numero di versione
In questo attacco, Yee Ching Tok ha notato che sebbene il pacchetto fosse stato improvvisamente aggiornato, il suo numero di versione non era cambiato, presumibilmente nella speranza che alcune persone potessero [a] scaricare comunque la nuova versione, forse anche automaticamente, ma [b] non preoccuparsi di cercare le differenze nel codice.
Ma un diff (abbreviazione di differenza, in cui vengono esaminate solo le righe nuove, modificate o eliminate nel codice) mostrava righe aggiunte di codice Python in questo modo:
Forse ricordate, dal famigerato bug di Log4Shell, che le cosiddette variabili ambientali, accessibili tramite os.environ in Python, sono impostazioni key=value di sola memoria associate a uno specifico programma in esecuzione.
I dati che vengono presentati a un programma tramite un blocco di memoria non devono essere scritti su disco quindi, questo è un modo pratico per passare attraverso dati segreti come le chiavi di crittografia, proteggendosi dal salvataggio improprio dei dati per errore.
Tuttavia, se puoi infettare un programma in esecuzione, che avrà già accesso all’ambiente del processo di sola memoria, puoi leggere i segreti da solo e rubarli, ad esempio inviandoli nascosti in un normale traffico di rete.
Se lasci intatta la maggior parte del codice sorgente che stai infettando, le sue solite funzioni continueranno a operare come prima, quindi è probabile che le modifiche malevole nel pacchetto passino inosservate.
Perché ora?
Apparentemente, il motivo per cui questo pacchetto è stato attaccato solo di recente è che il nome del server utilizzato per le e-mail dal manutentore originale era appena scaduto.
Gli aggressori sono stati quindi in grado di acquistare il nome di dominio ora inutilizzato, impostare un proprio server di posta elettronica e reimpostare la password sull’account.
È interessante notare che il pacchetto ctx infetto è stato presto aggiornato altre due volte, con una maggior quantità dell’”ingrediente segreto” aggiunta nel codice corrotto, questa volta incluso un codice di furto di dati più aggressivo.
La riga request.get() di seguito si connette a un server esterno controllato dai truffatori, anche se abbiamo nascosto il nome di dominio qui:
Il server di esfiltrazione oscurato riceverà le variabili ambientali codificate (inclusi tutti i dati rubati come le chiavi di accesso) come una stringa dall’aspetto innocente di dati casuali alla fine dell’URL.
La risposta che torna in realtà non ha importanza, perché è la richiesta in uscita, completa di dati segreti aggiunti, che gli aggressori stanno cercando.
Se vuoi provare tu stesso, puoi creare un programma Python autonomo basato sullo pseudocodice sopra, come questo:
Quindi avvia uno pseudoserver HTTP in ascolto in una finestra separata (abbiamo usato l’eccellente utility ncat del toolkit Nmap, come mostrato di seguito) ed esegui il codice Python.
Qui, siamo nella shell Bash e abbiamo usato env -i per ridurre le variabili di ambiente per risparmiare spazio, e abbiamo eseguito lo script di esfiltrazione Python con un set di variabili di ambiente AWS false (la chiave di accesso che abbiamo scelto è uno degli esempi deliberatamente non funzionali di Amazon utilizzati per la documentazione):
Il server di ascolto (è necessario avviarlo prima in modo che il codice Python abbia qualcosa a cui connettersi) risponderà alla richiesta e scaricherà i dati che sono stati inviati:
La riga GET /… sopra acquisisce i dati codificati che sono stati esfiltrati nell’URL.
Ora possiamo decodificare i dati base64 dalla richiesta GET e rivelare la falsa chiave AWS che abbiamo aggiunto all’ambiente di processo nell’altra finestra:
Criminalità correlata
Incuriosito, Yee Ching Tok è andato a cercare altrove il nome del server di esfiltrazione che abbiamo nascosto sopra.
Lo stesso server è apparso nel codice caricato di recente in un progetto PHP su GitHub, presumibilmente perché è stato compromesso dagli stessi aggressori più o meno nello stesso momento.
Quel progetto è quello che era un legittimo toolkit di hashing PHP chiamato phppass, ma ora contiene queste tre righe di codice indesiderato e pericoloso:
Qui, tutti i segreti di accesso di Amazon Web Services, che sono stringhe di caratteri pseudocasuali, vengono estratti dalla memoria dell’ambiente (getenv() sopra che è l’equivalente PHP di os.environ.get() nel codice Python canaglia che hai visto prima) e modellato in un URL .
Questa volta, i truffatori hanno utilizzato http invece di https, quindi non solo rubando i tuoi dati segreti, ma effettuando anche la connessione senza crittografia, esponendo così i tuoi segreti AWS a chiunque registri il tuo traffico mentre attraversa Internet.
Che fare?
- Non accettare ciecamente gli aggiornamenti dei pacchetti open source quando vengono visualizzati. Esamina tu stesso le differenze di codice prima di decidere che l’update è nel tuo interesse. Sì, i criminali determinati in genere nascondono le loro modifiche al codice illegali in modo più sottile rispetto agli hack che vedi sopra, quindi potrebbe non essere così facile da individuare. Ma se non guardi affatto, allora i truffatori possono farla franca con tutto ciò che ne consegue.
- Verifica la presenza di modifiche sospette nell’account di qualsiasi manutentore prima di fidarti. Guarda la documentazione nella versione precedente del codice (presumibilmente, il codice che hai già) per i dettagli di contatto del precedente manutentore e guarda cosa è cambiato sull’account dall’ultimo update. In particolare, se riesci a vedere nomi di dominio scaduti e registrati di nuovo solo di recente, o modifiche e-mail che introducono nuovi manutentori senza un evidente interesse precedente per il progetto, sii sospettoso.
- Non fare affidamento solo sui test dei moduli che verificano un corretto comportamento. Mira a test generici che cerchino anche comportamenti indesiderati, insoliti e imprevisti, soprattutto se tale comportamento non ha una connessione evidente con il pacchetto che hai modificato. Ad esempio, un’utilità per calcolare gli hash delle password non dovrebbe stabilire connessioni di rete, quindi se lo scopri mentre lo fai (usando dati di test anziché informazioni in tempo reale, ovviamente!), allora dovresti sospettare qualcosa di scorretto.
Strumenti di rilevamento delle minacce come Sophos XDR possono aiutarti in questo caso consentendoti di tenere d’occhio i programmi che stai testando e quindi di rivedere la registrazione delle loro attività per individuare comportamenti sospetti.
Dopotutto, se sai cosa dovrebbe fare il tuo software, dovresti anche sapere cosa non dovrebbe fare!