缓冲区溢出

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4
缓冲区溢出原理
内存低端 内 存 的 生 长 方 向
内存高端
局部变量字符数组buf EBP ret
函数参数
向局部变量数组buf中压入的字符过多, 则字符被写入EBP,ret所在的空间。
堆栈顶部

栈源自文库

EBP是基址寄存器,它指

向当前堆栈储存区的底部



5
由于内存的生长方向与堆栈的生长方向 是相反的,堆栈是从内存的低端向内存 的高端生长
当数组被溢出的时候,函数返回地址、过程帧 指针、函数指针等重要数据就有可能被修改。 被植入的攻击代码就可能执行。因此,对数组 进行边界检查,使超长代码不可能植入,这样 就完全没有了缓冲区溢出攻击产生的条件。
对数组边界检查,直接的办法就是对所有的数 组读写操作都进行检查,但这种完全检查要付 出很大的性能代价。
编译并且执行,我 们输入ipxodi,就会 输出Hello,ipxodi!。
7
运行时的堆栈分配
内存底部
内存顶部
name EBP ret
<----- [
][ ][ ]
^;name
堆栈顶部
堆栈底部
8
执行完gets(name)之后
内存底部
内存顶部
name EBP ret
<-----[ipxodi\0 ][ ][ ]
大部分的入侵是利用一些已被公布的漏 洞达成的,如能及时补上这些漏洞,将 增强系统抵抗攻击的能力,有效地防止 大部分的攻击 。
27
关闭不需要的特权程序
由于缓冲区溢出只有在获得更高的特权时才有 意义,所以带有特权的Unix下的suid 程序和 Windows 下由系统管理员启动的服务进程都经 常是缓冲区溢出攻击的目标。
2
原因
造成缓冲区溢出的原因是程序中没有仔 细检查用户输入的参数。缓冲区溢出就 是将一个超过缓冲区长度的字符串置入 缓冲区的结果.
3
后果
向一个有限空间的缓冲区中置入过长的字 符串可能会带来两种后果
一是过长的字符串覆盖了相邻的存储单元,引 起程序运行失败,严重的可导致系统崩溃;
另一种后果是利用这种漏洞可以执行任意指令 ,甚至可以取得系统特权,由此而引发了许多 种攻击方法。
^;name
堆栈顶部
堆栈底部
9
堆栈溢出
再执行一次,输入 ipxodiAAAAAAAAAAAAAAA,执行完 gets(name)之后
内存底部
内存顶部
name EBP ret
<-----[ipxodiAA][AAAA][AAAA]
^;name 堆栈顶部
堆栈底部
10
由于我们输入的name字符串太长,name数组 容纳不下,只好向内存顶部继续写‘A’
用到的工具X-Scan 3.3、专用于Microsoft Windows Messenger服务远程堆溢出漏 洞的扫描工具RetinaMSGSVC.exe、漏洞 利用工具msgdos.exe。
14
首先,对目标主机进行漏洞扫描,利用XScan3.3对202.119.201.1-202.119.201.254网 段进行漏洞扫描,发现主机202.119.201.71存 在安全漏洞,如图6.2所示。
很多存在漏洞的程序是由于调用了一些不安全 的库函数,这些库函数往往没有对数组边界进 行检查。现在已经开发了一些工具和技术来帮 助程序员编写安全正确的代码,例如利用 grep 搜索源代码中容易产生漏洞的库的调用。
22
非执行的缓冲区技术
所谓的非执行的缓冲区技术,也称为堆栈不可 执行,就是指通过使被攻击程序的数据段地址 空间不可执行,从而使得攻击者不可能执行被 植入被攻击程序输入缓冲区的代码。
由于堆栈的生长方向与内存的生长方向相反, 这些‘A’覆盖了堆栈的老的元素
EBP,ret都已经被‘A’覆盖了 在main返回的时候,就会把‘ AAAA’ 的ASCII
码:0x41414141作为返回地址,CPU会试图执 行0x41414141处的指令,结果出现错误,这 就是一次堆栈溢出
11
攻击成功发生必须同时满足三 个条件
非执行的缓冲区技术可以有效地对付把代码植 入自动变量的缓冲区溢出攻击,而对于其他形 式的攻击则没有效果。通过引用一个驻留的程 序的指针,就可以跳过这种保护措施。攻击者 也可以采用把代码植入堆或者静态数据段中来 跳过保护。
23
数组边界检查
缓冲区溢出的一个重要原因就是没有对数组进 行边界检查,如果数组不能被溢出,也就不可 能发生数组溢出攻击。
17
图6.4 RetinaMSGSVC.exe 扫描结果
18
然后,利用msgdos.exe对主机202.119.201.71 进行攻击,msgdos.exe是一个命令行工具,如 图6.5所示。
图6.5 利用msgdos.exe对主机进行攻击
19
如果溢出成功,则目标主机将会在一分钟后重启,如 图6.6所示。
问题存在于Messenger服务程序的search-byname函数中,攻击者提交特定序列的字符串 给这个函数可造成堆溢出,精心构建提交数据 可能以系统权限在目标机器上执行任意指令。
13
消息通过NetBIOS或者RPC提交给消息服 务,因此可以通过封闭NETBIOS端口 (137-139)和使用防火墙过滤UDP广播包 来阻挡此类消息。
图6.2 发现主机漏洞
15
其中的一个漏洞为Microsoft Windows Messenger服务远程堆溢出漏洞,图6.3为漏洞 信息 。
图6.3 漏洞描述 16
为确定目标主机202.119.201.71确实存在该漏 洞,利用Microsoft Windows Messenger服务远 程堆溢出漏洞的扫描工具RetinaMSGSVC.exe 对其进行扫描(如图6.4所示),扫描结果出 现VULENRABLE to MS03-43,说明该主机确实 可能存在此漏洞。
缓冲区溢出攻击
1
缓冲区溢出
1988年11月, 23岁的程序员Robert Tappan Morris编写的“Morris 蠕虫”是用于攻击VAX 和Sun机器的程序。这个程序大约使得整个 Internet的10%崩溃。Morris 蠕虫利用了一个 被称为缓冲区溢出的程序缺陷。
缓冲区溢出指的是一种系统攻击的手段,通过 向程序的缓冲区写超出其长度的内容,造成缓 冲区的溢出,从而破坏程序的堆栈,使程序转 而执行其它指令,以达到攻击的目的。
将攻击代码注入内存 将函数返回地址指针指向已注入攻击代
码的内存地址 执行攻击代码
12
缓冲区溢出实例
Windows Messenger服务用于Microsoft Windows操作系统服务器与客户端之间互相发 送一些短消息。Microsoft Windows Messenger 服务存在堆溢出问题,远程攻击者可以利用这 个漏洞以系统权限在目标机器上执行任意指令。
图6.6 目标主机被溢出
20
6.3.3 缓冲区溢出的防范
编写正确的代码 非执行的缓冲区技术 数组边界检查 程序指针完整性检查 及时安装安全补丁 关闭不需要的特权程序
21
编写正确的代码
由于缓冲区溢出漏洞存在的原因是在程序开发 时使用了与字符串操作相关的函数,没有对函 数参数进行严格控制,导致数据越界造成的。 如果能确保缓冲区中数据不越界并有效,就可 以避免缓冲区溢出。
24
程序指针完整性检查
程序指针完整性检查是指在程序指针被应用之 前检测到指针的改变,因此即使一个攻击者成 功地改变程序指针,由于系统提前检测到了指 针的改变,因此这个指针将不会被使用。
程序指针完整性检查通过阻止缓冲区溢出的一 个条件——由于函数返回地址或函数指针的改 变而导致的程序执行流程的改变,来阻止缓冲 区溢出的发生。
那么向堆栈中压入的数据超过了堆栈预 先分配的容量时,则就会覆盖内存高端 的有用数据,此时就会出现堆栈溢出, 从而使得程序失败,如果发生堆栈溢出 的是大型程序,则有可能导致系统崩溃。
6
看一段小程序
#include <stdio.h> int main ( ) { char name[8]; printf("Please type your name: "); gets(name); printf("Hello, s!", name); return 0; }
25
它的原理是在每次在程序指针被引用之 前先检测该指针是否已被恶意改动过, 如果发现被改动,程序就拒绝执行。
因此,即使一个攻击者成功地改变程序 的指针,由于系统事先检测到了指针的 改变,因此这个指针不会被使用。
常用的程序指针完整性检查有堆栈保护 和指针保护。
26
及时安装安全补丁
管理员必须不断关注最新的技术和补丁, 不断的对系统进行修补,这是漏洞出现 后最迅速有效的补救措施。
这时候,关闭一些不必要的特权程序就可以降 低被攻击的风险。如Solaris下的fdformat是个 有缓冲区溢出漏洞的suid 程序,因为这个格式 化软盘的命令用的较少,最直接的措施是去掉 这个程序或者去掉suid位。
当有缓冲区溢出漏洞的程序还没有补丁时,就 可以用这种方法。
28
相关文档
最新文档