• XSS.stack #1 – первый литературный журнал от юзеров форума

Уязвимость в OpenSMTPD, позволяющая удалённо выполнить код с правами root

INC.

REVERSE SIDE OF THE MEDAL
Эксперт
Регистрация
02.02.2008
Сообщения
3 950
Реакции
1 872
В развиваемом проектом 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
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх