Exploits review (выпуск 0xB)

Сегодняшний обзор exploit'ов мы посвятим Windows Vista, количество дыр в которой, несмотря на все заявления Microsoft, довольно значительно, и многие из них - критические (а ведь поставки Висты только начались). Microsoft едва успевает выпускать заплатки, а хакеры тем временем находят все новые и новые дыры.

GDI - локальное повышение привилегий

brief

Графическая подсистема Windows (GDI) продолжает оставаться одной большой дырой, значительная часть которой интегрирована в ядро и реализована в драйвере win32k.sys, однако GDI активно использует адресное пространство пользовательского процесса, помещая все элементы интерфейса (такие, например, как окна), в специальные объекты-секции, защищенные от непреднамеренной(!) записи со стороны пользовательского приложения, но допускающие умышленное проецирование секции на другой регион с атрибутами записи. Также существует возможность "повторного" выделения блока памяти внутри секции с присвоением ему необходимых атрибутов. Впервые это было обнаружено в далеком 2004 году хакером по имени Cesar Cerrudo, а чуть позже появился GDIKernelPoC-exploit, находящий GDI-объекты тупым перебором обработчиков (handles), и закладывающийся на то, что первый же найденный обработчик и есть указатель на секцию с GDI-объектом. Это справедливо для Windows 2000 с XP, но Виста и 2003 Server реализованы слегка иначе и потому GDIKernelPoC-exploit на них не работает (подробнее об этом можно прочитать в 6-м выпуске нашего обзора exploit'ов). Joel Eriksson усовершенствовал технику поиска GDI-секции путем введения дополнительных проверок на соответствие размеров найденного блока минимально возможному размеру таблицы GDI, а также анализу полей nUpper, ProcessID и nType, значения которых известны заранее, в результате чего ему удалось создать усовершенствованную модель exploit'а, пробивающую защиту Server 2003 и Виста, с которым он выступил на последней конференции Black Hat (текст презентации в формате pdf лежит по адресу https://www.blackhat.com/presentations/bh-eu-07/Eriksson-Janmar/Whitepaper/bh-eu-07-eriksson-WP.pdf).

targets

Уязвимости подвержены все платформы линейки NT до Windows Виста включительно.

exploit

Исходный код exploit'а на Си, написанный хакером с ником Ivanlef0u (http://ivanlef0u.free.fr), можно скачать с http://www.milw0rm.com/exploits/3688, он несет на себе shell-код, исполняющийся в режиме ядра и получающий управление путем модификации таблицы системных вызовов (SSDT). Это proof-of-concept exploit, всего лишь перезагружающий машину, однако shell-код может быть доработан и тогда...

solution

Microsoft не только не предоставила заплатку, но даже не обозначила сроки ее появления в обозримом будущем, так что эта дыра обещает стать весьма продуктивной лазейкой для хакеров и всяких прочих червей.

Сайт хакера Ivanlef0u

Рисунок 1. Сайт хакера Ivanlef0u.

CSRSS - множественные уязвимости

brief

CSRSS - Клиент/Серверная Подсистема Времени Выполнения (Client/Server Runtime Subsystem), реализованная в процессе csrss.exe - важнейший компонент архитектуры Windows NT, обеспечивающий работу всех установленных подсистем, которых изначально было три: POSIX, OS/2 и Win32, но OS/2 уже давно сдулась, POSIX, реализованная не лучшим образом, никогда не входила в штатную поставку Windows и постепенно исчезла как никому не нужный костыль, в результате чего осталась единственная подсистема - Win32, которая позднее (начиная с NT 4) была интегрированная в ядро и за csrss.exe остались лишь консольные приложения и управление потоками, тем не менее с точки зрения хакеров процесс csrss.exe представляет значительный интерес, хотя бы уже потому, что он исполняется с привилегиями SYSTEM и обладает правами отладки, а завершение процесса csrss.exe приводит к появлению Голубого Экрана Смерти. Практически сразу после выхода Висты, в CSRSS обнаружились три(!) критических ошибки, позволяющие завешивать систему, повышать локальные привилегии и даже выполнять удаленный shell-код.

Первая ошибка, найденная хакером по кличке NULL, описана на http://www.securityfocus.com/bid/21688 и сидит внутри функции NtRaiseHardError, которая при передаче ей стартового адреса одного из потоков csrss.exe обрушивает систему.

Вторая ошибка, обнаруженная компанией eEye Digital Security (уже после того, как Microsoft выпустила CSRSRV.DLL для закрытия первой), связана с процедурами удаленного вызова LPC/ALPC (что расшифровывается как Local Procedure Call и Advanced Local Procedure Call, соответственно), позволяющих приложениям взаимодействовать через ApiPort'ы, допускающие повторное открытие (при этом система ведет специальный счетчик, увеличивающийся на единицу при открытии и уменьшающийся при закрытии), однако в LPC-коде присутствует ряд мест, ничего не знающих ни о каких счетчиках и уверенных, что LPC-соединение может быть установлено только однажды. Одним из таких мест является функция CsrApiRequestThread, экспортируемая библиотекой CSRSRV.DLL и позволяющая манипулировать чужими LPC-соединениями, что в конечном счете приводит к повышению привилегий. Технические подробности содержатся в отчете eEye: http://www.securityfocus.com/archive/1/465233.

Третья ошибка, обнаруженная Tim'ом Garret'ом из Determina Security Research и независимо от него уже упомянутым хакером с ником NULL, сидит в библиотеке WINSRV.DLL (также относящейся к CSRSS) и при выводе диалоговых окон с сообщениями о "тяжелых" ошибках (HardError-messages) может выполнить произвольный код, переданный как локально, так и удаленно (через скрипты, размещенные на Web-странице, например). Подробности об этом можно почитать на http://www.securityfocus.com/bid/23324/info.

targets

Уязвимы практически все системы линейки NT, включая Microsoft Windows Vista x64 Edition 0, Vista Ultimate, Vista Home Premium, Vista Home Basic, Vista Enterprise, Vista Business и Windows Vista 0.

exploits

В сети уже появилось множество exploit'ов, использующих эти уязвимости. Вот только малая часть из них:
http://www.securityfocus.com/data/vulnerabilities/exploits/21688.cs;
http://www.securityfocus.com/data/vulnerabilities/exploits/21688.c; http://www.securityfocus.com/data/vulnerabilities/exploits/exploit-df-csrss-XPSP2.c; http://www.securityfocus.com/data/vulnerabilities/exploits/ms_csrss_exp.c.

solution

Microsoft выпустила заплатки для всех трех дыр, поэтому для защиты своего компьютера достаточно скачать последние обновления (по умолчанию система это делает автоматически).

Исходный код боевого exploit'a

Рисунок 2. Исходный код боевого exploit'a.

Windows Genuine Advantage - взлом через OEM BIOS

brief

Windows Genuine Advantage (сокращенно WGA) - самый мерзкий компонент Windows, ответственный за проверку подлинности регистрационных ключей, привязывающийся к железу и требующий повторной активации при его замене, что напрягает не только любителей халявы, но и обладателей лицензионных копий. Все это делает WGA соблазнительной мишенью для атаки, уже давно и с треском взломанной, несмотря на яростное сопротивление со стороны Microsoft, которая вместо того, чтобы думать головой, угрожает хакерам судебными исками, но... для этого их (хакеров) сначала найти надо!

Очередной метод взлома базируется на том факте, что ряд крупных OEM-поставщиков отказались от предустановки Висты, раздражающей пользователей своей глупой активацией, и стали коситься в сторону лагеря Linux и BSD. Microsoft тут же пошла на уступки и включила в Висту специальный код, проверяющий BIOS на принадлежность к определенному кругу OEM-поставщиков (с которыми Microsoft заключила специальное соглашение) и не требующий активации в данном случае (см. http://blogs.msdn.com/wga/archive/2007/04/10/reported-oem-bios-hacks.aspx). Хакеры тут же дизассемблировали код и выяснили, что WGA ищет в BIOS'е специальную идентификационную строку, находящуюся в boot-блоке и проецирующуюся в адресное пространство ЦП. Лихие головы тут же кинулись перешивать BIOS'ы, рискуя безвозвратно угробить компьютер, в то время как другие внедрили в загрузчик операционной системы специальную программу, проецирующую boot-блок в оперативную память (если это не сделала сама BIOS, см. опцию shadow-ROM) и уже там, в памяти, дописывающую подходящую идентификационную строку. Третьи же пошли по пути перехвата системных функций, читающих BIOS и возвращающих результат ОК или не ОК. Короче, вариантов взлома полно - только выбирай!

targets

Все версии Висты: Microsoft Windows Vista x64 Edition 0, Vista Ultimate, Vista Home Premium, Vista Home Basic, Vista Enterprise, Vista Business и Windows Vista 0.

exploits

Microsoft ведет борьбу со всеми, кто отваживается выложить код (неважно - исходный или откомпилированный) "ломалки" в сеть, поэтому линки постоянно меняют адреса и мрут как мухи, зачастую не продержавшись и нескольких часов. То же самое относится и к списку идентификационных строк.

solution

Купить лицензионную версию Висты.

Блог одного из разработчиков WGA

Рисунок 3. Блог одного из разработчиков WGA, признающего новый тип атаки.

Full disclose: ANI-формат - удаленное переполнение буфера

brief

В 2005 году компания eEye Digital Security, обнаружив классическое переполнение буфера в функциях, обрабатывающих анимированные курсоры (ANI), уведомила Microsoft и выпустила свою собственную заплатку, не дожидаясь выхода официального обновления (от Microsoft'а дождешься). Microsoft исправила ошибку, но полного аудита кода, естественно, не проводила и вот в конце марта 2007 года та же самая компания eEye Digital Security "выловила" в дикой природе несколько атакующих программ, работающих по схожему принципу и поражающих XP SP2 вместе с только что вышедшей Вистой. eEye Digital Security вновь уведомила Microsoft и выпустила обновленную версию своей заплатки вместе с исходными текстами, на основании которых хакер по кличке devcode, со ссылкой на CVE-2007-1765, создал proof-of-concept exploit, попавший на milw0rm (http://www.milw0rm.com/exploits/3617). Затем последовал exploit от хакера marsu (заявившего, что exploit от devcode у него не работает) и хотя marsu-exploit'у удалось "засветиться" на Security Focus (www.securityfocus.com/bid/23373) и milw0rm (http://www.milw0rm.com/exploits/3647), завешивая множество приложений: Word, WinAmp, Проводник и IE (последний - только при отключенном DEP'е), уязвимости был присвоен "локальный" статус и некоторое время ей не уделяли никакого внимания. Затем последовал бум exploit'ов, работающих даже при активном DEP (что позволило атаковать Висту с настройками по умолчанию путем посылки письма с анимированным курсором внутри или размещением этого же курсора на Web-страничке, посещаемой жертвой) - http://www.milw0rm.com/exploits/3652, а вместе с ними появились exploit'ы, пробивающие заплатку от eEye - http://www.milw0rm.com/exploits/3636, за которыми последовал готовый генератор exploit'ов - http://www.milw0rm.com/exploits/3651 и атаки возобновились с новой силой. Компания Zert, проанализировав ситуацию, установила, что заплатка от eEye исправляет лишь часть уязвимого кода, оставляя другую часть нетронутой. Заплатка, выпущенная Zert'ом, полностью ликвидировала уязвимость, заткнув течь (http://zert.isotf.org/advisories/zert-2007-01.htm), а через некоторое время вышло внеплановое официальное обновление от Microsoft, по умолчанию устанавливающееся на Висту в автоматическом режиме, однако учитывая, что достаточно многие пользователи предпочитают скачивать обновления вручную (то есть, не скачивать их вообще), а также то, что данная уязвимость затрагивает не только Висту, но и всех ее предшественниц из линейки NT, атаки закончатся еще не скоро, поэтому имеет смысл остановиться на этой дыре и рассмотреть ее поподробнее.

Живые курсоры

Рисунок 4. "Живые" курсоры также могут быть заражены вирусами и прочей сранью.

targets

Все версии Висты: Microsoft Windows Vista x64 Edition 0, Vista Ultimate, Vista Home Premium, Vista Home Basic, Vista Enterprise, Vista Business и Windows Vista 0.

exploits

http://www.milw0rm.com/exploits/3617;
http://www.milw0rm.com/exploits/3634;
http://www.milw0rm.com/exploits/3635;
http://www.milw0rm.com/exploits/3636;
http://www.milw0rm.com/exploits/3647;
http://www.milw0rm.com/exploits/3648;
http://www.milw0rm.com/exploits/3651;
http://www.milw0rm.com/exploits/3652;
http://www.milw0rm.com/exploits/3692;
http://www.securityfocus.com/data/vulnerabilities/exploits/ani_loadimage_chunksize2.rb;
http://www.securityfocus.com/data/vulnerabilities/exploits/ani_loadimage_chunksize.rb;
https://www.immunityinc.com/downloads/immpartners/ani_cursor.tar;
https://www.immunityinc.com/downloads/immpartners/ani_vista.tar;

solution

Официальное обновление от MS.

full disclose

Анимированные курсоры хранятся в файлах с расширением .ani, cur, или .ico, представленных в RIFF-формате (Resource Interchange File Format - Файловый Формат для Обмена Ресурсами), имеющих теговую структуру, состоящую из порций данных произвольного типа, называемых "чанками" (от английского "chunk" - "ломоть", "большой кусок"). RIFF-формат неплохо документирован и помимо анимированных курсоров используется для хранения аудио и видеоданных; avi, wav и midi-файлы - все они являются примерами RIFF.

Живой курсор в hiew

Рисунок 5. "Живой" курсор в hiew'e.

За анимированным курсором закреплен тег "anih" (61h 6Eh 69h 68h), а сам чанк имеет следующую структуру:

struct ANIChunk
{
        char tag[4]; // ASCII-тег "anih"
        DWORD size; // длина чанка в байтах
        char data[size]; // данные, описывающие "раскладку" курсора в файле
}

Листинг 1. Структура чанка "anih".

Образцы "правильных" анимированных курсоров можно выдернуть из штатной поставки Windows (они расположены в папке \WINNT\Cursors\), ниже приведен фрагмент одного из них:

0000000000:  52 49 46 46 C2 1B 00 00 | 41 43 4F 4E 4C 49 53 54  RIFF??  ACONLIST
0000000010:  48 00 00 00 49 4E 46 4F | 49 4E 41 4D 0E 00 00 00  H   INFOINAM?
0000000020:  53 70 69 6E 6E 69 6E 67 | 20 43 6F 69 6E 00 49 41  Spinning Coin IA
0000000030:  52 54 26 00 00 00 4D 69 | 63 72 6F 73 6F 66 74 20  RT&   Microsoft
0000000040:  43 6F 72 70 6F 72 61 74 | 69 6F 6E 2C 20 43 6F 70  Corporation, Cop
0000000050:  79 72 69 67 68 74 20 31 | 39 39 33 00 61 6E 69 68  yright 1993 anih
0000000060:  24 00 00 00 24 00 00 00 | 09 00 00 00 09 00 00 00  $   $   ?   ?
0000000070:  00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00
0000000080:  02 00 00 00 01 00 00 00 | 4C 49 53 54 3A 1B 00 00  ?   ?   LIST:?
0000000090:  66 72 61 6D 69 63 6F 6E | FE 02 00 00 00 00 02 00  framicon??    ?

Листинг 2. Фрагмент дампа анимированного курсора coin.ani, позаимствованный из штатного комплекта поставки Windows.

Несмотря на то, что по спецификациям от Microsoft поле data может иметь произвольную (и формально ничем не ограниченную) длину, программисты из Microsoft своих собственных спецификаций не читают (они, наверное, вместо этого траву курят), размещая в data структуру, состоящую ровно из 24h байт, которые функция user32.dll!LoadCursorIconFromFileMap, вызываемая из функции user32.dll!LoadAniIcon, копирует в буфер фиксированного размера посредством функции memcpy(dst, src, size), без всяких проверок size на корректность размера!

Естественно, если size > 24h, происходит классическое стековое переполнение с подменой адреса возврата и возможностью передачи управления на shell-код, находящийся здесь же, в массиве data.

Для предотвращения переполнения компания eEye модифицировала функцию LoadCursorIconFromFileMap (псевдокод которой приведен ниже), добавив явную проверку на размер. Точно также поступала и Microsoft в своей заплатке, выпущенной под кодовым названием MS05-002.

int LoadCursorIconFromFileMap(struct MappedFile* file, ...)
{
        struct ANIChunk chunk;
        struct ANIHeader header; // 24h-байтовая структура

        ...

        // читаем первые 8 байт чанка (в них расположен ASCII-тэг)
        ReadTag(file, &chunk);

        // это наш тэг "anih"?
        if (chunk.tag == "anih")
        {
                // проверяем размер на корректность
                + if (chunk.size != 36) // добавлено MS05-002 и eEye

                // если размер != 24h отваливаем
                + return 0;

        // читаем чанк в локальный буфер фиксированного размера
        ReadChunk(file, &chunk, &header);
}

Листинг 3. Исправленный псевдокод уязвимой функции LoadCursorIconFromFileMap, читающий чанки из анимационных файлов.

Однако оказалось, что если в файле присутствует более одного "anih"-чанка, второй и все последующие чанки обрабатывает совершенно другой код, сосредоточенный в функции USER32.DLL!LoadAniIcon (см. листинг 4) и, естественно, работающий по той же схеме, что и первый (то есть, никаких проверок не выполняющий), поскольку программисты из Microsoft уже давно освоили метод copy-n-paste, а выполнять аудит всего кода - лень, да и времени нет (и так покурить не дают):

int LoadAniIcon(struct MappedFile* file, ...)
{
        struct ANIChunk chunk;
        struct ANIHeader header; // 24h-байтовая структура
        
        ...
        
        while (1)
        {
                // читаем первые 8 байт чанка (в них расположен ASCII-тэг)
                ReadTag(file, &chunk);
                
                // в зависимости от типа тэга делаем либо то, либо другое
                switch (chunk.tag)
                {
                        case 'seq ': // обрабатываем тэг "seq"
                                        ...
                        
                        case 'LIST': // обрабатываем тэг "LIST"
                                        ...
                        
                        case 'rate': // обрабатываем тэг "rate"
                                        ...
                        
                        case 'anih': // обрабатываем тэг "anih"
                                        // читаем chunk.size в 24h-байтовую структуру

                                        ReadChunk(file, &chunk, &header);
                        ...

Листинг 4. Псевдокод уязвимой функции LoadAniIcon, обрабатывающий второй и все последующие "anih"-чанки.

Таким образом, чтобы пробить заплатку от eEye или официальный патч MS05-002 от Microsoft, необходимо поместить в .ani файл два чанка: первый - правильный и второй - вызывающий переполнение.

Дамп одного из таких файлов приведен ниже. Он не несет на своем борту никакого shell-кода и "всего лишь" вызывает исключение при попытке просмотра анимированного курсора любым приложением, поддерживающим данный формат - например, знаменитым IrfanViever'ом:

00000000   52 49 46 46  90 00 00 00  41 43 4F 4E  61 6E 69 68   RIFF....ACONanih
00000010   24 00 00 00  24 00 00 00  02 00 00 00  00 00 00 00   $...$...........
00000020   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
00000030   00 00 00 00  01 00 00 00  61 6E 69 68  58 00 00 00   ........anihX...
00000040   41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41   AAAAAAAAAAAAAAAA
00000050   41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41   AAAAAAAAAAAAAAAA
00000060   00 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41   .AAAAAAAAAAAAAAA
00000070   41 41 41 41  41 41 41 41  41 41 41 41  00 00 00 00   AAAAAAAAAAAA....
00000080   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................
00000090   42 42 42 42  43 43 43 43                             BBBBCCCC

Листинг 5. Полный дамп ani-файла, пробивающего заплатку от eEye вместе с официальным патчем MS05-002 от Microsoft.

А что насчет Internet Exporer'a? Его, в отличие от Irfan Viewer'а, заставить выполнять shell-код не так-то просто и помимо всего прочего необходимо обойти защиту от выполнения кода в стеке (известную под кодовым именем DEP - Data Execution Prevention), обхитрить механизм разномизации адресного пространства (ASLR - Address space layout randomization) и преодолеть проверку целостность адреса возврата, выполняемую функцией при трансляции программы компилятором Microsoft Visual C++ 7.x с ключом /GS.

Просмотр анимированных курсоров в InfanView

Рисунок 6. Просмотр анимированных курсоров в InfanView'е.

DEP, ASLR и /GS - вот три причины, по которым большинство exploit'ов отказываются работать на Висте, работающей на процессоре с поддержкой флагов NX/XD (аппаратный DEP), но все эти защиты достаточно легко обойти (впрочем, как и все остальное, сделанное Microsoft), однако это уже тема совершенно другого разговора. Любопытствующих мы отсылаем к сборнику мыщъхиных статей (http://nezumi.org.ru/vista-overstack-pack.zip), подробно рассматривающих методику борьбы со всей "святой троицей".

Интересные ссылки по теме