百科知识库-中国实用知识供应者
网站地图设为首页加入收藏
百科知识库
您当前的位置:百科知识库科学技术电脑技术网管天地介绍Propolice怎样保护stack-smashing的攻击
知识导航
介绍Propolice怎样保护stack-smashing的攻击

介绍Propolice怎样保护stack-smashing的攻击 整理:XUNDI
 
  低级......
 |-----------------------------------|
 | 如果你觉得这中文乱七八糟,JMP 0xAA|
 |-----------------------------------|
 | ....................|
 |-----------------------------------|
  0xAA ------> |请看文章最后提供原文,|
 |如果你觉得还是看不懂原文,JMP 0xBB |
 |-----------------------------------|
 |............ |
 |-----------------------------------|
  0xBB-------> | 请去请教backend,warning3,scz等他们|
 |如果你请教以后还是不懂,JMP 0xCC |
 |-----------------------------------|
 |.............. |
 |-----------------------------------|
  0xCC-------> |JMP 0x黄河 |
 |-----------------------------------|
  高级......
 

stack-smashing是一种引起设备停止并且导致允许攻击者侵入系统的攻击方法,
一般它被使用在叫缓冲溢出的应用程序漏洞上。stack-smashing攻击是在UNIX
安全新闻报道上最常见最普通的攻击方式。在1999年,IIS4.0的那个由EEYE发现
的缓冲溢出,使将近1500000系统遭受此漏洞的侵害。

多数应用程序使用C写的时候使用缓冲区(buffer),这个缓冲区是一个保存了一些
同样数据类型的数据,通常是字符数组,在堆栈里临时保存这些字符串操作的临时
值。stack-smashing攻击通常是提供一个超过实际BUFFER大小的字节数到缓冲区,
这就导致了破坏了BUFFER中的内容,这些内容可能就是调用函数的返回地址和函数
指针。


这文章提供了系统的解决缓冲溢出攻击的方法,这文章提供的一种叫ProPolice
保护方法能自动在应用程序编译的时候插入保护代码.它的主要特征是在对数字
的操作下具有比较少的效率支出,保护多种stack-smashing攻击,支持多种处理器。

下面讲讲攻击说明和它们的类别

缓冲溢出漏洞通常在应用程序需要读取外部信息如字符串时,接收缓冲区
相对与实际的输入字符串小而且应用程序又不正确检查这些操作时产生。
缓冲区在实时运行时分配空间到堆栈,这时候堆栈中保存了一些可执行函数
的信息:如本地变量,参数变量,和返回地址。而超长的字符串改动了这些
信息,如攻击者把一系列机器语言命令作为字符串插入到堆栈,并使这些字符
串覆盖在堆栈中的返回地址为这些命令的地址(我们通常所说的SHELLCODE),
这样到函数返回的时候就执行了这些代码。通常这些方法的最终目标是获得有
一定权利的SHELL。

图1描述了在一函数调用的时候典型的堆栈结构,在图的在最底下是堆栈指针在
堆栈的顶,C语言程序在堆栈中从堆栈顶(就是内存低端)使用下面的顺序来排列:
本地变量,前栈帧指针 (previous frame pointer--前栈帧指针),这对被调函
数而言不可见,也就是被压栈保存的%ebp,返回地址,和被调函数的入口参数。
其中下面所示的帧栈指针(frame pointer)定位了本帧以及前栈帧的帧指针存储在
调用者的栈帧中。


  高址......
 |-----------------------------------|
 | 传递给函数的参数| 向上是字符
 |-----------------------------------| 串增长方向
 | 函数的返回地址 (RET)|
 |-----------------------------------|
  帧栈指针-->| 保存的前栈帧指针 |
  (frame pointer)|(previous frame pointer) |
 |-----------------------------------|
 | 局部变量| 向下是堆栈
 |-----------------------------------| 增加方向
 | buffer |
 |-----------------------------------|
  堆栈指针-->|-----------------------------------|
  ......
  低址

 

  

 图 1 -- 堆栈结构



