Как заточить exploit под себя

       

>>> Врезка explouit'ы, атакующие Windows, фиксированные адреса и все-все-все


Вот типичный пример учебного exploit'а http://milw0rm.com/shellcode/1675 (см. прилагаемый файл 1675.c):

unsigned char beepsp1[] =

"\x55\x89\xE5\x83\xEC\x18\xC7\x45\xFC"

"\x10\xC9\xEA\x77"                       //Address \x10\xC9\xEA\x77 = SP1

...

"\x00\x00\x8B\x45\xFC\xFF\xD0\xC9\xC3";

unsigned char beepsp2[] =

"\x55\x89\xE5\x83\xEC\x18\xC7\x45\xFC"

"\x53\x8A\x83\x7C"                       //Address \x53\x8A\x83\x7C = SP2

"\x00\x00\x8B\x45\xFC\xFF\xD0\xC9\xC3";

int main()

{



       void (*function)();

       *(long*)&function = (long)beepsp1;

       function();

}

Листинг 4 фрагмент простейшего exploit'а, работающего под Windows, и привязывающего к фиксированным адресам

Данный shell-код вызывает функцию beep из KERNEL32.DLL, обращаясь к ней по ее непосредственным адресам, которые в разных версиях Windows, естественно, будут сильно неодинаковые. На наш выбор предоставляется всего два варианта — XP SP1 и XP SP2, причем, никакого автодетекта не производится и нужный shell-код приходится подключать самостоятельно. А как быть, если мы хотим атаковать W2K SP5?

Используем утилиту DUMPBIN из SDK для определения адреса функции beep, вызывая ее со следующими ключами: "DUMPBIN /EXPORTS /HEADERS KERNEL32.DLL > out.txt" (при этом KERNEL32.DLL соответствующей версии должен быть в нашем распоряжении).

OPTIONAL HEADER VALUES

       79430000 image base

...

       ordinal       hint   RVA           name

       13     C      0000D4D1      Beep

Листинг 5 фрагмент информации, сообщенной dumpbin

Вычисляем адрес функции Beep – к image base (79430000h) добавляем RVA адрес самой функции (0000D4D1h), получаем — 7943D4D1h, который и записываем в shell-код, не забывая про обратный порядок байт в x86: "\xD1\xD4\x43\x79".

К чести создателя exploit'а, в нем, по крайней мере, присутствуют комментарии.
Другие хакеры их не оставляют! В результате, exploit падает под всеми версиями Windows, кроме одной. Вопрос — какой именно? Дизассемблер показывает ничего не значащие адреса, над которыми для "изгнания" нулей могут проводится всякие математические манипуляции.

00000006: C745FC1396EA77   mov    d,[ebp][-04],77EA9613

0000000D: 806DFC13         sub    b,[ebp][-04],13

Листинг 6 фрагмент shell-кода, привязывающего к фиксированным адресам

В ячейку [ebp-04] заносится значение 77EA9613h из которого тут же вычитается 13h, следовательно эффективный адрес равен 77EA9600h. Это легко. Сложнее разобраться — какой функции он принадлежит. Приходится перебирать все версии Windows, какие только есть в нашем распоряжении в надежде, что хоть в одной из них по заданному адресу окажется начало функции и эта функция будет той, которую ожидает увидеть exploit (проверять можно хоть soft-ice, хоть dumpbin).

Занятие это трудное и неблагодарное. К черту такой exploit! В статье "техника написания переносимого shell-кода", опубликованной в одном из прошлых номеров "хакера" наглядно показывалось как находить API-функции в памяти, освобождаясь от фиксированных адресов и чехарды версий. Изначально кривую программу легче переписать с нуля, чем каждый раз подкладывать новые подпорки и костыли. Впрочем, на этот счет есть разные мнения, так что свой путь выбирает каждый.


Содержание раздела