Я хочу использовать уязвимость фрагмента кода C в образовательных целях, управляя стеком. Простое переполнение буфера в стеке, при котором адрес возврата перезаписывается адресом, по которому должен выполняться шелл-код. Код представляет собой простую функцию, которая принимает в качестве аргументов буфер и пытается strcpy()
буфер получить фиксированный размер. Параметр, заданный в main, является argv[1]
. Поэтому я думаю, что если бы я нашел точный объем памяти, который мне нужно перезаписать, то я мог бы просто дать в качестве входных данных строку, составленную из \x90
(инструкции NOP), за которой следует шелл-код и в конце адрес этого буфера. Поскольку это первый аргумент, его адрес равен $ebp+8
, и вы можете найти его, запустив gdb
, установите точку останова в начале функции и просто наберите i args
, чтобы получить адрес строки, которая передается как аргумент. Итак, я обнаружил, что если я перезаписываю n
байтов и затем даю значения адреса, то это точно перезапишет адрес возврата. Итак, у меня есть такой ввод:
perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)'
Это не сработало, и я попытался понять, почему. С gdb
я запускаю программу. Я поставил точку останова перед функцией strcpy()
. В этот момент у меня есть аргумент, который является строковым указателем, который указывает на мой ввод, и его адрес совпадает с указанным в конце моего ввода, я шагнул вперед на 1 инструкцию. Я осмотрел стек. Теперь у меня есть сохраненный eip
($ebp + 4
) со значением адреса, указанного в конце argv[1]
, что является ожидаемым поведением (это означает, что он не перезаписывает другие адреса выше адреса возврата, который является значение первого аргумента). Странно то, что теперь содержимое $ebp+8
- это не «адрес», а что-то еще? Но содержимое сохраненного eip
- это адрес, который указывает на мою строку, которая использует vuln. Но не похоже, что ret addr выполняет содержимое этого адреса.