准备工作:
务必仔细看实验的相关文档提示,非常重要。
level 1:
这个题目相当容易,该题会运行test函数,test函数调用了Gets函数,我们就是需要在Gets函数执行return语句时,利用我们输入的非常奇妙的字符串,然后去执行touch1函数。而不是顺利返回到test函数中即可。
理解题意后:
1.确定touch1函数的位置。使用objdump -d ./ctarget命令。
00000000004017c0 <touch1>:
4017c0: 48 83 ec 08 sub $0x8,%rsp
4017c4: c7 05 0e 2d 20 00 01 movl $0x1,0x202d0e(%rip) # 6044dc <vlevel>
4017cb: 00 00 00
4017ce: bf c5 30 40 00 mov $0x4030c5,%edi
4017d3: e8 e8 f4 ff ff callq 400cc0 <puts@plt>
4017d8: bf 01 00 00 00 mov $0x1,%edi
4017dd: e8 ab 04 00 00 callq 401c8d <validate>
4017e2: bf 00 00 00 00 mov $0x0,%edi
4017e7: e8 54 f6 ff ff callq 400e40 <exit@plt>
得到我们想要的结果0x0000 0000 0040 17c0
2.画出test函数的运行时用户栈,找到Gets函数返回地址的存储位置以及缓冲溢出攻击需要溢出的量。使用gdb工具,在test函数和Gets函数设置断电。然后运行(注意这里的命令r -q)否则报错,因为我们不需要上传到成绩服务器。
这是test函数以及它运行时各寄存器的值,我们重点关注rsp栈顶指针。
Dump of assembler code for function test:
=> 0x0000000000401968 <+0>: sub $0x8,%rsp
0x000000000040196c <+4>: mov $0x0,%eax
0x0000000000401971 <+9>: callq 0x4017a8 <getbuf>
0x0000000000401976 <+14>: mov %eax,%edx
0x0000000000401978 <+16>: mov $0x403188,%esi
0x000000000040197d <+21>: mov $0x1,%edi
0x0000000000401982 <+26>: mov $0x0,%eax
0x0000000000401987 <+31>: callq 0x400df0 <__printf_chk@plt>
0x000000000040198c <+36>: add $0x8,%rsp
0x0000000000401990 <+40>: retq
End of assembler dump.
(gdb) info register
rax 0x0 0
rbx 0x55586000 1431855104
rcx 0xc 12
rdx 0x7ffff7dd3780 140737351858048
rsi 0xc 12
rdi 0x60601c 6316060
rbp 0x55685fe8 0x55685fe8
rsp 0x5561dca8 0x5561dca8
r8 0x7ffff7fd9700 140737353979648
r9 0xc 12
r10 0x4032b4 4207284
r11 0x7ffff7b7f970 140737349417328
r12 0x2 2
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x401971 0x401971 <test+9>
eflags 0x212 [ AF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
这是Gets函数
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>: sub $0x28,%rsp
0x00000000004017ac <+4>: mov %rsp,%rdi
0x00000000004017af <+7>: callq 0x401a40 <Gets>
0x00000000004017b4 <+12>: mov $0x1,%ea