Уязвимость в OpenSMTPD, позволяющая удалённо выполнить код с правами root
29 января 2020 года
В развиваемом проектом OpenBSD почтовом сервере OpenSMTPD выявлена критическая уязвимость (CVE-2020-7247), позволяющая удалённо выполнить shell-команды на сервере с правами пользователя root. Уязвимость выявлена в ходе повторного аудита, проведённого компанией Qualys Security (прошлый аудит OpenSMTPD проводился в 2015 году, а новая уязвимость присутствует с мая 2018 года). Проблема устранена в выпуске OpenSMTPD 6.6.2. Всем пользователям рекомендуется срочно установить обновление (для OpenBSD исправление можно установить через syspatch).
Предложено два варианта атаки. Первый вариант работает в конфигурации OpenSMTPD по умолчанию (приём запросов только с localhost) и позволяет эксплуатировать проблему локально, когда атакующий имеет возможность обратиться к локальному сетевому интерфейсу (loopback) на сервере (например, на системах хостинга). Второй вариант проявляется в случае настройки OpenSMTPD для приёма внешних сетевых запросов (почтовый сервер, принимающий стороннюю почту). Исследователями подготовлен прототип эксплоита, который успешно работает как с вариантом OpenSMTPD из состава OpenBSD 6.6, так и с переносимой версией для других ОС (проведено в Debian Testing).
Проблема вызвана ошибкой в функции smtp_mailaddr(), вызываемой для проверки корректности значений в полях "MAIL FROM" и "RCPT TO", определяющих отправителя/получателя и передаваемых в ходе соединения с почтовым сервером. Для проверки части почтового адреса, идущей перед символом "@", в smtp_mailaddr() вызывается функция valid_localpart(), которая считает допустимыми (MAILADDR_ALLOWED) символы "!#$%&'*/?^`{|}~+-=_" в соответствии с требованиями RFC 5322.
При этом непосредственное экранирование строки производится в функции mda_expand_token(), которая заменяет только символы "!#$%&'*?`{|}~" (MAILADDR_ESCAPE). В дальнейшем подготовленная в mda_expand_token() строка используется при вызове агента доставки (MDA) при помощи команды 'execle("/bin/sh", "/bin/sh", "-c", mda_command,...'. В случае помещения письма в mbox через /bin/sh запускается строка "/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}", где значение "%{mbox.from}" включает экранированные данные из параметра "MAIL FROM".
Суть уязвимости в том, что smtp_mailaddr() имеет логическую ошибку, из-за которой в случае передачи пустого домена в email функция возвращает успешный код проверки, даже если часть адреса до "@" содержит недопустимые символы. Далее при подготовке строки функцией mda_expand_token() экранируются не все возможные спецсимволы shell, а только спецсимволы, допустимые в почтовом адресе. Таким образом, для запуска своей команды достаточно использовать в локальной части email символ ";" и пробел, которые не входят в набор MAILADDR_ESCAPE и не экранируются. Например:
$ nc 127.0.0.1 25 HELO professor.falken MAIL FROM:<;sleep 66;> RCPT TO:<root> DATA. QUIT
После данного сеанса OpenSMTPD при доставке в mbox запустит через shell команду
/usr/libexec/mail.local -f ;sleep 66; root
При этом возможности атаки ограничиваются тем, что локальная часть адреса не может превышать 64 символа, а спецсимволы '$' и '|' заменяются на ":" при экранировании. Для обхода данного ограничения использован тот факт, что тело письма передаётся после запуска /usr/libexec/mail.local через входной поток, т.е. через манипуляции с адресом можно запустить только командный интерпретатор sh и задействовать тело письма как набор инструкций. Так как в начале письма указываются служебные SMTP-заголовки, для их пропуска предлагается использовать вызов команды read в цикле. Рабочий эксплоит приобретает примерно такой вид:
$ nc 192.168.56.143 25 HELO professor.falken MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;> RCPT TO:<root@example.org> DATA #0 #1... #d for i in W O P R; do echo -n "($i) " && id || break done > /root/x."`id -u`"."$$". QUIT
Источники
править
Любой участник может оформить статью: добавить иллюстрации, викифицировать, заполнить шаблоны и добавить категории.
Любой редактор может снять этот шаблон после оформления и проверки.
Комментарии
Если вы хотите сообщить о проблеме в статье (например, фактическая ошибка и т. д.), пожалуйста, используйте обычную страницу обсуждения.
Комментарии на этой странице могут не соответствовать политике нейтральной точки зрения, однако, пожалуйста, придерживайтесь темы и попытайтесь избежать брани, оскорбительных или подстрекательных комментариев. Попробуйте написать такие комментарии, которые заставят задуматься, будут проницательными или спорными. Цивилизованная дискуссия и вежливый спор делают страницу комментариев дружелюбным местом. Пожалуйста, подумайте об этом.
Несколько советов по оформлению реплик:
- Новые темы начинайте, пожалуйста, снизу.
- Используйте символ звёздочки «*» в начале строки для начала новой темы. Далее пишите свой текст.
- Для ответа в начале строки укажите на одну звёздочку больше, чем в предыдущей реплике.
- Пожалуйста, подписывайте все свои сообщения, используя четыре тильды (~~~~). При предварительном просмотре и сохранении они будут автоматически заменены на ваше имя и дату.
Обращаем ваше внимание, что комментарии не предназначены для размещения ссылок на внешние ресурсы не по теме статьи, которые могут быть удалены или скрыты любым участником. Тем не менее, на странице комментариев вы можете сообщить о статьях в СМИ, которые ссылаются на эту заметку, а также о её обсуждении на сторонних ресурсах.