ВЗЛОМТюрин АлексейÈÄÅÌÍÀ ÏÀÑÕÀËÜÍÓÞÎÕÎÒÓÏîäðîáíîñòè egg hunt øåëëêîäà ïîñëåäíèõ íîìåðàõ ][ áûëà íàïèñàíà ñåðèÿ ñòàòåé ïî êîäèíãó æèâó÷èõ ñïëîéòîâñ èñïîëüçîâàíèåì ðàçíîîáðàçíûõ ìåòîäîâ îáõîäà ìåõàíèçìîâ çàùèòû â ïîñëåäíèõâåðñèÿõ Windows. ×òîáû òû áûë ïðîñâåùåí è ÷óâñòâîâàë ñåáÿ â ñïëîéòîñòîðîåíèèêàê ðûáà â áîðùå, ÿ ïîâåäàþ êîå-÷òî íà áëèçêóþ òåìó — øåëëêîäîïèñàíèå.À èìåííî: âíóòðåííîñòè è òåõíè÷åñêèå ïîäðîáíîñòè ìåòîäà/øåëëêîäà. Èìÿ åìó —Egg Hunting.×ÒÎ ÒÀÊÎÅ EGG HUNTING?По сути иггхантинг представляет собой небольшой по размерушеллкод, цель которого — найти в виртуальной памяти атакуемогопроцесса боевой шеллкод и передать ему управление процессом.Нахождение обеспечивается за счет уникальной последовательностисимволов, стоящих перед основным шеллкодом. Насамом деле, Egg Hunting — это один из классических методов,используемых в сплойтостроении/шеллкодописании. Используетсяон уже давно в тех или иных ситуациях. Лучшей работойпо данной теме считается статья такого известного человечкакак skape аж от 2003 года (hick.org/code/skape/papers/egghuntshellcode.pdf).À ÇÀ×ÅÌ ÎÍÎ ÍÀÌЕсли просто, то иггхантинг используют в ситуациях, когда основнойшеллкод не влезает в переполняемый буфер и/или неизвестно, где онразмещен в памяти. Если непонятно, то поймешь на примере. А еслис подробностями, то...Все мы просматриваем багтрэк, читаем описание уязвимостей, иногдазакладываем в PoC-сплойты. Большинство из них имеют начинку ввиде, например, запуска калькулятора или открытия TCP-порта. То жесамое относится и ко всякого рода статьям про сплойтостроение, гдесплойты применяются в лабораторных условиях, а начинка используетсятолько для того, чтобы показать, что все получилось.В реальной жизни, как ни странно, не все так просто, и функционалакалькулятора явно не хватает для того, чтобы и в систему въесться, иобойти всякие механизмы безопасности, не говоря уж об антивирусахи файерволах, и, к тому же, ограничениях на используемые символы.Конечно, во многом выручают staged-шеллкоды, где боевой шеллкодпопадает в память постепенно, по стадиям. М-м… в общем, иггхант —это подвид staged-шеллкода.К примеру, универсальный шеллкод назапуск калькулятора — всего 200 байт (а привязанный к конкретной ОСи ее адресам — всего 27 байт :)), на бинд — 341 байт. Если добавитьограничения на использование \x00\xff, что вполне обычно, получаем227 байт и 368 байт соответственно.Если предположить, что мы ограничены БУКВО-циферками: 534, 816.В общем, тут все понятно.Да и проcтой бинд порта — неинтересно. К примеру, шеллкод наустановку туннеля через DNS, о котором я писал в рубрике Easy Hack,весит аж за 1000 байт, и это в натуральном виде.Что же нам могут предложить эксплойты? Сколько могут вместить всебя начинки? По-разному. Очень.Это в лабораторных условиях при переполнении буфера мы получаембольшую, непрерывную, неизмененную область в стеке с полностьюконтролируемым EIP. Эх… Кстати, в MSF к каждому сплойту указываетсяразмер возможной начинки и запрещенные символы в раз-066 XÀÊÅÐ 08 /139/ 10
Результат переполненияПередача управления за счет перезаписи SEHв деледеле «Payload information». Например, ms08_067_netapi — 400 байт,trendmicro_serverprotect — 800 байт, а размер сплойтов на ActiveX неограничен,так как боевой шеллкод в куче. Как видишь, далеко не всесплойты могут вместить в себя все, что хотелось бы. Что же делать?Все зависит от ситуации, но иногда нам помогает техника иггхантинга.Иногда — это когда основной шеллкод есть еще где-то в виртуальномадресном пространстве процесса. Как его запихнуть туда? Всезависит от ПО. Например, для IE 6/7, извращаясь с ява-скриптом, мыможем запихнуть основной шелл в кучу или, для imap-сервера MercurMessaging — последовательной отправкой imap-запросов.ÍÎÂÀß ÆÈÇÍÜ ÈÃÃÕÀÍÒÈÍÃÀНе совсем новая, но... жизнь ведь не стоит на месте, и семейство ОСWindows обзавелось такими страшными словами как ASLR, SafeSEH,DEP, GS и т.д. Что это для нас значит? Писать сплойты, особенноуниверсальные, стало гораздо, гораздо труднее. Но, конечно, не невозможно.Раз разработчики используют комплексные меры по защите,мы используем комплексные меры по взлому :). Отличным примеромздесь является jit-spay шеллкод под IE8, FF3.6 с обходом DEP, ASLR(exploit-db.com/exploits/13649/), написанный Алексеем Синцовым. Вэтом сплойте он использовал иггхантинг в jit-спрее почти единственномдоступном куске в памяти, которая исполняема. Возможности запихнутьв спрей основной шеллкод не было из-за всевозможных ограничений.ÒÅÎÐÈßЧто собой представляет иггхантинг-шеллкод и требования к нему?В общем-то, иггхантгинг-шеллкод — это шеллкод минимального размера,который может быстро найти в вируальном адресном пространствепроцесса основной шеллкод и передать ему управление. Иггхантингнаходит основную начинку по последовательности символов, стоящихперед ней. Это так называемый tag или egg, потому и egg hunting. Само«яйцо» — уникальная четырехбайтовая последовательность символов,которая повторяется дважды. Дважды, чтобы избежать коллизий, тоесть неверных обнаружений иггхантером. К тому же, что это за боевойшеллкод, если у него или одно яйцо, или совсем их нету :).Основная «трудность» для иггхантера в том, что не все виртуальноеадресное пространство процесса выделено («существует»). То естьсуществуют невыделенные страницы памяти, попытка обратиться ккоторым вызовет ошибку access violation, и программа тупо вылетит.Во-вторых, начинка находится неизвестно где, поэтому доступныестраницы приходится побайтово перебирать. Существует три (с половиной)основных техники организации иггхантинга под семействоWindows. Общий алгоритм у них похож: иггхантер проверяет адресапамяти на возможность доступа и, при положительном результате,побайтово сравнивает память для поиска тега. Разница заключается вреализации.NTDISPLAYSTRING / NTACCESSCHECKANDAUDITALARMЭто основная (с половиной :)) техника. Она заключается в использованиисистемного вызова(system call) NtDisplayString для проверкидоступа к странице памяти. Вид вызова:NTSYSAPI NTSTATUS NTAPI NtDisplayString(IN PUNICODE_STRING String);Вообще, вызов производится за счет прерывания: в EAX указывается,какой вызов произвести, а в остальных регистрах — аргументы к нему.В данном случае адрес, к которому мы пытаемся получить доступ,лежит в регистре EDX. Ответ функции попадает в EAX и равен0xc0000005, если доступ к странице вызовет Access Violation. Для побайтовогосравнения используется оператор scads, который оперируетс нашим тэгом (egg) в EAX и адресом из EDI.Общий вид шеллкода и его подробное описание:00000000 6681CAFF0F or dx,0xfff00000005 42 inc edx00000006 52 push edx00000007 6A43 push byte +0x4300000009 58 pop eax0000000A CD2Eint 0x2e0000000C 3C05cmp al,0x50000000E 5Apop edx0000000F 74EFjz 0x000000011 B890509050 mov eax,0x7730307400000016 8BFA mov edi,edx00000018 AF scasd00000019 75EA jnz 0x50000001B AFscasd0000001C 75E7jnz 0x50000001E FFE7jmp ediИтак, первые две строчки выравнивают EDX под начало страницыпамяти. Размер минимальной страницы равен 1000h в x86, поэтому мыпроверяем адрес, и, если его нет, переходим к следующей странице.Таким образом, сначала мы меняем последние три байта EBX на FFF,а потом инкриминируем, что в итоге дает нам выравнивание по 1000h.После, при джампах, мы увеличиваем значение EDX либо на 1h(см.строки 00000019, 0000001C), либо до следующей страницы, то есть на1000h (см. 0000000F).Далее мы кладем EDX в стек, чтобы сохранить значение, так как регистрыменяют свои значения при вызове функции.Следующие две команды перемещают в EAX 0x43h. Этим мы указываем,что надо запустить именно функцию NtDisplayString. int 2eделает системный вызов. Результат, как уже говорилось, попадает вEAX. Его младшие байты мы сравниваем с 0x5 и при положительномXÀÊÅÐ 08 /139/ 10 067