缓冲区溢出

        缓冲区溢出(Buffer Overflow)是计算机安全领域内既经典又古老的话题。顾名思义,缓冲区溢出的含义是为缓冲区提供了多于其存储容量的数据,就像我们往杯子里面倒入过量的水一样,多于的那部分水就可能会发生你意想不到的事情。通常情况下,缓冲区溢出的数据只会破坏程序数据,造成程序意外终止。但是如果有人精心构造溢出数据的内容,就有可能造成意想不到的后果,比如对方就有可能获得系统的控制权,从而操控整个程序。

        再举个比较形象点的例子。用户(或者是黑客)提供了多于水杯的水--缓冲区溢出攻击的数据,然后系统提供的是溢出的容器--缓冲区。这样,多于的水就会利用缓冲区对程序进行破坏甚至攻击。

        缓冲区在系统中的表现形式是多样的,高级语言定义的变量、数组、结构体等在运行时可以说都是保存在缓冲区内的,因此所谓缓冲区可以更形象地理解为一段可读写地内存区域。缓冲区攻击地最终目的就是希望系统能够执行这块可读写内存中已经被蓄意设定好地恶意代码。按照冯诺依曼存储程序原理,程序代码是作为二进制数据存储在内存中地,同样程序地数据也在内存中,因此直接从内存地二进制形式上是无法区分哪些是数据哪些是代码地,这也为缓冲区攻击提供了可能。



上图是进程地址空间分布地简单表示。其中,代码段存储了用户程序地所有可执行代码,在程序正常执行地情况下,程序计数器(PC指针)只会在代码段和操作系统地址空间内寻址。数据段内存储了用户程序地全局变量、文字池等。栈空间存储了用户程序的函数栈帧(包括参数、局部数据等),实现函数调用机制,它的数据增长方向是低地址方向。堆空间存储了程序运行时动态申请的内存数据等,数据增长方向是高地址方向。除了代码段和受操作系统保护的数据区域,其他的内存区域都可作为缓冲区,因此缓冲区溢出的位置可能在数据段以及堆、栈段。如果程序的代码有漏洞,恶意程序会教唆程序计数器(PC指针)从上述缓冲区内取值,执行恶意程序提供的代码。

原理讲倒这里,相信大家已经有了一定的认识,接下来我们通过一段代码和一个图片来更清晰的认识一下栈溢出的攻击方式。

我们知道,很多应用程序都会接受用户的外界输入,尤其是当函数内的一个数组缓冲区接受用户输入的时候,一旦程序代码未对输入的长度进行合法性检查的话,缓冲区溢出便有可能触发,比如下边的这个简单函数。

void fun(unsigned char *data){

       unsigned char buffer[BUF_LEN];

       strcpy ((char*) buffer, (char*) data) ;   //溢出点

}

这是一个简单的函数,它也是一个典型的栈溢出代码。因为在使用不安全的strcpy库函数时,系统会盲目的将data的全部数据拷贝到buffer指向的内存区域。buffer的长度是有限的,一旦data的数据长度超过BUF_LEN,便会产生缓冲区溢出



上图是缓冲区溢出的示意图。我们知道,由于栈的增长方向是向低地址增长的,因此局部数组buffer的指针在缓冲区的下方。当把data的数据拷贝到buffer内时,超过缓冲区区域的高地址部分的数据会“淹没”原本的其他栈帧数据,根据淹没数据的内容不同,可能会产生以下情况:

1. 淹没了其他的局部变量。如果被淹没的局部变量是条件变量,那么可能会改变函数原本的执行流程。这种方式可以用于破解简单的软件验证

2. 淹没了ebp的值。修改了函数执行结束后要恢复的栈指针,将会导致栈帧失去平衡

3. 淹没了返回地址。这是栈溢出原理的核心所在,通过淹没的方式修改函数的返回地址,使程序代码执行意外的流程

4. 淹没参数变量。修改函数的参数变量也可能改变当前函数的执行结果和流程

5. 淹没上级函数的栈帧。影响的是上级函数的执行。但前提是保证函数能正常返回,即函数地址不能被随意修改



上图是基本的一个栈溢出攻击。如果在data本身的数据内就保存了一系列的指令的二进制代码,一旦栈溢出修改了函数的返回地址,并将该地址指向这段二进制代码的位置,那么就完成了基本的溢出攻击行为。通过计算返回地址内存区域相对于buffer的偏移,并在对应位置构造新的地址指向buffer内部二进制代码的位置,便能执行用户自定义的代码。这段即是代码又是数据的二进制数据被称为shellcode,因为攻击者希望通过这段代码打开系统的shell,以执行任意的操作系统命令。

关于缓冲区溢出,还有很多细节可以去学习,这里只是简单的讲述了一下原理。大家可以自行去查阅资料学习。

































































  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值