【CSAPP】Attacklab 详解

Lab要求:

理解函数调用引起栈变化的机制,并利用此机制发现漏洞发起攻击

实验机器:

VMware的虚拟机——Ubuntu-20.04

实验材料:

CSAPP的官网selfstudy-handout:
点击以进入CMU提供的下载渠道
一定记得看Writeup!
在这里插入图片描述

关键小技巧:

1:直接./ctarget会给CMU服务器报告,就会出错,以-q运行则正常。
2:./flie1.exe | ./file2.exe是指将./file1的结果作为运行file2的参数, 例如./hex2raw < try.txt | ./ctarget -q,就是将十六进制字符转化为raw,再把它作为运行ctarget参数。
3:如果想以文件为输入调试ctarget可以这样:先将构造的16进制字符串转化为raw保存在sd.txt,再进入gdb,用-i来引入sd.txt:

在这里插入图片描述

Part 1 Level 1:

在这里插入图片描述
从writeup中找到任务:通过改写getbuf栈帧最下面的返回地址,使本该返回test的getbuf,去调用另一个存在于ctarget的未调用函数touch1

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>

sub $0x28,%rsp ,可以看到getbuf预留了40(dec)的位置给即将输入的字符。

在这里插入图片描述

由于小端法,0x4017c0被表示为c0 17 40

结果展示:

在这里插入图片描述
在这里插入图片描述





Part 1 Level 2:

在这里插入图片描述
从writeup中找到任务:通过改写getbuf栈帧最下面的返回地址,使本该返回test的getbuf,去调用另一个存在于ctarget的未调用函数touch2,且需要传入自己的cookie。

主要思路:

  1. 考虑到需要完成特殊的操作,首先需要用objdump把代码转化为十六进制数,构造字符串。
  2. 应该把代码转义成的数插入输入,再利用ret跳转至该位置运行自己插入的代码,
    再然后还是用ret跳转至touch2的位置,正常运行。

具体步骤:

  1. 先将需要完成的操作转化为十六进制数:
    比如 pushq 0x4017ec 就是 68 ec 17 40 00
    为什么用pushq?:ret==pop %rip会将当前的%rsp所在的内存读取出来,作为%rip即将要执行的指令,所以要先将这段插入代码之后要去的地址压入栈中。
    为什么赋值%rdi?:%rdi是默认用来传输第一参数的寄存器,一般是由调用者负责提前赋好值,我的目的在于覆盖它的赋值,让%rdi等于我的cookie。
    在这里插入图片描述

  2. 构建字符串:
    构建思路:首先要让我们插进来的代码运行,然后我们的代码会跳转至touch2:
    为了让我们插进来的代码得以运行,需要知道gets把我们的字符串放到了哪里,在gets的出口设置断点,
    查看get将我们的字符串放在了哪?可以看到我输入的“asdfasdf”应为gets的输出,即字符串地址保存在%rax,用x /s $rax查看%rax中保存的地址所在内存是否包含我的输入——“asdfasdf”,发现在0x5561dc78确实有我的输入。
    在这里插入图片描述
    那么应该在0x5561dc78+0x28,即0x5561dca0处放置0x5561dc78。
    在这里插入图片描述

结果展示:

在这里插入图片描述
在这里插入图片描述





Part 1 Level 3:

在这里插入图片描述
从writeup中找到任务:通过改写getbuf栈帧最下面的返回地址,使本该返回test的getbuf,去调用另一个存在于ctarget的未调用函数touch3,且需要以字符串传入自己的cookie。

主要思路:

  1. 考虑到需要完成特殊的操作,首先需要用objdump把代码转化为十六进制数,构造字符串。
  2. 应该于安全的位置存放cookie的ASCII码。
  3. 应该把代码转义成的数插入输入,再利用ret跳转至该位置运行自己插入的代码,
    再然后还是用ret跳转至touch3的位置,正常运行。

具体步骤:

1. 先将需要完成的操作转化为十六进制数:

在这里插入图片描述
为什么用pushq?:ret==pop %rip会将当前的%rsp所在的内存读取出来,作为%rip即将要执行的指令,所以要先将这段插入代码之后要去的地址压入栈中。
为什么赋值%rdi?:%rdi是默认用来传输第一参数的寄存器,一般是由调用者负责提前赋好值,我的目的在于覆盖它的赋值,让%rdi等于我打算存放字符串的地址,即0x5561dca8。
为什么将字符串存放于0x5561dca8如图?
在这里插入图片描述

这里是引用
Writeup 的小建议,大概是说hexmatch与strncmp会覆盖getbuf的栈帧,应当把字符串放置在安全的地方。
在这里插入图片描述
可以看到,0x5561dca8至 0x5561dcb8 的部分没有被污染,但0x5561dc78至 0x5561dca8 的数据均已被破坏,所以可以把数据放在0x5561dca8之上。

2. 构建字符串:

把之前反汇编好的十六进制字符填充到相应位置,得:
在这里插入图片描述

结果展示:

在这里插入图片描述

Part 2 Level 2:

在这里插入图片描述
从writeup中找到任务:通过改写getbuf栈帧最下面的返回地址,使本该返回test的getbuf,去调用另一个存在于ctarget的未调用函数touch2,且需要传入自己的cookie。


主要思路:

  1. 反汇编需要的操作
  2. 根据反汇编的结果在farm中寻找gadgets(ctrl+F)
  3. 按照合理的顺序插入数据以及gadgets的地址

具体步骤:

  1. 需要反汇编的操作为:
    在这里插入图片描述
  • 为什么使用pop?: 直接再farm中找到 mov $0x59b997fa, %rdi 比较困难,所以需要把0x59b997fa存入栈中,再进一步保存至寄存器
  • 为什么不用pop %rdi?: 使用的操作需要在farm中找到,而恰好没有pop %rdi (5f in hex)
  1. 找到相应的gadgets
  • 注意到在函数 addval_219 中,有58 90 c3,其中90表示什么也不做,所以正好满足gadgets的要求,
    对应着 pop %rax,开始于0x4019ab;
  • 而函数 addval_273 中,有48 89 c7 c3,对应着mov %rax, %rdi ,开始于0x4019a2;
00000000004019a7 <addval_219>:
  4019a7:	8d 87 51 73 58 90    	lea    -0x6fa78caf(%rdi),%eax
  4019ad:	c3                   	retq   

00000000004019a0 <addval_273>:
  4019a0:	8d 87 48 89 c7 c3    	lea    -0x3c3876b8(%rdi),%eax
  4019a6:	c3                   	retq 
  1. 构建入侵字符串
    在这里插入图片描述
    具体步骤解释: 注意箭头位置,此刻正在执行gadget_1,所以pop %rax,会把我提前安排好的cookie(0x59b997fa)赋给%rax,
    %rsp=%rsp-8,然后下一步执行retq (c3 in hex),即pop %rip,这会使程序跳转执行0x4019a2,即gadget_2,
    之后类似,不多赘述。

结果展示:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值