声明:这个是本人自己探索稍微参考了上网上的。如有不对之处欢迎指正哦。

2018.6.15更新一些说得不清楚的地方(标红了)

1.运行makecookie生成属于自己的身份标识:

2.攻击五个缓冲区的四个地方,使我这个身份标识出现在它不该出现的地方。

3.Gets函数与gets函数类似,但不能判断数组越界,只能简单的将字符串复制到一个32个字节大小的数组。这也是本次hack的关键。

4. -u cookie 确保不同的人用不同的ID做题,并攻击不同的地址。-h用于打印这几个操作的内容

Level0:

第一关是让你修改getbuf函数保存的函数返回地址,本来执行完getbuf应该返回到test函数去的,但现在让你返回到smoke函数。

题目给了几条建议:

1.对bufbomb进行反汇编;

2.注意字节顺序;

3.使用GDB进行检查;

4.getbuf在栈的位置与gcc的版本有关。

解题过程:

输入一个超出32字节的字符串,覆盖ebp的内容,因为ebp存储的是test函数的返回地址,将其修改为smoke函数的首地址即可。但如何准确命中?

先来看getbuf函数的反汇编代码:

据此画出其栈结构图:

根据汇编代码可知最终esp在ebp-40这个位置,也就是说要想修改getbuf函数返回地址,要一个长40+8的字符串。由于地址是向上增大(注意是小端),因此函数的返回地址需要放在后44-48位。

先来看smoke函数的反汇编代码:

首地址是0x0804e0a,卧槽有个0a(被这里坑了),前面说了输入的字符串不能包含0a,不然那个Gets函数会以为你输入\n,就会结束字符串的输入。我想着能不能用smoke首地址的下一个地址来替代,然而是可以的。

测试字符串如下:

运行一哈看看:

Level1:

这一关跟第一关类似,也是修改getbuf的函数保存的函数返回地址让它进入一个叫fizz的函数。但是,需要自己传入一个参数,就是多了这么点东西。又来修改一下ebp的返回值?试试看。为什么我要强调进入而不是调用,进入跟调用是有区别的,函数在被调用之前,系统会将调用者的返回地址(也就是调完函数之后要执行的下一条指令的地址)保存入栈,就像test调用getbuf的时候,test函数的返回地址被保存在getbuf的栈中,因为执行完getbuf之后需要返回到test继续执行下一条指令,如何返回到test,就需要一个指引,也就是保存的那个函数返回地址。但进入由于是强行修改的,并不会保存函数的返回地址,所以进入的那个函数的堆栈结构会跟调用的函数不太一样,少了四字节来保存函数的返回地址。因此fizz取参的位置并不是ebp+8,而是多了四个字节的偏移量,在ebp+12处。详细分析看下面的图:

先来看看fizz函数的反汇编代码:

画出其堆栈结构:

汇编代码mov了一个立即数0x804a2e0,用GBD查看是什么玩意:

额。。是这么个东西。。

从栈结构图可以看出,fizz函数是从ebp+8处取参数,所以套路还是差不多的,前44个字节随便填点东西,45-48填fizz函数的入口地址,49-52填自己的cookie,因为fizz是从这个位置取参的。看看效果如何:

测试字符串:

最后一行是ebp+8的参数

???并没有返回我的cookie。

以下是我从网上查阅的资料:

test函数中调用getbu函数的堆栈结构:

修改返回地址为fizz函数的首地址后的堆栈结构:

getbuf函数执行完毕,执行leave语句:

执行ret语句后:

进入到fizz函数后:

由于我们是直接进入的fizz函数,而不是调用,因此系统并没有保存test函数 的返回地址。所以fizz堆栈里面并没有函数的返址。也就是说getbuf的ebp和fizz的ebp并不一样。因此并不是在ebp+8取参数,由于没有返址,在getbuf函数就多了4个字节的偏移量,因此要将我的cookie放在ebp+12这个位置。说白了就是fizz的ebp位置与其它函数的不一样。因此ebp+8并不是参数位置。

测试字符串:

运行看看:

原来对参数的设置也是有要求的。要设置为自己的身份标识。怪不得不提示我通关。

Levle2:

这一关跟前面的关卡也差不多。也是执行完getbuf函数后不返回到test,而是调用bang函数(注意这里是调用并不是单纯的进入,所以它后面要求你将bang函数的首地址压栈保存),它还多了一个全局变量作位参数。这一关就是要求你将bang函数首地址压入堆栈,然后通过ret来执行跳转。目前一脸懵逼完全不知道要干嘛?读完它给出的建议,大概意思是自己要写一个汇编代码然后生成机器码,再通过hex2raw传入给bufbomb。指导书后面给了个例子,大概意思跟我前面说的差不多,就是写一个汇编然后反汇编得到它的机器码,然后将getbuf的返址修改为它(它指的是你写的这个机器码)的首地址,就会执行先修改global_value的值然后进入bang函数。说白了你现在要写一个函数,具备以下功能:将全局变量设为你的cookie,然后调用bang函数判断有没有设置成功。

