Размещение шеллкода в памяти
Шеллкод обычно вставляется в уязвимую программу через аргументы командной
строки, переменные окружения или строку ввода. В любом случае при создании
шеллкода, мы не знаем адрес, по которому он расположен. И все же мы должны знать
адрес строки "/bin/sh ". Небольшая хитрость позволит нам это
сделать.
При вызове подпрограммы при помощи инструкции call , процессор
сохраняет адрес возврата в стек, этот адрес непосредственно следует за адресом
инструкции call (см. выше). Обычно, следующий шаг - сохранить
состояние стека (особенно регистр %ebp инструкцией push
%ebp ). Чтобы получить адрес возврата при входе в подпрограмму, достаточно
забрать его из стека инструкцией pop . Конечно, мы сохраним нашу
строку "/bin/sh " непосредственно после инструкции
call , чтобы позволить нашему "самедельному прологу" предоставить
нам нужный адрес строки. Итак : beginning_of_shellcode:
jmp subroutine_call
subroutine:
popl %esi
...
(Шеллкод)
...
subroutine_call:
call subroutine
/bin/sh
Конечно подпрограмма у нас не настоящая: или вызов execve()
будет успешным и процесс заменится оболочкой, или он закончится неуспешно и
функция _exit() завершит программу. Регистр %esi дает
нам адрес строки "/bin/sh ". Теперь этого достаточно, чтобы
построить массив, поместив адрес после строки: первый элемент массива (в
%esi+8 , длина /bin/sh + нулевой байт) содержит
значение регистра %esi , второй - в %esi+12 - нулевой
адрес (32 бита). Код будет выглядеть так: popl %esi
movl %esi, 0x8(%esi)
movl $0x00, 0xc(%esi)
Диаграмма 6
показывает область данных:
Назад |
Содержание |
Вперед
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|