
PHPMailer < 5.2.18 Эксплойт удаленного выполнения кода и уязвимый контейнер
PHPMailer — самый популярный транспортный класс в мире, с примерно 9 миллионами пользователей по всему миру. Загрузки продолжаются со значительной скоростью ежедневно. Используется многими проектами с открытым исходным кодом: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! и многими другими.
PHPMailer до версии 5.2.18 страдает от уязвимости, которая может привести к удаленному выполнению кода (RCE). Функция mailSend в транспорте isMail в PHPMailer, когда свойство Sender не установлено, может позволить удаленным злоумышленникам передавать дополнительные параметры команде mail и, как следствие, выполнять произвольный код через " (обратная косая черта и двойная кавычка) в поддельном адресе From.
Чтобы настроить уязвимую среду для вашего теста, вам понадобится установленный Docker и просто выполните следующую команду:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
И это создаст уязвимое веб-приложение на вашем хосте на порту 8080

Чтобы эксплуатировать эту цель, просто выполните:
./exploit хост:порт
Если вы используете этот уязвимый образ, вы можете просто выполнить:
./exploit localhost:8080
После эксплуатации файл с именем backdoor.php будет сохранен в корневой папке веб-директории. И эксплойт предоставит вам оболочку, где вы сможете отправлять команды на бэкдор:
./exploit.sh localhost:8080
[+] CVE-2016-10033 эксплойт от opsxcq
[+] Эксплуатация localhost:8080
[+] Цель эксплуатирована, доступ к оболочке по адресу http://localhost:8080/backdoor.php
[+] Проверка, был ли создан бэкдор на целевой системе
[+] Backdoor.php найден на удаленной системе
[+] Выполнение whoami
www-data
RemoteShell>
И это всё, у вас есть оболочка. Существует еще один эксплойт, который иллюстрирует другой вариант использования.
./deface.sh localhost:8080
[+] CVE-2016-10033 эксплойт от opsxcq
[+] Эксплуатация localhost:8080
[+] Цель эксплуатирована, доступ к оболочке по адресу http://localhost:8080/backdoor.php
[+] Проверка, был ли создан бэкдор на целевой системе
[+] Backdoor.php найден на удаленной системе
[+] Размещение вашего сообщения на сервере
[+] Задача выполнена, выход
И если вы снова посетите страницу, вы увидите это:

До этого коммита в class.phpmailer.php в определенном сценарии не было фильтрации специальных символов в адресе электронной почты отправителя. Этот недостаток может привести к удаленному выполнению кода через функцию mail здесь.
Анализируя код, в функции 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 напрямую добавляется к переменной $params, которая фильтровалась в функции validateAddress(), но так как она использует спецификацию RFC 3696, это допускает определенные символы, которые нарушат работу.
В данном случае, кавычки:
В дополнение к использованию обратной косой черты для экранирования, для обрамления строк могут использоваться обычные символы двойных кавычек. Например,
"Abc@def"@example.com
"Fred Bloggs"@example.com
являются альтернативными формами первых двух примеров выше. Эти формы в кавычках редко рекомендуются и не распространены на практике, но, как обсуждалось выше, должны поддерживаться приложениями, обрабатывающими адреса электронной почты. В частности, формы в кавычках часто встречаются в контексте адресов, связанных с переходом из других систем и контекстов; эти переходные требования все еще возникают, и поскольку система, принимающая предоставленный пользователем адрес электронной почты, не может "знать", связан ли этот адрес с устаревшей системой, такие формы адресов должны приниматься и передаваться в почтовую среду.
Вы можете прочитать полный RFC здесь, если хотите. Но также, если версия PHP ниже 5.2.0 и не установлен PCRE, переменная $patternselect в validateAddress() будет установлена в noregex. Это приведет к тому, что ввод сможет избежать любых проверок regex. Он пройдет только небольшую проверку:
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);
Затем поток выполнения переходит к функции mailPassthru(), которая, если выполняется в safe_mode, не будет уязвима к этому недостатку, как указано в следующем коде
//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);
}
Но если он не выполняется в safe_mode, тогда наш специальный параметр будет передан в mail(), и, если нам повезет, он получит наш файл, содержащий все, что мы хотим, чтобы было записано туда, куда мы выберем.
Эксплуатация PHP mail() функции не нова, но она все еще жива, и люди все еще используют ее. Чтобы объяснить, как это работает, давайте посмотрим, как определена функция mail():
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
Существует несколько методов эксплуатации для разных результатов, мы сосредоточимся на эксплуатации 5-го параметра для получения удаленного выполнения кода (RCE). Параметр $additional_parameters используется для передачи дополнительных флагов в качестве параметров командной строки программе, настроенной для отправки письма. Эта конфигурация определяется переменной sendmail_path.
Примечание по безопасности из официальной документации PHP:
Параметр additional_parameters может использоваться для передачи дополнительных флагов в качестве параметров командной строки программе, настроенной для отправки почты, как определено параметром конфигурации sendmail_path. Например, это можно использовать для установки адреса отправителя конверта при использовании sendmail с опцией -f sendmail.
Этот параметр экранируется с помощью escapeshellcmd() внутри, чтобы предотвратить выполнение команд. escapeshellcmd() предотвращает выполнение команд, но позволяет добавлять дополнительные параметры. По соображениям безопасности рекомендуется, чтобы пользователь очищал этот параметр, чтобы избежать добавления нежелательных параметров в команду оболочки.
Учитывая дополнительные параметры, которые можно внедрить, мы будем использовать -X для эксплуатации этого недостатка. Подробнее о параметре -X