Привет, я пытаюсь написать эксплойт переполнения для простой программы, которую я создал. Bellow — это программа на C, которую я написал.
#include <unistd.h>
#include <string.h>
#include <stdio.h>
char *string_in = "Did not work";
int test(char *this){
char sum_buf[6];
strncpy(sum_buf,this,24);
return 0;
}
void hello(){
printf("hello man");
string_in = "If this triggered, it means our shell code is working\n";
return;
}
int main(int argc, void **argv){
test("01234567890123456789\x00\x40\x06\x02");
printf("My string is %s",string_in);
return 0;
}
В основном происходит то, что строка должна быть прочитана в EBP с перезаписью со значением 0x00400602, которое является адресом возврата моей функции hello(). Я знаю, что это значение адреса для моей функции hello, так как objdump -d test_stack.o. Из дампа объекта я могу сказать, что rsp был расширен на 20 байт, как показано ниже.
00000000004005b4 <test>:
4005b4: 55 push %rbp
4005b5: 48 89 e5 mov %rsp,%rbp
4005b8: 48 83 ec 20 sub $0x20,%rsp
4005bc: 48 89 7d e8 mov %rdi,-0x18(%rbp)
4005c0: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4005c7: 00 00
4005c9: 48 89 45 f8 mov %rax,-0x8(%rbp)
4005cd: 31 c0 xor %eax,%eax
4005cf: 48 8b 4d e8 mov -0x18(%rbp),%rcx
4005d3: 48 8d 45 f0 lea -0x10(%rbp),%rax
4005d7: ba 18 00 00 00 mov $0x18,%edx
4005dc: 48 89 ce mov %rcx,%rsi
4005df: 48 89 c7 mov %rax,%rdi
4005e2: e8 a9 fe ff ff callq 400490 <strncpy@plt>
4005e7: b8 00 00 00 00 mov $0x0,%eax
4005ec: 48 8b 55 f8 mov -0x8(%rbp),%rdx
4005f0: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
4005f7: 00 00
4005f9: 74 05 je 400600 <test+0x4c>
4005fb: e8 a0 fe ff ff callq 4004a0 <__stack_chk_fail@plt>
400600: c9 leaveq
400601: c3 retq
0000000000400602 <hello>:
400602: 55 push %rbp
400603: 48 89 e5 mov %rsp,%rbp
400606: b8 6d 07 40 00 mov $0x40076d,%eax
40060b: 48 89 c7 mov %rax,%rdi
40060e: b8 00 00 00 00 mov $0x0,%eax
400613: e8 98 fe ff ff callq 4004b0 <printf@plt>
400618: 48 c7 05 0d 0a 20 00 movq $0x400778,0x200a0d(%rip) #
Начиная с суммы менее $20,%rsp, я знаю, что мне нужно написать не менее 20 байтов... но я не уверен, сколько еще мне нужно написать, чтобы добраться до моего rbp. Возможно, что из моих вычислений мне нужно записать 8 или мои байты, так как есть 2 вызова x. Хотя я действительно не уверен, сколько мне нужно написать.
Я компилирую свою программу так...
gcc -g stack.c -o test_stack.o
execstack -s test_stack.o
Поскольку я использую Ubuntu 11, моя версия ядра похожа на 3.0.17, поэтому я знаю, что мой aslr включен по умолчанию. Возможно, мне нужно отключить это, но я не знаю, как это сделать. Также я запускаю i386:x86_64. Могу ли я сказать, как на самом деле выглядит мой стек во время прогона? Как я могу заставить это работать и как узнать, сколько мне нужно написать?
Спасибо за помощь
\x00\x40\x06\x01
. Кроме того, я думаю, вам может понадобиться изменить порядок этих байтов, потому что x86 хранит 0x00400601 в памяти как 0x01, 0x06, 0x40, 0x00. Наконец, я не знаю, помогут ли мои предложения. Это зависит от того, как gcc создает фрейм стека. Лучше всего выполнить пошаговое выполнение в отладчике, чтобы вы могли видеть, что происходит. - person Jim Mischel   schedule 20.04.2012sub $0x20,%rsp
выделяет 32 байта для кадра стека, а не 20 (шестнадцатеричная запись). - person Michael Foukarakis   schedule 20.04.2012