Обзор уязвимости
Sendmail - один из самых
популярных почтовых агентов (Mail Transfer Agent - MTA).
Примерно 50%-75% серверов в Интернете
используют его для обмена почтой. Это не
удивительно, поскольку в ОС Unix и Linux он
установлен по умолчанию.
3 марта 2003 года мировая
общественность была уведомлена о новой
уязвимости найденной в Sendmail (5.79-8.12.7). Ее
нашел Марк Давд из Internet Security Systems X-Force.
Уязвимость найдена в функции обработки
заголовка сообщения. При получении письма
производится семантическая проверка
адреса получателя в том числе и полей "From",
"To", "CC". Для этих целей
используется функция crackaddr(char* addr), которая
описана в файле headers.c. Обрабатываемые
данные помещаются в статический буфер,
после заполнения которого они проходят
несколько проверок безопасности. Одна из
этих проверок функционирует некорректно,
эта особенность дает возможность
злоумышленнику (при помощи специально
формированного поля адреса) переполнить
буфер в куче и выполнить произвольный код
от имени пользователя, запустившего MTA.
Некорректная робота одной из проверок
заключается в обработке символов '<' и '>'
указанных в адресе реципиента. Дело в том,
что при обработке данного поля каждая
встреча символа '>' указатель buflim, который
ссылается на конец буфера, увеличивает на 1.
Но, в тоже время, появление '<' никак не
обрабатывается, хотя при возникновении
такой ситуации указатель buflim должен быть
уменьшен. Поскольку каждой закрывающейся
скобке должна предшествовать
открывающаяся мы не можем просто указать в
адресе N закрывающихся скобок чтобы
увеличить буфер на N. К сожалению для
увеличения значения указателя buflim на 1,
нужно использовать комбинацию '<>'. Для
вычисления максимального значения X на
которое можно увеличить указатель конца
буфера нужно решить простое уравнение:
(2 * x) <= (MAXNAME + 1 - 7) + x
x <= (MAXNAME + 1 - 7)
Таким образом мы определяем насколько
можно увеличить значение buflim чтобы добиться
максимального количества байт, которые
переполнят буфер. В данном случае оно будет
равно 250.
Эксплуатация
Из-за статистической декларации буфера на
пути к эксплуатации данной уязвимости
становятся компиляторы, размещающие
статические данные в сегменте данных (data
segment). Другими словами, должны быть некие
используемые статические данные
размещенные по окончании буфера, которые
при его переполнении исполнились бы от
имени процесса Sendmail. После экспериментов,
проведенных Польской хакерской командой LAST
STAGE OF DELIRIUM(LSD), выяснилось, что на
большинстве Unix системах за буфером такие
данные не расположены. Следующий список
содержит результаты, полученыее при
исследовании:
Freebsd 4.4 - (default & self compiled Sendmail 8.11.6) does not crash
Solaris 8.0 x86 - (default & self compiled Sendmail 8.11.6) does not crash
Solaris 8.0 sparc - (default & self compiled Sendmail 8.11.6) does not crash
HP-UX 10.20 - (self compiled Sendmail 8.11.6) does not crash
IRIX 6.5.14 - (self compiled Sendmail 8.11.6) does not crash
AIX 4.3 - (binary of Sendmail 8.11.3 from bull.de) does not crash
RedHat 7.0 - (default Sendmail 8.11.0) does not crash
RedHat 7.2 - (default Sendmail 8.11.6) does not crash
RedHat 7.3 (p) - (patched Sendmail 8.11.6) does not crash
RedHat 7.0 - (self compiled Sendmail 8.11.6) crashes
RedHat 7.2 - (self compiled Sendmail 8.11.6) crashes
RedHat 7.3 - (self compiled Sendmail 8.11.6) crashes
Slackware 8.0 (p) - (patched Sendmail 8.11.6 binary) crashes
Slackware 8.0 - (self compiled Sendmail 8.12.7) does not crash
RedHat 7.x - (self compiled Sendmail 8.12.7) does not crash
(p) -установлен патч
Из предложеной вашему вниманию статистики
прежде всего видно, что многие системы
являются потенциально чувствительны к
данной уязвимости. Это RedHat и Slackware Linux. Как
выяснилось, причиной крушения Sendmail в этих
системах является неверное значение
указателя MciCache, объявленого в файле mci.c. LSD
провели более детальное исследование и им
удалось успешно эксплуатировать
уязвимость Buffer Overrun в системе Linux Slackware 8.0.
Достичь этого удалось изменяя значения
некоторых указателей и MciCache в частности.
Определенно нужно изменить следующие
данные:
- установить значение статического
указателя MCI **MciCache в адрес начала структуры
mailer_con_info,
- установить адрес структуры *mci_mailer в адрес
MCI,
- аказатель на *mci_host в адрес MCI,
- аказатель на FILE *mci_out в адрес MCI.
После внесения изменений становится
возможным влияние на исполнение процеса
Sendmail:
Program received signal SIGSEGV, Segmentation fault.
0x400ee94a in _IO_vfprintf (s=0xaabbccdd, format=0x809b773 "%s%s",
ap=0xbfffd6ac) at vfprintf.c:1024
1024 vfprintf.c: No such file or directory.
(gdb) where
#0 0x400ee94a in _IO_vfprintf (s=0xaabbccdd, format=0x809b773 "%s%s",
ap=0xbfffd6ac) at vfprintf.c:1024
#1 0x400f7047 in fprintf (stream=0xaabbccdd, format=0x809b773 "%s%s")
at fprintf.c:32
#2 0x8084ff8 in smtpmessage ()
#3 0x80847ac in smtpquit ()
#4 0x8069e89 in mci_uncache ()
#5 0x8069f14 in mci_flush ()
#6 0x804e0b9 in finis ()
#7 0x8073042 in dowork ()
#8 0x807f9bc in smtp ()
#9 0x804da8e in main ()
#10 0x400c19cb in __libc_start_main (main=0x804ac00 <main>, argc=3, argv=0xbffffbe4,
init=0x804a07c <_init>, fini=0x808918c <_fini>, rtld_fini=0x4000ae60
<_dl_fini>, stack_end=0xbffffbdc)
at ../sysdeps/generic/libc-start.c:92
Как видно вызов функции fprintf идет со
сфальсифицированным значением указателя
потока FILE*. Далее следует увеличить
количество изменений, для полного контроля
над уязвимым процессом. А точнее внести
изменения в структуру _IO_FILE. После внесения
необходимых изменений можно влиять на ход
выполнения процесса Sendmail:
Program received signal SIGSEGV, Segmentation fault.
0xaabbccdd in ?? ()
(gdb) where
#0 0xaabbccdd in ?? ()
#1 0x400f7047 in fprintf (stream=0xbfffa260, format=0x809b773 "%s%s")
at fprintf.c:32
#2 0x8084ff8 in smtpmessage ()
#3 0x80847ac in smtpquit ()
#4 0x8069e89 in mci_uncache ()
#5 0x8069f14 in mci_flush ()
#6 0x804e0b9 in finis ()
#7 0x8073042 in dowork ()
#8 0x807f9bc in smtp ()
#9 0x804da8e in main ()
#10 0x400c19cb in __libc_start_main (main=0x804ac00 <main>, argc=3, argv=0xbffffbe4,
init=0x804a07c <_init>, fini=0x808918c <_fini>, rtld_fini=0x4000ae60
<_dl_fini>, stack_end=0xbffffbdc)
at ../sysdeps/generic/libc-start.c:92
Как результат - возможность исполнения
произвольного кода. Реализацией данной
схемы нападения является эксплоит
написанный LSD.
Найденная уязвимость позволяет
атакующему удаленно получить права root'а (администратора)
на сервере с установленным Sendmail. Ситуацию
усложняет и тот факт, что такая атака не
будет обнаружена брандмаузерами или
другими пакетными фильтрами, даже в лог-файлах
не останется никаких следов. А для успешной
атаки злоумышленнику не нужно ничего знать
о удаленной системе.
Устранение уязвимости:
Но уже выпущена новая
версия Sendmail 8.12.8. А для оперативного
устранения уязвимость рекомендуется
отключить IDENT-проверку в .mc-файле: define(`confTO_IDENT',
`0s').
Дополнительная информация:
Описание - http://www.iss.net/issEn/delivery/xforce/alertdetail.jsp?oid=21950
Бюллетень CERT - http://www.cert.org/advisories/CA-2003-07.html
Senmail 8.12.8 - ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.12.8.tar.gz