Обзор эксплойтовКрис Касперски Количество критических дыр, обнаруженных в Windows за последние два месяц а, просто потрясает воображение — глаза разбегаются, не в сила х выбрать, к аким уязвимостям отд авать предпочтение. К тому же, дыр намного больше, чем к ажется. С уязвимостью в GDI+ ассоциирован только один бюллетень безопасности, но ошибок там… (в том числе, и неисправленных!). По сложившейся тра диции, затык а я старые дыры, MS успешно пробивает новые. MS GDI+ удаленное выполнение кода в GIF-парсереBriefГрафическая подсистема Windows, реализованная в библиотеке GDI.DLL (позже она перелопачена в GDI32. DLL), создавалась опытными людьми, которые привыкли сначала думать, а потом кодить. Неудивительно, что ошибки в GDI начали обнаруживаться только после того, как Microsoft перенесла львиную часть гра фического кода с прикладного уровня в ядро (поступившись безопасностью в угоду быст родействию). Уровень квали фикации сотрудников к тому времени уже упал, а вместе с ним упало и качество кода. К власти рвались карьеристы, к клавиатурам тянулись индусы и воинствующие пионеры, стре мясь разломать старый код и переписать его с нуля. Попытка создания улучшенной реализа ции графической подсистемы (известной под именем GDI+) не увенчалась успехом — новые возможности оказались поп росту невостребованными, а вот ошибки полезли, как грибы пос ле дождя. Значительная часть ошибок была ликвидирована в первые же годы существова ния GDI+ (смотри, например, «Microsoft Security Bulletin MS04-028 Buffer Overrun in JPEG Processing (GDI+) Could Allow Code Execution» по адресу —microsoft.com/technet/security/bulletin/MS04-028.mspx). Однако дефекты проектирования продолжают обнаруживаться и сегодня. Девятого октября два хакера Peter Winter-Smith (NGSSoftware) и Ivan Fratric (Zero Day Initiative) независимо друг от друга обнаружили ошибку в парсере GIF-файлов, приводящую к переполнению буфера с возможностью удаленного захвата управления. На самом деле, ошибок там намного больше (включая неинициализированные поля, используемые для вычисления размеров выделяемых блоков памяти, и косяки целочисленного переполнения) — такое впечатление, что парсер программировали даже не индусы, а чукчи. Исследование дизассемблерных листингов реально вызывает шевеление волос на голове. У меня до сих пор шерсть дыбом стоит. Но об этом мы поговорим чуть позже, а сейчас вернемся к двум обозначенным хакерам, обнаружившим ошибку переполнения в COLOR Stream, длину которого, естественно, никто не проверяет. TargetsIE 6.0/SP1, Office XP, Office 2007/ SP1/SP2/SP3, Word 2003/SP3, PowerPoint Viewer 2007/SP1, Excel Viewer 2003/SP3, Excel Viewer 2007/SP3. ExploitJohn Smith (Вася Пупкин) из хакерской группировки Evil Fingers (www.evilfingers.com), членом которой, кстати говоря, являюсь и я, выпустил exploit, написанный на Перле. Можно скачать как с официального сайта группы — evilfingers.com/patchTuesday/MS08_052_GDI+_Vulnerability_ver2.txt, так и с независимых сайтов — securityfocus.com/data/vulnerabilities/exploits/31020.pl. SolutionСамое радикальное и самое надежное решение — найти и удалить библиотеку GDIplus. dll, поскольку все равно ее никто реально не использует. Ну... практически никто. Некоторые приложения могут перестать работать, вынуждая нас устанавливать очередной комплект заплаток, скачать которые можно с securityfocus.com/bid/31020/solution. MS GDI+ переполнение кучи в Vec tor Markup LanguageBriefMicrosoft вновь оказалась на высоте реализации своих же собственных стандартов. А ведь как хорошо все начиналось! В памятном 1998 году, пока россияне пребывали в кризисном состоянии, Microsoft совместно с Macromedia усиленно продвигали на рынок язык векторной разметки (Vector Markup Language или, сокращенно, VML). Внедрялся он непосредственно внутрь HTMLкода и претендовал на стандарт, представленный на рассмотрение организации W3C. Впрочем, большого распространения VML так и не получил и в настоящий момент (опционально) его поддерживает только Google Maps. В частности, следующий код выводит на экран закрашенный эллипс: «<v: oval style="position: absolute; left:0; top:0; width:100px; height:50px" fillcolor="blue" />». Девятого октября хакер Greg MacManus из VeriSign отправил в iDefense Labs сообщение об обнаруженной им уязвимости в VML, конструктивно реализованной в динамической библиотеке GdiPlus.dll (iDefense Labs платит за информацию о дырах). Краткое техническое описание проблемы можно найти на labs.idefense.com/intelligence/vulnerabilities/display.php?id=743 и в официальном бюллетене безопасности MS08-052: go.microsoft.com/fwlink/?LinkId=125468. Не помешает также сходить и на сайт Security Focus, где дыра проходит под номером #31020: www.securityfocus.com/bid/31020. Однако ни один из этих ресурсов не дает ответа на вопрос: в чем, собственно, состоит суть программы и каким образом осуществить переполнения. Зарывшись в дебри дизассемблерных листингов, я быстро выяснил, что система позволяет создавать эллипсы с отрицательным фокусом, но не умеет рассчитывать объем динамической памяти, требующийся для их размещения (тривиальное целочисленное переполнение в процессе умножения). В результате происходит классическое переполнение кучи, приводящее к возможности удаленного захвата управления со всеми вытекающими отсюда последствиями. TargetsIE 5.5/6.0, Office XP, Office 2007/SP1/SP2/SP3, Word 2003/SP3, PowerPoint Viewer 2007/SP1, Excel Viewer 2003/SP3, Excel Viewer 2007/SP3. ExploitJohn Smith (Вася Пупкин) из хакерской группировки Evil Fingers (www.evilfingers.com), выпустил proof-of-concept exploit, который можно скачать как с официального сайта группы — http://www.evilfingers.com/patchTuesday/MS08_052_GDI+_Vulnerability.txt, так и с независимых сайтов: downloads.securityfocus.com/vulnerabilities/exploits/31018.html.txt. SolutionСамое радикальное и самое надежное решение (как уже отмечалось выше) — найти и удалить библиотеку GDIplus.dll, поскольку все равно ее никто реально не использует. Расширение «Skype » для Firef ox доступ к буфф обменаBriefКакое отношение имеет Skype к GDI+? Как можно эксплуатировать уязвимость в IE через Горящего Лиса? Оказывается — можно! Социальная инженерии в совокупности с систематическим подходом делают свое дело! Седьмого октября 2008 на milw0rm’е появился exploit, написанный польским хакером с труднопроизносимым ником irk4z. Он демонстрирует направленную атаку на буфер обмена через Skype-расширение для Горящего Лиса (https://developer.skype.com/SkypeToolbars), пользующееся большой популярностью и предустановленное на множестве компьютеров и ноутбуков. Подробности — в блоге первооткрывателя дыры (irk4z.wordpress.com), кстати, до сих пор еще не засветившейся на Secure Focus’е. Наверное, это потому, что хакер изъясняется исключительно на польском языке. Мой перевод предлагается ниже: «Я нашел ошибку в Скайповом расширении для Горящего Лиса, позволяющую модифицировать системный буфер обмена по своему усмотрению. Забавно, что данное расширение автоматически устанавливается инсталлятором Skype, так что количество уязвимых машин должно быть очень велико. Описанная дыра похожа на недавно обнаруженную уязвимость, открывающую доступ к буферу обмена посредством Adobe Flash и ActionScript, что позволяет атакующему манипулировать его содержимым». А где же здесь IE? А вот где! Скидываем жертве ссылку на сайт, сообщая, что его нужно смотреть только через IE. Пусть это будет какой-нибудь приличный сайт типа www.arcme.com, а мы тем временем незаметно подменяем адрес в буфере обмена и когда жертва вставит его в IE, она неожиданно окажется на www.free-shitty-hosting.com/~halyava/evil.html, где ее поимеет злобный HTML-код, эксплуатирующий одну из вышеописанных дыр в IE. TargetsУязвимость подтверждена в Skype extension for Firefox BETA 2.2.0.95. Про другие версии ничего не известно. ExploitДемонстрационный exploit можно скачать с milw0rm.com/exploit.php?id=6690 или воспользоваться исходным кодом, приведенным ниже (чтобы превратить его в боевую модель, достаточно убрать комментарии, заботливо вставленные автором):
SolutionВнимательно следить за буфером обмена. Это единственное «лекарство», существующее на сегодняшний день. GDI + internalsНесмотря на то, что библиотека GDIplus.dll используется только Офисом и IE, она стоит того, чтобы в ней поковыряться ломом на предмет поиска свежих багов... Microsoft, как водится, затыкает намного больше ошибок, чем описывает в бюллетенях безопасности. Да и те затыкает впопыхах, и только со второй третей попытки ей удается разогнать бардак, вернее, перегнать баги из одного места в другое. Как показывает хакерский опыт, совокупное количество ошибок представляет собой константу, осциллирующую вокруг некоторого значения. Библиотека GDIplus.dll интересна еще и тем, что позволяет продемонстрировать широкий арсенал хакерских техник, использующихся для анализа патчей. Сравнивая оригинальную и пропаченную версию, мы найдем, что именно исправила Microsoft и локализуем дыру вместе с обстоятельствами ее проявления. Сравнивать, естественно, будем утилитой PatchDiff — бесплатным аналогом коммерческого плагина к IDA Pro, скрывающимся за невразумительным названием BinDiff. Однако PatchDiff обнаруживает слишком много различий, большая часть из которых нам неинтересна и совершенно непригодна ни для локальных, ни, тем более, для удаленных атак. PatchDiff, конечно, мощное оружие, но хакерствовать все-таки приходится головой. Дедуктивный метод (активно использовавшийся Шерлоком Холмсом) позволяет отсеять огромное количество «холостых» функций на ранних стадиях анализа. Пару выпусков назад мы бегло описывали возможности PatchDiff’a. Теперь, когда ты уже немного освоился с ним, пришла пора переходить от пассивного созерцания к активному вторжению в машинный код. Нам потребуется IDA Pro 5.2 или выше (IDA Pro 5.3 в действительности представляет собой большой bug-fix). Бесплатная версия не поддерживает плагинов, но эту проблему легко решить, найдя в Сети или Осле статьи на тему «IDA Pro для бедных». PatchDiff денег не просит и потому общедоступен —cgi.tenablesecurity.com/tenable/patchdiff.php. А вот поиск графической библиотеки GDIplus.dll намного более проблематичен, чем это кажется на первый взгляд — слишком много версий и все такие разные. Я решил выложить анализируемые библиотеки на свой сервер, благо они re-distributable. Качай — nezumi.org.ru/souriz/GDIplus.rar. Открываем пропатченную версию в IDA Pro, дожидаемся окончания процесса дизассемблирования и выходим из ИДЫ, выгружая базу в idb-файл. Открываем оригинальную версию, дизассемблируем. Затем лезем в меню «Edit - Plugins» и зовем «PatchDiff» или просто нажимаем <CTRL-8> , открывая ранее сохраненную базу пропатченной версии библиотеки. Даем PatchDiff’у поработать минут с полчаса (на Pentium-III Coppermine) и втыкаем в результат. А он таков: 119 matched-функций (парных функций, в которых найдены различия — основных кандидатов на пост президента, тьфу, в хранители багов); 276 unmatched-функций (тех, которые отличаются настолько сильно, что PatchDiff’у не удалось сопоставить их друг с другом; баги здесь также вполне вероятны, но искать их — тухлое дело, требующее много ручной работы); 6367 идентичных функций (полностью совпадающих друг с другом; баги здесь, если и есть, то кочующие от одной версии к другой, то есть неисправленные). Вот такая, значит, ситуация. С учетом размера библиотеки (1,7 Мб) количество matched-функций не так уж и велико, однако, в пересчете на естественные единицы (пиво, сигареты) положение практически безнадежно. Даже если на анализ каждой функции тратить порядка 10 минут, то процесс завершится через 119 10/60 = 1.190/60 = 20 часов. С учетом реальной производительности труда нам потребуется по меньшей мере пара дней напряженной работы, причем безо всяких гарантий на успех, поскольку искомый код может скрываться в unmatched- функциях. На их анализ уйдет больше недели! Да за это время все мозги скурить можно, а из пивных бутылок построить скульптуры в стиле «Москва наносит удар по Церетели». А что если у нас только одна банка пива и меньше пачки сигарет? Успеем ли мы завершить анализ? Успеем! Главное — выработать план и четко ему следовать. Тупое попарное сравнение функций как-то не возбуждает. В самом деле, повадки противника хорошо известны. Почему бы не нанести удар в наиболее вероятные места локации? Может, кто помнит детские игрушки середины 80х? Всякие лабиринты, по которым катается шарик? Я (да и не я один) уже тогда выяснил, что проходить лабиринт лучше не с начала, а с конца (вообще-то, правильно сконструированный лабиринт должен быть к этому параллелен, вот только правильных лабиринтов вокруг нас упорно не наблюдается и чаще попадаются бракованные). Также и здесь. Переполнение кучи (если таковое есть) завязано на функциях из серии HeapAlloc, вызываемых напрямую или же через обертки типа malloc или new. Целочисленное переполнение часто (хотя и не всегда) связано с машинной командой IMUL. Вот их-то мы и будем искать в дизассемблерном тексте, а точнее в matched-функциях. Быстро, дешево и сердито. Результат, конечно, не гарантирован, но нам везет, и дырявая функция обнаруживается буквально через несколько минут стучания по клавиатуре. Вот она — int __stdcall sub_4ED096ED(HICON hIcon, int). Тут сразу и IMUL, и вызов HeapAlloc, причем умница IDA Pro распознала HeapAlloc даже во вложенной функции, правильно определив назначение передаваемого ей параметра как dwBytes. Возьмем этот трюк на заметку!
Кстати, наша подопытная располагается в списке matched-функций на почетном 44?м месте. То есть, где-то примерно посередине, и потому искать ее тупым попарным перебором пришлось бы очень долго. А так… мы потратили на это — считанные минуты. Конечно, без везения здесь не обошлось, но с другой стороны, ведь и с ножом у горла никто не стоял! Задача хакерства — поразить цель с ультразвуковой скоростью, а целей для атаки намного больше, чем свободного времени. Если штурм крепости завершился провалом, мы просто переходим к следующей — вот и все! Кстати, забавная деталь — ошибка-то совсем не там, хотя и в функции sub_4ED096ED(HICON hIcon, int)! Непатченная версия «забывала» инициализировать поле bmiHeader.biHeight и потому в пофиксенной библиотеке появилась команда «mov eax, [ebp+var_42C.bmiHeader.biHeight]», которую, собственно говоря, и «запеленговал» PatchDiff. Однако, ошибка никуда не исчезла, а как была, так и осталась. Команда IMUL (смотри строку «.text:4ED097F1 imul ecx, eax») подвержена целочисленному переполнению, подробно описанному в блоге securitylabs.websense.com/content/Blogs/3178.aspx (уязвимость парсера RLE-файлов в GDI+), где приводится бажная и исправленная версии библиотеки GDIplus.dll. При всей внешней схожести между этими примерами есть существенное различие. В нашем случае IMUL используется для детекции целочисленного переполнения (MS VC и некоторые другие компиляторы автоматически вставляют код, препятствующий передаче функции HeapAlloc заведомо некорректных значений). А вот в примере, взятом из блога, инструкция IMUL задействована в вычислении требуемого размера блока выделяемой памяти. Совсем не одно и то же! Поэтому сам по себе IMUL — еще не свидетельство наличия дыры и прежде, чем выносить окончательное заключение, следует проанализировать примыкающий к ней код. Конечно, это требует времени, но код, вставляемый компилятором, весьма характерен и распознается с первого взгляда. А как именно он борется с переполнением, подробно рассказывается в блоге одного из сотрудников Microsoft: blogs.msdn.com/michael_howard/archive/2005/12/06/500629.aspx. |