В PHPMailer выявлена ещё одна критическая уязвимость, вызванная недоработкой в PHP
29 декабря 2016 года
В библиотеке PHPMailer выявлена ещё одна критическая уязвимость (CVE-2016-10045), позволяющая выполнить свой код на сервере. Проблема устранена в выпуске PHPMailer 5.2.20. Уязвимость позволяет обойти метод защиты, реализованный для блокирования прошлой уязвимости, и касается не столько самого PHPMailer, сколько внутренних проблем с функцией mail() и средствами экранирования символов в PHP.
Напомним, что уязвимость в PHPMailer позволяла через передачу специально оформленного адреса отправителя, корректного и полностью соответствующего RFC 3696, организовать передачу дополнительных аргументов утилите /usb/sbin/sendmail, запускаемой по умолчанию при вызове PHP-функции mail(). Для атаки используется опция "-X", позволяющая записать тело сообщения в переданный в качестве аргумента файл (игнорируется в реализациях утилиты sendmail от проектов Postfix и Exim). Так как формально атака осуществляется через корректный email-адрес, проходящий проверку на предмет соответствия требованиям RFC 3696, при выпуске первого исправления для блокирования уязвимости был добавлен дополнительный вызов escapeshellarg(), производящий экранирование аргументов, передаваемых в функцию mail().
Из-за особенностей PHP данная защита оказалась неэффективной. В частности, для защиты от подстановки дополнительных shell-команд внутри функции mail() уже применяется экранирование итоговой команды через escapeshellcmd(). Добавленное разработчиками PHPMailer экранирования отдельных аргументов при помощи escapeshellarg() привело к некорректному двойному экранированию спецсимволов, в результате которого на выходе остаётся рабочая команда. Например, попытка отправки по адресу "Attacker\' -Param2 -Param3"@test.com приводит к следующей расстановке аргументов при вызове функции mail() и использовании для этого аргумента escapeshellarg():
$mail-SetFrom("\"Attacker\\' -Param2 -Param3\"@test.com", 'Client Name'); Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-f\"Attacker\\\] Arg no. 4 == [-Param2] Arg no. 5 == [-Param3"@test.com']
Так как выполнение двойного экранирования (escapeshellcmd( escapeshellarg( $address))) ломает всю защиту и штатными средствами устранить уязвимость через экранирование символов оказалось невозможно, разработчики PHPMailer решились на нарушение совместимости с RFC 3696 и в версии PHPMailer 5.2.20 реализовали дополнительную фильтрацию, которая может привести к прекращению обработки некоторых сложных email-адресов.
В ходе разработки исправления был поднят пласт проблем с функциями escapeshellcmd() и escapeshellarg(), поведение которых отличается для разных платформ и локалей. Кроме mail(), escapeshellcmd() также вызывается в некоторых других PHP-функциях, что мешает применению для них escapeshellarg() для экранирования отдельных аргументов. При включении Safe mode число таких функций расширяется, что создаёт дополнительные скрытые подводные камни при обеспечении безопасности (при включении safe mode защита через escapeshellarg для некоторых функций PHP перестаёт работать). По мнению разработчиков PHPMailer для полноценного устранения проблемы требуется внутренняя переработка функции mail() в PHP, в которой следует вместо строки $additional_parameters, подставляемой в выполняемую команду, использовать массив отдельных аргументов и обеспечить запуск sendmail напрямую, а не через shell.
Следует отметить, что проблема не ограничивается PHPMailer и, например, вчера обнаружена (CVE-2016-10074) в другой популярной PHP-библиотеке SwiftMailer, которая используется в таких проектах, как Yii2, Laravel и Symfony. Несмотря на то, что разработчики были уведомлены о проблеме ещё 2 декабря, исправление до сих пор не выпущено и последний выпуск SwiftMailer 5.4.5-dev остаётся уязвимым. Метод эксплуатации полностью аналогичен уязвимости в PHPMailer.
$email_from = '"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'; Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fattacker\] Arg no. 4 == [-oQ/tmp/] Arg no. 5 == [-X/var/www/cache/phpcode.php] Arg no. 6 == ["@email.com]
Источники
править
Любой участник может оформить статью: добавить иллюстрации, викифицировать, заполнить шаблоны и добавить категории.
Любой редактор может снять этот шаблон после оформления и проверки.
Комментарии
Если вы хотите сообщить о проблеме в статье (например, фактическая ошибка и т. д.), пожалуйста, используйте обычную страницу обсуждения.
Комментарии на этой странице могут не соответствовать политике нейтральной точки зрения, однако, пожалуйста, придерживайтесь темы и попытайтесь избежать брани, оскорбительных или подстрекательных комментариев. Попробуйте написать такие комментарии, которые заставят задуматься, будут проницательными или спорными. Цивилизованная дискуссия и вежливый спор делают страницу комментариев дружелюбным местом. Пожалуйста, подумайте об этом.
Несколько советов по оформлению реплик:
- Новые темы начинайте, пожалуйста, снизу.
- Используйте символ звёздочки «*» в начале строки для начала новой темы. Далее пишите свой текст.
- Для ответа в начале строки укажите на одну звёздочку больше, чем в предыдущей реплике.
- Пожалуйста, подписывайте все свои сообщения, используя четыре тильды (~~~~). При предварительном просмотре и сохранении они будут автоматически заменены на ваше имя и дату.
Обращаем ваше внимание, что комментарии не предназначены для размещения ссылок на внешние ресурсы не по теме статьи, которые могут быть удалены или скрыты любым участником. Тем не менее, на странице комментариев вы можете сообщить о статьях в СМИ, которые ссылаются на эту заметку, а также о её обсуждении на сторонних ресурсах.