咋个写这个汇编呢?先来看bang函数的反汇编代码:

用GDB查看mov 0x804d10c到底是个什么玩意?

后面又和0x804d104的值进行比较。(联系下bang函数里面的if判断就应该能联想到这里是取参和gobal_value进行比较)

所以我猜想这个0x804d10c应该是全局变量 global_value 的地址。

所以要修改gobal_value的值只需把我的cookie赋给这个地址再push bang函数的首地址再ret一下应该就可以了。

下面是我的汇编代码:

这里就不要借助eax寄存器了,因为会使你的机器码变长,位数不符合要求。你可能会疑问,源操作数和目的操作数不是不能同时为两个内存地址啊?但注意,这里是一个立即数和内存地址,这种方法不太常见,我查阅了相关资料,发现是可以的。当时写博客忘记改这里了,实在抱歉。

编译+反汇编后得到一个d文件:相关指令在指导书给出了,自己翻一番。

那么需要的机器码就是这一堆东西了:c7 05 0c d1 04 08 95 1a 0e 48 68 52 8d 04 08 c3

接下来是怎么找到我写的这个函数的入口地址找到呢?

指导书给出方法了,用GBD设置断点调试,看下getbuf的汇编:

在call gets函数前,执行了对eax的一系列的操作。紧接着又来了一个mov  %eax,(%esp),这是ret也就是调用结束后esp返回到这里,所以我猜想此时的eax应该保存着调用函数的首地址。那么我写的函数的首地址应该也保存在这里。用GBD查看:

得到此时eax的内容,将getbuf函数的返址修改为它即可。

测试字符串如下:

运行一哈看看:

由于忘记是小端模式,将eax里面的地址内容填反了。给我来了个better luck next time 。

Level3:

第三关有点难。题目都读大半天。跟level2一样也要自己写汇编代码转换成机器码。这一关大概就是让你输入一个字符串,让getbuf函数返回自己的身份标识(cookie),说白了就是让你写一个函数具备以下功能:能将自己的cookie设置为getbuf函数的返回值且将test函数的首地址压入栈,然后通过ret来跳转。题目给的建议我就不巴拉巴拉了,跟level2的差不多。

先来看test函数这个小妖怪:

这个Boom就是用来检测你修改得对不对,不是判断失败的。我被这句代码卡了很久。

函数的返回值一般存储在eax寄存器中,所以通过修改eax的内容就可以修改返回值了。题目还有一个要求,不能改变它的旧ebp,因为它要继续执行test函数,才能判断你是否正确修改了返回值。所以level3有两种办法,第一种修复ebp(此处指的是新的ebp),第二种就是将test的地址压入栈然后再ret,此时再修改ebp的值(仿照调用bang函数的方法)。本人选择第二种。

先看test函数的反汇编:

调用getbuf后,执行的下一句语句,将这条指令的地址压入栈即可,因为getbuf函数被调用结束后就会顺着这个地址继续执行下去,也就达到了题目的要求了。

汇编代码如下:

(这里输错了cookie。应该是0x480e1a95的!!粗心害死人)

然后按照之前的步骤,把机器代码弄出来:

接下来是如何找到旧ebp的值呢?很简单,getbuf函数的第一个ebp存储的肯定是旧ebp。GBD查看:

这么个妖怪。

然后是找到我们编写的函数的地址:

和level2一样没有改变。

测试字符串如下:

运行:

Fuck!错了!错哪了??错哪了??

回去检测一遍,发现是ebp的值查看错了,应该是push ebp 后的值。还有一个错误,就是我输错了我的cookie。气哭啊。。。

如图:

应该是这个妖怪!

然后修改测试字符串:

运行一哈:

终于等到你!

第一种办法就是直接mov 原ebp的值给现在的ebp就好。其它还是一样。然后构造字符串的时候就不需要填原ebp的值了。

Level4:

