>>> Врезка 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-функции в памяти, освобождаясь от фиксированных адресов и чехарды версий. Изначально кривую программу легче переписать с нуля, чем каждый раз подкладывать новые подпорки и костыли. Впрочем, на этот счет есть разные мнения, так что свой путь выбирает каждый.