Размещение шеллкода в памяти
Шеллкод обычно вставляется в уязвимую программу через аргументы командной
строки, переменные окружения или строку ввода. В любом случае при создании
шеллкода, мы не знаем адрес, по которому он расположен. И все же мы должны знать
адрес строки "/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
показывает область данных:
Назад |
Содержание |
Вперед
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|