图2的函数foo是一个有漏洞的函数,它产生的堆栈结构就如图1所示。这函数读
取了环境变量'HOME'的内容到大小为128字节的'buffer'中,但是由于strcpy
函数没有正确检查输入的大小,它就能拷贝超过128字节的数据到"buffer"中,
想象下如果"HOME"变量有这样的字符串:128字节的41,1, 1, 1, 1, 2, 2, 2,
2, 3, 3, 3, 3。这就分配了128个A字符,和0x01010101, 0x02020202, 和
0x03030303分别到"buffer","lvar"和前栈帧指针(previous frame pointer)
及返回地址(ret)中.(我们假定使用了默认的32位变量和C语言符号.)当foo函数
完成它的操作并返回调用foo函数的函数返回地址,也就是覆盖了刚才堆栈中的
返回地址,而变为了0x03030303地址,这样如果有恶意代码存放在上面这个
0x03030303地址中的话,这恶意代码将以此函数原来的运行级别运行。


  void foo()
  {
 long *lvar;
 char buffer[128];
 ........
 strcpy (buffer,getenv("HOME"));
 ........
  }
  图 2:一个简单的有缓冲溢出的示例


我们下面介绍下一种典型的攻击方式,攻击者怎样获得应用程序的控制。在第一
类中攻击的目标在堆栈中,下面列出了存储在堆栈中的数据并描述攻击模式的使用:

--返回地址
  通过改变返回地址的值到恶意代码地址是最流行的攻击方式。
 
--本地变量

--入口参数变量

这个函数的变量是另一个需要控制的目标,把入口参数或者本地变量指定为攻击
代码也是攻击的一种方式,在这种情况下,漏洞一般是通过检查源程序发现的。

第三种函数指针重定向(Function Pointers)
 “void (* foo)()”声明了一个返回值为void函数指针的变量foo。函数指针
可以用来定位任何地址空间,所以攻击者只需在任何空间内的函数指针附近找到
一个能够溢出的缓冲区,然后溢出这个缓冲区来改变函数指针。在某一时刻,当
程序通过函数指针调用函数时,程序的流程就按攻击者的意图实现了!它的一个攻
击范例就是在Linux系统下的superprobe程序。
 

改变指针变量而不是指向函数的指针也是有可能获得应用程序的控制,在这种
情况下,如图2函数foo,指针变量'lvar'可以改变它指向返回地址的地址。如果
在'strcpy'声明(statement)后有一个声明(statement)通过'lvar'修改值的指向,
就存在了改变其值到返回地址的可能。

--前栈帧指针(previous frame pointer)

对于对前栈帧指针(previous frame pointer)的攻击也可以获得对应用程序的
控制,前栈帧指针(previous frame pointer)和返回地址的联系是基于下面的
条件下:
  --返回地址的位置由栈帧指针(the frame pointer)决定
  --在函数返回时候栈帧指针(the frame pointer)指派了前栈帧指针
  (previous frame pointer)的值。
这样一个攻击者可以建立一个含有指向攻击代码的返回地址的伪造帧。他也可以
改变前栈帧指针(previous frame pointer)的值而指向伪造帧地址。当函数返回
到调用函数时,栈帧指针(frame pointer)会根据上面所述的第二个条件而指向
攻击者伪造的帧。也就是说攻击者改变了返回地址。



一些目前存在的相关技术


目前对于缓冲问题的保护已经有不少方案(project)发表,一种方法是下面参考中的
:从源程序中检查排除有漏洞代码并从发现的问题中帮助应用程序变的更安全。
如在参考中所示地址中有安全审核工具来自动检查源码,它主要是检查和排除
一些危险的函数:如strcpy,gets等等,但工具的受限之处是它不检查指针变量的边界。

另一个方案是提供对程序代码潜在的漏洞进行保护的方式,我们可以根据他们怎样
保护动机分为四个类别:

  1,避免数组的溢出问题
  参考中的是对数组边界进行检查方法和参考中的是对内存访问进行
  检查的方法,这两种方法防止了对分配给数组边界之外访问。因此,这些
  方法是很安全的一种方法,但是,这种保护的开销比不保护的代码昂贵的很,
  经过这样优化的代码相对于普通的代码速度慢。

  2,禁止攻击代码的执行
  ``Solar Designer'' 开发的LINUX补丁就是使堆栈区域的不可执行性,因此
  存储在堆栈中的攻击代码就不能执行了。Solar Designer提供的kernel
  security patc

    

 
百科知识库 版权所有

Copyright © 2007-2009 www.zsku.net, All Rights Reserved

本站所收集信息资料为网络转载 版权属各作者 并已著明作者 旨在资源共享、交流、学习之用,请勿用于商业用途,本站并不保证所有信息、文本、图形、链接及其它内容的绝对准确性和完整性,故仅供访问者参照使用。