Имеет ли значение адрес arg c при переполнении буфера? - PullRequest
0 голосов
/ 02 февраля 2020

Я работаю над переполнением стекового буфера на Protostar, и моя конечная цель - лучше понять, что происходит. Я нахожусь на упражнении 4 (https://exploit.education/protostar/stack-four/). Я получил переполнение буфера для выполнения желаемой функции, но я могу сделать это только в GDB. Причина, по которой я могу сделать это только в gdb, заключается в том, что второе слово после конца буфера, который я использую, содержит адрес памяти arg c. Если это второе слово будет перезаписано, то вызов функции не будет работать. Я скомпилировал с опцией -fno-stack-protector.

В gdb я запустил:

run <<< (echo -e "$(python -c "print('h'*64)")aaaa\xa0\xf0\xff\xbfaaaaaaaaaaaaaaaaaaaa\x3b\x84\x04\x08\x37\x16\xe2\xb7")

64 часа заполнили буфер, первые четыре a просто переполнили слово, следующий четыре байта являются адресом аргумента c, следующие 5 слов (20 а) просто переполняются. Затем я помещаю адрес win (функция, которую я хочу вызвать), а затем старый адрес возврата, чтобы выйти без segfault.

Когда я запускаю это в gdb, я вызываю функцию win, и процесс завершается. Когда я запускаю это за пределами GDB, я получаю segfault. Я подумал, что, возможно, переменные окружения были разными, но это не тот случай, когда я изменил переменные окружения в gdb так, чтобы они точно совпадали с тем, что есть у меня вне gdb, и он все еще не работает.

7 слов после Конец буфера и до адреса возврата: 1: 0xb7fbb300 - Неизвестно 2: 0xbffff0a0 - адрес argc 3: 0x00000000 - пусто 4: 0xb7e21637 - Адрес возврата, но не фактический, который имеет значение. (не знаю, почему их два) 5: 0xb7fbb000 - Неизвестно 6: 0xb7fbb000 - Неизвестно 7: 0x00000000 - Неизвестно

Итак, мои вопросы: почему это работает только в gdb? и каково значение адреса arg c для предотвращения segfault? И почему я вижу обратный адрес дважды? Один раз на 4-м слове после буфера и снова на 8-м слове после буфера.

1 Ответ

0 голосов
/ 02 февраля 2020

Когда я запускаю это в GDB, я вызываю функцию win, и процесс завершается. Когда я запускаю это вне gdb, я получаю ошибку segfault.

GDB отключает рандомизацию адресов по умолчанию (используйте (gdb) set disable-randomization off, чтобы включить его в GDB).

Рандомизация адресов был реализован точно , чтобы сделать атаки переполнения стека более сложными, поэтому неудивительно, что ваша атака блокируется им.

Вы можете отключить систему рандомизации адресов в целом, или вы можете заставить свою атаку работать, несмотря на рандомизацию (возможно, пытаясь тысячи раз с разными адресами и надеясь, что вам повезет, или сделав полезную нагрузку переполнения устойчивой к изменениям &argc).

...