Я пытаюсь выполнить атаку переполнения буфера в программе, написанной на c, я использую GNU / Linux (Ubuntu 16.04 LTS). это исходный код:
#include<stdio.h>
void CALLME(){
puts("successful!");
}
int main(void){
char s[16];
scanf("%s",s);
}
что я хочу сделать, так это переопределить адрес возврата main, чтобы после основной функции выполнялась функция CALLME. я компилирую программу с
gcc -m32 -fno-stack-protector -o prog prog.c
используйте команду:
nm prog | grep CALLME
я получил адрес CALLME: 0804845b
дизассемблировать main в gdb я обнаружил, что: во время основной функции адрес возврата находится в 8 (% ebp), а адрес строки s находится в -0x18 (% ebp). Таким образом, разница составляет 0x8 + 0x18 = 32
я пытаюсь использовать:
perl -e 'вывести "a" x 32. "\ x5b \ x84 \ x04 \ x08" '| ./основной
это не сработало.
Segmentation fault (core dumped)
Почему ? Основная функция более особенная? Потому что в других функциях (которые я сделал) с аналогичной уязвимостью он работает?
ПРИМЕЧАНИЕ: я не думаю об ASLR, некоторые ребята сказали, что это происходит только тогда, когда я компилирую gcc -pie ... и другие вещи.
я так не думаю. как я уже сказал: если я перемещаю 2 строки в основной функции в функцию, которую я сделал (назовите ее run ()), то в main: я вызываю run (), моя атака была успешной, разница в адресе возврата (run () ) имеет значение 4 (% ebp) и начинается с -0x18 (% ebp), я использую: perl -e 'print "a" x28. "\ x5b \ x84 \ x04 \ x08" '| ./основной
«Я так не думаю» звучит не очень уверенно. Вы пишете int main(void) в своем коде, но на самом деле main принимает два аргумента, int argc и char *argv[], так что вы перезаписываете по крайней мере их. Вы также более тщательно проверяли код, который настраивает фрейм стека, чтобы увидеть, что он пытается сохранить, а затем восстановить?
ах. может между ними есть какие-то важные дела. Спасибо за вашу помощь. я буду исследовать больше.

sначинается с-0x18(%ebp), а ваш обратный адрес - с8(%ebp). Поскольку дляsвыделено только 16 байтов, похоже, что у вас есть 8 + 0x18 - 16 = 16 байт в стеке между-8(%ebp)и8(%ebp), которые важны, но которые вы перезаписываете с помощью a. Вам необходимо изучить стековый фрейм дляmainболее подробно.