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

Обзор эксплойтов

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

Хакер, номер #092, стр. 092-050-7


00104B6 push dword ptr [eax]

00104B8 call sub_2C1EB

00104BD mov edi, eax

***** old.lst

00104B6 push dword ptr [eax]

00104B8 call sub_2C10D

00104BD mov edi, eax

Очевидно, что здесь вызывается одна и та же процедура (кто не верит — может посмотреть код самой процедуры), но утилитам сравнения этого ведь не объяснишь. А свой собственный скрипт писать лень. К тому же обнаруживается довольно странное поведение компилятора, иногда меняющего порядок следования команд в новой версии драйвера:

Листинг 4: Странное изменение порядка следования команд в разных версиях файлов

***** new.lst

016C91 mov edx, ecx

016C93 shr eax, 10h

016C96 shl edx, 10h

016C99 or eax, edx

***** old.lst

016C91 mov edx, ecx

016C93 shl eax, 10h

016C96 shr edx, 10h

016C99 or eax, edx

То же самое происходит и с регистрами:

Листинг 5: Странное изменение выбора регистров в разных версиях файлов

***** new.lst

01381B xor ecx, ecx

01381D mov ch, al

01381F mov cl, ah

013821 mov [esi+0Eh], cx

***** old.lst

01381B xor ecx, ecx

01381D mov cl, ah

01381F mov ch, al

013821 mov [esi+0Eh], cx

А ведь это еще не самое страшное! Поскольку в начале каждой строки стоит ее адрес, то при «раздвижке» одной или нескольких функций оставшаяся часть файла трактуется как «измененная», хотя в действительности изменились только адреса. Какой же выход? Копируем old.lst в old-1.lst, загружаем его в FAR по <F4> и, удерживая клавишу <ALT> (вместо <SHIFT>), вертикальными блоками отрезаем все операнды инструкций и адреса, стоящие в начале строки. Аналогичную операцию проделываем и над new.lst. В результате чего получаем два симпатичных файла вида:

push

mov

call

Пропускаем их через FC с обязательным выводом номеров строк (за это отвечает ключ /N), иначе мы потом не найдем соответствующие им адреса в old.lst/new.lst файлах, и с замиранием сердца наблюдаем за процессом. Конечно, мы получим много ложных срабатываний, уже приведенных в листинге 4. Но их очень легко отсеять чисто визуально — меняется лишь порядок следования команд, но сам шаблон остается неизменным. А вот и первое действительное различие:

Листинг 7: Реальное различие между старой и новой версией драйвера

***** old1.lst

024127: mov

024128: cmp

***** new1.LST

024127: mov

024128: call

024129: mov

024130: cmp

В прежней версии TCPIP.SYS никакого call'а не было! А ну-ка заглянем в дизассемблерный текст, открыв old.lst/new.lst файлы и перейдя к строке 24127.

Листинг 8: Сравнение дизассемблерных листингов двух версий TCPIP.SYS

01DF18 mov d,[esi+20h], 1988Bh mov d,[esi+20h], 1988Bh

01DF1F call PsGetCurrentProcessId call PsGetCurrentProcessId

01DF24 mov [esi+28h], eax mov [esi+28h], eax

call PsGetCurrentProcessId

mov [esi+2Ch], eax

01DF27 cmp [ebp+NewIrql], 2 cmp [ebp+NewIrql], 2

01DF2B mov [edi+8], esi mov [edi+8], esi

01DF2E jbe short loc_1DF40 jbe short loc_1DF48

01DF30 push asc_1DE7C; "Lock problems!!\n" push asc_1DE7C;"Lock problems!!\n"

01DF35 call DbgPrint call DbgPrint

01DF3A pop ecx pop ecx

01DF3B call DbgBreakPoint call DbgBreakPoint

Назад на стр. 092-050-6  Содержание  Вперед на стр. 092-050-8