Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #45, АВГУСТ 2004 г.

SEH на службе у контрреволюции

Крис Касперски aka мыщъх

Спецвыпуск Xakep, номер #045, стр. 045-048-4


Путь второй: зарегистрировать свой собственный SEH-фрейм. Как же мы сможем что-то зарегистрировать в системе, если еще не перехватили управления? – воскликнешь ты. Указатель на текущий обработчик всегда содержится в одном и том же месте – в первом двойном слове TIB'а, лежащего по адресу fs:[00000000h], и псевдофункцией poke его вполне реально перезаписать. Пусть вас не смущает наличие сегментного регистра FS – вся память, принадлежащая процессу, отображается на единое адресное пространство, и до TIB'а можно дотянуться и через другие сегментные регистры, например, через тот же DS, используемый процессором по умолчанию. Естественно, при адресации через DS TIB будет располагаться совсем по другому смещению, и, чтобы его узнать, придется прибегнуть к услугам отладчика. Ты можешь использовать Soft-Ice, Microsoft Kernel Debugger или любой другой отладчик по своему вкусу.

Сначала необходимо определить значение селектора, загруженного в регистр FS. В Soft-Ice за это отвечает команда "CPU" (если Soft-Ice настроен правильно, то все основные регистры автоматически отображаются в верхней части окна). Затем, просматривая таблицу глобальных дескрипторов, содержимое которой выводит команда "GDI", находим соответствующий ему базовый адрес. Для первого потока процесса на всех NT-подобных системах он равен FFDFF00h, а все последующие потоки уменьшают его на 1000h, то есть мы получаем ряд указателей вида 7FFDE000h, 7FFDD000h, 7FFDC000h...

В любом случае, протестировать вашу машину не помешает (вдруг какая-то версия NT поведет себя иначе?). Протокол работы с отладчиком приводится ниже.

ЛИСТИНГ

Определение адреса указателя на текущий SEH-фрейм

:cpu

Processor 00 Registers

----------------------

CS:EIP=0008:8046455B SS:ESP=0010:8047381C

EAX=00000000 EBX=FFDFF000 ECX=FFDFF890 EDX=00000023

ESI=8046F870 EDI=8046F5E0 EBP=FFDFF800 EFL=00000246

DS=0023 ES=0023 FS=0030 GS=0000

:gdt

Sel. Type Base Limit DPL Attributes

GDTbase=80036000 Limit=03FF

0008 Code32 00000000 FFFFFFFF 0 P RE

0010 Data32 00000000 FFFFFFFF 0 P RW

001B Code32 00000000 FFFFFFFF 3 P RE

0023 Data32 00000000 FFFFFFFF 3 P RW

0028 TSS32 80295000 000020AB 0 P B

0030 Data32 FFDFF000 00001FFF 0 P RW

003B Data32 00000000 00000FFF 3 P RW

Обрати внимание: FFDFF000h – это не адрес текущего SEH-фрейма. Это – указатель на фрейм. Сам же фрейм должен быть сформирован непосредственно в shell-коде, а в FFDFx000h занесен указатель на него (см. картинку).

Затем остается лишь совершить что-нибудь недозволенное или же пустить все на самотек, дождавшись, пока исковерканная переполнением программа не вызовет исключения естественным путем, и тогда наш SEH-обработчик немедленно получит управление. Остальное, как говорится, дело техники.

Подавление аварийного завершения приложения

Независимо от того, каким путем shell-код захватил управление, он может зарегистрировать свой собственный обработчик структурных исключений. Это делается приблизительно так:

Назад на стр. 045-048-3  Содержание  Вперед на стр. 045-048-5