缓冲区溢出攻击的工作原理及防范策略

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

服 务

病毒黑客

图1 计算机程序内存存放示意图

为了搞清楚“黑客”基于缓冲区

溢出漏洞攻击的工作原理,我们先来

分析一下计算机程序在内存中的存储

和运行方式,计算机程序在内存中

通常分为[1]程序段、数据段和堆栈

部分,其具体存放策略如图

示,程序段存放的是可执行的二进制

机器代码或者只读数据,这个段的内

容只允许读或者执行操作,不允许写

服 务病毒黑客

操作如下:首先把参数‘c’,’b’,’a’压入堆栈;然后保存指令寄存器(I P)中的内容,作为返回地址(R E T);第三个放入堆栈的是基址寄存器(F P);接着把当前的栈指针(S P)拷贝到F P,作为新的基地址;最后为函数变量留出一定空间,把

S P减去适当的数值,使其指向局部变量的位置;执行完上述函数调用操作后,程序转到函数中继续执行,此时堆栈中的数据如图2所示。

图2 堆栈工作原理示意图

函数执行完毕后,执行出栈操作,其中最主要的是将r e t送到I P中[3],正常执行此操作会使程序返回到函数调用指令的下一条指令,继续程序的正常执行,不会产生缓冲区的溢出,那么什么情况下会产生缓冲区的溢出呢?让我们来分析一下面的程序。

Buffer_overflow.c

void function(char *str)

{ char buffer[16]; 

strcpy(buffer,str);

}

void main()

{ char large_str [512];

int i;

for( i = 0; i < 512; i++) 

large_str [i] = \'A\'; 

function(large_str); 

}

在程序Buffer_overflow.c执行过程中,当调用函数function时,函数将字符串*str不经过边界检查,直接拷贝到内存区域buffer[16]。此时堆栈结果如图3所示:首先将参数*str

压入堆栈,占用512字节的内存,接

着将返回地址将指令寄存器IP中的返

回地址ret入栈,然后将基址指针FP

入栈,最后分配16字节的函数局部变

量存储空间,随后程序转入function

执行,当执行完strcpy(buffer,str)指

令后,溢出产生了,程序执行的结果

是从buffer开始的512个字节都将被

*str的内容\'A\'覆盖,包括基址指

针SFP和程序返回地址ret,甚至部

分*str的内容。\'A\'的十六进值为

0x41,所以函数的返回地址ret变成

了0x41414141, 这超出了程序的地址

空间,引起段错误,而且导致函数执

行完毕后不能返回到调用它的主程序。

由此可见,缓冲区溢出允许我们改变

一个函数的返回地址。通过这种方式,

可以改变程序的执行顺序。通过精心

设计,黑客可以利用覆盖缓冲区数据

的方式将病毒、木马程序或者入侵程

序代码殖入被攻击的计算机,并更改

返回地址值以指向它们已殖入的恶意

代码,对系统发起攻击,获取系统的

控制权。溢出是病毒编写者和特洛伊

木马编写者偏爱使用的一种攻击方法。

攻击者或者病毒善于在系统当中发现

容易产生缓冲区溢出之处,运行特别

程序,获得优先级,指示计算机破坏

文件,改变数据,泄露敏感信息,产

生后门访问点,感染或者攻击其他计

算机。

图3 堆栈溢出原理示意图

3 基于缓冲区溢出攻击的防

范策略

通过缓冲区溢出攻击原理分析可

以看出,底层系统自动保护措施的缺

陷和程序员程序设计所犯的错误是攻

击赖以发生的根源,所以对于缓冲区

溢出攻击的防范应该从弥补底层系统

缺陷和完善程序设计两方面入手,要

让程序员不犯错误通常是很难的,因

此缓冲区溢出攻击的防范措施应该主

要依赖于对底层系统缺陷的弥补,譬

如对于操作系统的缺陷,可以通过及

时地下载安装操作系统补丁程序予以

解决。除此之外,还常采用以下几类

防范策略[4]:

(1)基于探测方法(c a n a r y)的

防御。

基于探测方法(c a n a r y)的

防御主要包括I m m u n i x使用的

StackGuard方法、OpenBSD 使用

的ProPolice方法和 Microsoft 的

/GS 选项方法。

StackGuard方法是通过修改 C

编译器(g c c),以便将一个“探测

值”插入到返回地址r e t的前面,在

任何函数返回之前,它执行检查以确

保探测值没有改变。如果攻击者改写

返回地址,探测仪的值就会改变,系

统内就会发出警告并相应地中止程序

的执行。这是一种行之有效的方法,

不过这种方法无法防止缓冲区溢出改

写其他值(攻击者仍然可以利用这些

值来攻击系统)。人们也曾研究扩展

这种方法来保护其他值(比如堆上的

值)。

ProPolice

方法又称为ssp,是

StackGuard 的方法的一种变化形式。

像 StackGuard 一样,ssp 使用一

个修改过的编译器在函数调用中插入

一个探测仪以检测堆栈溢出。然而,

84算机安全 2008.3

相关文档
最新文档