Стек полностью испорчен, пытаясь вызвать переполнение буфера - PullRequest
0 голосов
/ 19 марта 2020

после нескольких часов отладки без каких-либо усилий, я надеюсь найти здесь справку по StackOverflow.

В настоящее время я обучаюсь PTP и из-за того, что я использую только Linux, я также хочу потренироваться в самых первых лабораториях на моей локальной машине.

Мне нужно использовать очень простую Программу через переполнение буфера. Только источники даны:

goodpwd. cpp:

#include <iostream>
#include <cstring>

int bf_overflow(char *str){
       char buffer[10];         //our buffer
       strcpy(buffer,str);      //the vulnerable command
       return 0;
}

int good_password(){            // a function which is never executed
       printf("Valid password supplied\n");
       printf("This is good_password function \n");
       return 0;
}

int main(int argc, char *argv[])
{
       int password=0; // controls whether password is valid or not
       printf("You are in goodpwd.exe now\n");
       bf_overflow(argv[1]); //call the function and pass user input
       if ( password == 1) {
             good_password(); //this should never happen
 }
         else {
       printf("Invalid Password!!!\n");
 }
       printf("Quitting sample1.exe\n");
       return 0;
}

Я скомпилировал его, чтобы получить исполняемый файл, используя

gcc -fno-stack-protector -z execstack -o goodpwd goodpwd.cpp -ggdb -m32 -lstdc++ -no-pie -O0

(Я также уже пробовал это без -no-pie и -O0, но я подумал, что, возможно, проблема может быть в оптимизации ..)

Я использовал gdb для отладки исполняемого файла:

gdb goodpwd -tui -q

После установки точки останова на строку 6 (с уязвимым strcpy) я выполнил следующую команду:

(gdb) run AAAAAAAAAAAAAABCDE

после нажатия n на go на следующую строку, у меня было загляните в стек:

(gdb) x/20x $esp

это дало мне следующий результат:

0xffffd6f0:     0xffffd748      0x4141a8b0      0x41414141      0x41414141
0xffffd700:     0x41414141      0x45444342      0xffffd700      0x0804923b
0xffffd710:     0xffffd99c      0xf7fe4bd0      0xffffd800      0x08049209
0xffffd720:     0x00000002      0xffffd7f4      0xffffd800      0x00000000
0xffffd730:     0x0804c000      0x00000002      0x08049080      0xffffd760

Я не могу объяснить себе, почему:

  • есть два A в 0xffffd6f4
  • там нет A в 0xffffd6f6
  • Я получил 16 A, начиная с 0xffffd6f8
  • Я получил EDCB в 0xffffd704 (из-за маленького порядка, спасибо @ 1201ProgramAlarm)
  • $ bsp - 0xffffd708, а $ eip - 0x80491a7, но после выполнения еще двух шагов (выход из функции) $ eip устанавливается в 0x8 04923e, потому что после всего, что я узнал, я почти уверен, что это должно быть 0x08049209
  • , после этих двух шагов я получаю эту ошибку: main (argc=<error reading variable: Cannot access memory at address 0x4141a8b0>, argv=<error reading variable: Cannot access memory at address 0x4141a8b4>) at goodpwd.cpp:21

Я был бы очень признателен если есть кто-то, кто сможет мне помочь. Борьба в модуле 3 из 43 - не лучшее чувство, которое я когда-либо испытывал: D

Редактировать: ASLR должен быть деактивирован:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

1 Ответ

0 голосов
/ 19 марта 2020

Может быть, было слишком поздно вчера. Но сегодня я узнал, что @ 1202ProgramAlarm сделал очень хорошую мысль.

Из-за использования системы с прямым порядком байтов 0xffffd704 был прав. Мои заблуждения по поводу 0xffffd6f4 и 0xffffd6f6 были неуместны, потому что они не влияли на результат.

Значение старого $ EIP все еще было в 0xffffd70e, но я никогда не трогал его. Мне просто нужно было улучшить строку в аргументе, и после этого я смог использовать уязвимость. Это было очень весело. Спасибо за советы.

...