最后一关了,想必很难。。自从bomb实验。。对闯关实验都留下阴影了。这一关要求你用-n这个指令,我也不知道这啥,先看题目,大概就是用-n运行bufbomb的时候,不再调用getbuf函数,而是调用一个叫getbufn的函数。两者类似,但getbufn限制了缓冲区的大小为512个字节,然后再-n模式下bufbomb会对你输入的测试字符串执行五次,每次都会有不同的堆栈偏移。你要一个汇编程序使得这五次执行都要返回你的cookie。。吗的好难的感觉。。然后它还要求getbufn函数返回你的cookie到test而不是返回1到cookie。。唉不难。修改下eax就好。判断你的cookie返回到test它会输出kaboom!然后又要通过ret来实现。。。。

它给的建议提是你用hex2raw发送多次字符串。指令给出了。然后就是要用同一个字符串攻击getbufn五次,还提示你用很多很大的nop指令来提高你的命中率,就是不停的nop,直到找到你写的那个机器代码的入口地址,这是我的理解。

getbufn这个小妖怪每次调用会在栈中随机分配一段存储地址,也就是它的ebp不是确定的。但我们的写的跳转地址是固定的,所以就需要大量的nop使得我们的攻击代码滑倒ebp那一段区域去,提高命中率。因此跳转代码要位于有效机器代码入口地址前的nop机器指令填充区,说白了,跳转代码和有效机器代码之间要填充大量的nop。

因为栈的机器代码是由低地址向高地址执行,因此有效的机器代码尽量后移。(所谓有 效机器代码就是咱们的攻击程序)

说了这么多废话。开始解题:

先看getbufn函数的反汇编代码:

此处将eax赋为ebp-0x208,也就是咱们要写的函数的首地址。每执行一次getbufn函数,testn的ebp都会改变,但是testn栈顶esp的位置却不变,所以我们现在要通过esp和ebp的关系来确定testn的ebp位置。然后修改这个位置的返回值就可以实现攻击了。

先来看testn这个小妖怪的汇编代码:(为什么是testn呢?-n模式下都有专用的函数)

从这里可以得到两个有用的信息:首先是ebp和esp的关系:ebp=esp+0x24+0x4(多了一个ebx,修正),这是ebp的真值。也就是esp+0x28为ebp的正确位置。然后第二个信息就是getbufn函数的返回地址0x08048ce2。

到这里攻击的汇编代码已经可以写出来了:

得出机器代码:

现在就差最后一个东西了,咱们写的这个汇编程序的入口地址。一开始的时候说了首地址为ebp-0x208.现在要找到一个最大的ebp,使得五次调用的时候都能跳到这个汇编程序的入口地址(我也不知道咋证明,大概跟nop有关)

这里我补充一下为什么要选取最大的ebp:首先咱们写的函数的首地址是固定的了,如何保证不同ebp的时候都能跳到这个入口地址呢?先来看个原理图:

入口地址
.......
nop
ebp(max)
........      
ebp(min)

如果咱们选取ebp(min),这个时候第一个nop填充的位置就是ebp(min)下一个栈位置,但是这个位置和最大的ebp位置差了一定的位置(就暂且设为4吧),由于nop的数量是固定的了,那么nop填充完之后,函数的入口地址就会跟最后一个nop差了四个位置,也就是没有命中!显然这样子是不可以的。那么我选取最大的ebp,第一个填充的nop就为它的下一个位置,填完所有的nop后,最后一个nop恰好会是函数的入口地址,因此不管你ebp如何变化,我最后一个nop一定能命中函数的入口地址。一句话概括就是:我的nop数量大于等于最大ebp和函数入口地址的栈长度。大概就是这么个意思。

那么通过查看五次调用getbufn函数的ebp就能确定最大的ebp值。

第一次:

第二次:

第三次:

第四次:

第五次:

有两次是一样的。不过没关系。取最大的ebp为:0x55683020,再去减去0x208得到:0x55682E18。因此最高的函数入口地址为:0x55682E18。

接下来如何构造我们的测试字符串呢?

共有520+4(覆盖旧ebp)+4(修改返回地址)=528字节。其实就是三个部分:nop,攻击代码,跳转地址。根据前面得到机器代码共15个字节+入口函数的地址4个字节=19个字节。那么需要填冲的nop为528-19=509个字节。

坑得一笔!怎么加都算不准509个!找了两个小时。。才真的够509个nop!(nop对应的十六进制为0x90)

运行一下:

嘛哟。看了n多次Better luck next time!!终于看到它了!激动啊啊啊!!

由于是第一篇博客,并不怎么会写,有些地方写得确实不好,现在回来改一下。希望能帮助到有需要的人。

如有错误欢迎留言指出。

