Shellcode своими руками

Xakep, номер #044, стр. 044-038-5


char *var1="correct";

..

recv(s,buff,5000,0); - получение данных

if(strcmp(buff,var1)==0)... - сравнение буфера с переменной 1.

...

return 0; возврат из процедуры

В этом случае мы не можем присвоить переменной 1 произвольное значение - она является указателем на область памяти, содержащим строку "correct". Если после переполнения там окажется "левое" значение, то функция strcmp вызовет ошибку, и программа "вылетит", до исполнения нашего кода дело не дойдет.

Мы не можем точно знать, что находится после MP-зоны - одна из критичных переменных или адрес возврата, а нам нужно как-то перезаписать его. Вот два приема, позволяющие решить эту проблему.

1. Побайтовый подбор. Размер данных увеличивается на 1, и последний байт подбирается так, чтобы сервис сохранял работоспособность. Способ хороший, почти универсальный, но далеко не всегда работает. Например, если наши данные обрабатываются как ASCIIZ-строка, то в конце данных обязан быть символ с кодом 0 - это не позволит нам подобрать последний символ, т.к. его значение нам неподвластно.

2. Наполнение достаточным числом адресов возврата. Мы не будем пытаться определить, что находится после MP-зоны, а просто поставим в нее адрес возврата, повторенный достаточно много раз. Учитывая, что компиляторы выравнивают данные в стеке, все указатели, находящиеся между буфером и адресом возврата, будут указывать на один и тот же адрес, на него же будет указывать и адрес возврата. Способ тоже интересный, но если в ту область данных что-то запишут, то в момент возврата из процедуры там будет уже не шеллкод, а неизвестно что.

3. Этот способ - модификация второго. После MP-зоны записываются убывающие значения, шаг убывания равен длине шеллкода. Это гарантирует нам, что указатель после переполнения будет указывать на область памяти, находящуюся после шеллкода, и одновременно избавляет нас от необходимости угадывать расстояние от MP-зоны до адреса возврата - любое из значений может подойти в качестве адреса возврата.

Все эти способы требует также знания еще одного параметра: "выравнивания". Нет гарантии, что разница между началом буфера и адресом возврата кратна четырем. Вообще, MP-зона вполне может "заезжать" в область критичных переменных, поэтому нам придется подбирать еще один параметр брутфорсом: на сколько байт необходимо сократить MP-зону. Для этого надо перебрать значения от ноля до трех.

Итог - если пользоваться третьим способом определения значения критичных переменных, нам потребуется порядка 50 попыток, чтобы "вслепую" выполнить произвольный код даже в довольно тяжелых случаях, когда мы ничего не знаем о структуре стека уязвимой программы. За исключением зависимости от протокола, этот эксплоит, снабженный шеллкодами под все ОС, будет универсальным. Вот так мы достигли worldwide rulez'а...

Ссылки по теме

Smashing The Stack for Fun and Profit (Aleph1)

http://www.phrack.com/show.php?p=49&a=14

eEye Digital Security

http://www.eeye.com/

Online shellcode generator

Назад на стр. 044-038-4  Содержание  Вперед на стр. 044-038-6