CSAPP:bufbomb实验相关推荐

  1. csapp bufbomb实验

    csapp (<深入理解计算机系统>)一书中有一个关于缓冲区溢出的实验,其程序代码如下: /* Bomb program that is solved using a buffer ove ...

  2. CSAPP Lab2 实验记录 ---- Bomb Lab(Phase 1 - Phase 6详细解答 + Secret Phase彩蛋解析)

    文章目录 Lab 总结博客链接 实验前提引子 实验需要指令及准备 Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 Phase 6 Phase Secret(彩蛋Phas ...

  3. CSAPP Lab5实验记录 ---- Shell Lab(实验分析 + 完整代码)

    文章目录 Lab 总结博客链接 前引 Lab5 Shell Lab 1.获取相关Lab材料 2.Overview(总览) 3.Explore(实现前的摸索) 4.函数实现 + 实现代码分析 1.eva ...

  4. 《深入理解计算机系统》(CSAPP)实验三 —— Buf Lab

    这是CSAPP的第三个实验,主要让我们熟悉GDB的使用,理解程序栈帧的结构和缓冲区溢出的原理. 实验目的   本实验的目的在于加深对IA-32函数调用规则和栈结构的具体理解.实验的主要内容是对一个可执 ...

  5. CSAPP buflab 实验报告

    实验程序压缩包下载 提取码:1111 实验题目:BUFLAB 实验目的: 本实验将帮助您详细了解IA-32调用约定和堆栈组织.它涉及到对lab目录中的可执行文件bufbomb应用一系列缓冲区溢出攻击. ...

  6. csapp炸弹实验_bomb_lab详解

    个人博客:sekyoro.top 之前图床挂了(没错是gitee),现在更新一下 文章目录 开始的准备 objdump与gdb常用命令 objdump gdb readelf 正式开始 initial ...

  7. CSAPP Lab3 实验记录 ---- Attack Lab(Ctarget)

    文章目录 Lab 总结博客链接 前引 实验前准备 Part I: Code Injection Attacks Test 1 Test 2 Test 3 结尾 Lab 总结博客链接 CSAPP Lab ...

  8. 《深入理解计算机系统》(CSAPP)实验七 —— Malloc Lab

    文章目录 隐式空闲链表 分离的空闲链表 显示空闲链表 1. 实验目的 2. 背景知识 3. Implicit list mm_init extend_heap mm_malloc find_fit p ...

  9. 计算机系统实验拆炸弹,CSAPP 炸弹实验解析上

    CSAPP(Computer Systems A Programmer's Perspective),中译名为深入理解计算机系统,是一本优秀的计算机教材.该书配套了若干个课后实验,可供读者检验所学知识 ...

最新文章

  1. 2013河北省职称计算机应用能力考试操作题答案,2013河北省职称计算机应用能力考试操作题步骤详解(部分).doc...
  2. varchar和Nvarchar区别 ----转载
  3. ABAP 使用DYNP_VALUES_READ来获取屏幕字段值
  4. Socket编程实践(2) --Socket编程导引
  5. 用户控件(UserControl)
  6. SQL Server中的数据库表分区
  7. collectd 5.7.2 发布,系统监控和统计工具
  8. 电子计算机专业vs土木工程专业,最难学十大工科专业 不想累成狗就别去(高薪)...
  9. 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
  10. 性能优化篇 之 如何开展优化类的工作(2)
  11. 关键路径c语言,有向图的关键路径的C程序实现代码
  12. 【路径规划】基于matlab多种算法无人机路径规划【含Matlab源码 1263期】
  13. modelsim 10.7安装教程
  14. 软考《软件设计师教程》(第五版)
  15. JxBrowser开启调试模式,JxBrowser debug
  16. java小游戏实战局域网联机_结对编程3——黄金点小游戏实现局域网联机
  17. 第一章 语音信号处理概述
  18. android 按钮自动按下,按键点击精灵app官方版-按键点击精灵(全能自动点击连点器)下载v2.200.2安卓版-西西软件下载...
  19. Blender自动化建模入门
  20. 【虚幻4】UMG组件的简介与使用(Common 常用组件篇)

热门文章

  1. hashcat 2.哈希的装载
  2. 黑马程序员golang_成为Go程序员的7个阶段
  3. 学 Vim 时希望早点知道的建议
  4. 在widows下使用ioperm控制端口
  5. 三星9500android 8.0,三星note 8 高通835 N9500(国行、港行),8.0的安卓版本,可以自行安装xposed框架...
  6. 逻辑分析仪的使用--LA1010
  7. Spring Boot Controller
  8. 乔姆斯基文法分类【0型1型2型3型文法】
  9. 学习参考 | 从运动学到机械臂控制
  10. 2022年全球及中国设备漏电断路器行业头部企业市场占有率及排名调研报告