划重点!关于缓冲区溢出攻击,这份防范策略⼀定要收好!⼀、缓冲区溢出攻击的基本概念
缓冲区溢出是⼀种⾮常普遍、⾮常危险的漏洞,在各种操作系统、应⽤软件中⼴泛存在。利⽤缓冲区溢出攻击,可以导致程序运⾏失败、系统宕机、重新启动等后果。更为严重的是,可以利⽤它执⾏⾮授权指令,甚⾄可以取得系统特权,进⽽进⾏各种⾮法操作。
缓冲区溢出攻击有多种英⽂名称:buffer overflow,buffer overrun,smash the stack,trash the stack,scribble the stack,mangle the stack, memory leak,overrun screw;它们指的都是同⼀种攻击⼿段。第⼀个缓冲区溢出攻击--Morris蠕⾍,发⽣在1988年,由罗伯特,莫⾥斯(R ob。rtMorris)制造,它曾造成全世界6000多台⽹络服务器瘫痪。
计算机程序⼀般都会使⽤到⼀些内存,这些内存或是程序内部使⽤,或是存放⽤户的输⼊数据,这样的内存⼀般称作缓冲区。溢出是指盛放的东西超出容器容量⽽溢出来了,在计算机程序中,就是数据使⽤到了被分配内存空间之外的内存空间。⽽缓冲区溢出,简单的说就是计算机对接收的输⼊数据没有进⾏有效的检测(理想的情况是程序检查数据长度并不允许输⼊超过缓冲区长度的字符),向缓冲区内填充数据时超过了缓冲区本⾝的容量,⽽导致数据溢出到被分配空间之外的内存空间,使得溢出的数据覆盖了其他内存空间的数据。
通过往程序的缓冲区写超出其长度的内容,⽐如定义⼀个字符串变量,只允许他存储最多15个字符串(IP地址的最⼤字符数),但⽤户输⼊的时候误操作输⼊了15个以上的字符,加上程序本⾝没有去校验⽤户输⼊的字符数量,⽽直接存储到这个变量的内存地址空间,就造成缓冲区的溢出,从⽽破坏程序的堆栈,造成程序崩溃或使程序转⽽执⾏其它指令,以达到攻击的⽬的。造成缓冲区溢出的原因是程序中没有仔细检查⽤户输⼊的参数。
⼆、缓冲区溢出漏洞攻击⽅式
缓冲区溢出漏洞可以使任何⼀个有⿊客技术的⼈取得机器的控制权甚⾄是最⾼权限。⼀般利⽤缓冲区溢出漏洞攻击root程序,⼤都通过执⾏类似“exec(sh)”的执⾏代码来获得root 的shell。⿊客要达到⽬的通常要完成两个任务,就是在程序的地址空间⾥安排适当的代码和通过适当的初始化寄存器和存储器,让程序跳转到安排好的地址空间执⾏。
1)在程序的地址空间⾥安排适当的代码
在程序的地址空间⾥安排适当的代码往往是相对简单的。如果要攻击的代码在所攻击程序中已经存在了,那么就简单地对代码传递⼀些参数,然后使程序跳转到⽬标中就可以完成了。攻击代码要求执⾏“exec(‘/bin/sh’)”,⽽在libc库中的代码执⾏“exec(arg)”,其中的“arg”是个指向字符串的指针参数,只要把传⼊的参数指针修改指向“/bin/sh”,然后再跳转到libc库中的响应指令序列就可以了。当然,很多时候这个可能性是很⼩的,那么就得⽤⼀种叫“植⼊法”的⽅式来完成了。
当向要攻击的程序⾥输⼊⼀个字符串时,程序就会把这个字符串放到缓冲区⾥,这个字符串包含的数据是可以在这个所攻击的⽬标的硬件平台上运⾏的指令序列。缓冲区可以设在:堆栈(⾃动变量)、堆(动态分配的)和静态数据区(初始化或者未初始化的数据)等的任何地⽅。也可以不必为达到这个⽬的⽽溢出任何缓冲区,只要到⾜够的空间来放置这些攻击代码就够了。
2)控制程序转移到攻击代码的形式
缓冲区溢出漏洞攻击都是在寻求改变程序的执⾏流程,使它跳转到攻击代码,最为基本的就是溢出⼀个没有检查或者其他漏洞的缓冲区,这样做就会扰乱程序的正常执⾏次序。通过溢出某缓冲区,可以改写相近程序的空间⽽直接跳转过系统对⾝份的验证。原则上来讲攻击时所针对的缓冲区溢出的程序空间可为任意空间。但因不同地⽅的定位相异,所以也就带出了多种转移⽅式。
(1)Function Pointers(函数指针)
在程序中,“void (* foo) ( )”声明了个返回值为“void” Function Pointers的变量“foo”。Function Pointers可以⽤来定位任意地址空间,攻击时只需要在任意空间⾥的Function Pointers邻近处到⼀个能够溢出的缓冲区,然后⽤溢出来改变Function Pointers。当程序通过Function Pointers调⽤函数,程序的流程就会实现。
(2)Activation Records(激活记录)
当⼀个函数调⽤发⽣时,堆栈中会留驻⼀个Activation Records,它包含了函数结束时返回的地址。执⾏溢出这些⾃动变量,使这个返回的地址指向攻击代码,再通过改变程序的返回地址。当函数调⽤结束时,程序就会跳转到事先所设定的地址,⽽不是原来的地址。这样的溢出⽅式也是较常见的。
(3)植⼊综合代码和流程控制
常见的溢出缓冲区攻击类是在⼀个字符串⾥综合了代码植⼊和Activation Records。攻击时定位在⼀个可供溢出的⾃动变量,然后向程序传递⼀个很⼤的字符串,在引发缓冲区溢出改变Activation Records的同时植⼊代码(权因C在习惯上只为⽤户和参数开辟很⼩的缓冲区)。植⼊代码和缓冲区溢出不⼀定要⼀次性完成,可以在⼀个缓冲区内放置代码(这个时候并不能溢出缓冲区),然后通过溢出另⼀个缓冲区来转移程序的指针。这样的⽅法⼀般是⽤于可供溢出的缓冲区不能放⼊全部代码时的。如果想使⽤已经驻留的代码不需要再外部植⼊的时候,通常必须先把代码做为参数。在libc(熟悉C的朋友应该知道,现在⼏乎所有的C程序连接都是利⽤它来连接的)中的⼀部分代码段会执⾏“exec(something)”,当中的something就是参数,使⽤缓冲区溢出改变程序的参数,然后利⽤另⼀个缓冲区溢出使程序指针指向libc中的特定的代码段。
程序编写的错误造成⽹络的不安全性也应当受到重视,因为它的不安全性已被缓冲区溢出表现得淋漓尽致了。
三、缓冲区溢出攻击的防范策略
缓冲区溢出攻击的防范是和整个系统的安全性分不开的。如果整个⽹络系统的安全设计很差,则遭受缓冲区溢出攻击的机会也⼤⼤增加。针对缓冲区溢出,可以采取多种防范策略。
(1)系统管理上的防范策略
⼀要关闭不需要的特权程序。
⼆要及时给程序漏洞打补丁。
(2)软件开发过程中的防范策略
发⽣缓冲区溢出的主要及各要素是:数组没有边界检查⽽导致的缓冲区溢出;函数返回地址或函数指针被改变,使程序流程的改变成为可能;植⼊代码被成功的执⾏等等。所以针对这些要素,从技术上可以采取⼀定的措施。
1)强制写正确的代码的⽅法。
只要在所有拷贝数据的地⽅进⾏数据长度和有效性的检查,确保⽬标缓冲旦中数据不越界并有效,则就可以避免缓冲区溢出,更不可能使程序跳转到恶意代码上。
2)通过操作系统使得缓冲区不可执⾏,从⽽阻⽌攻击者殖⼊攻击代码。
通过使被攻击程序的数据段地址空间不可执⾏,从商使得攻击者不可能执⾏被植⼊被攻击程序输⼊缓冲区的代码,这种技术被称为缓冲区不可执⾏技术。
3)改进C语⾔函数库。
C语⾔中存在缓冲区溢出攻击隐患的系统匾数有很多。例如gets(),sprintf(),strcpy(),strcat(),fscanf(),scanf(),vsprintf()等。可以开发出更安全的封装了若⼲⼰知易受堆栈溢出攻击的岸函数。
4)使堆栈向⾼地址⽅向增长。
使⽤的机器堆栈压⼊数据时向⾼地址⽅向前进,那么⽆论缓冲区如何溢出,都不可能覆盖低地址处的函数返回地址指针,也就避免了缓冲区溢出攻击。但是这种⽅法仍然⽆法防范利⽤堆和静态数据段的缓冲区进⾏溢出的攻击。
5)在程序指针失效前进⾏完整性检查。
原理是在每次在程序指针被引⽤之前先检测该指针是否⼰被恶意改动过,如果发现被改动,程序就拒绝执⾏。
6)利⽤编译器将静态数据段中的函数地址指针存放地址和其他数据的存放地址分离。
如果你想更好的提升你的编程能⼒,学好C语⾔C++编程!弯道超车,快⼈⼀步!
shell代码【】,分享(源码、项⽬实战视频、项⽬笔记,基础⼊门教程)
欢迎转⾏和学习编程的伙伴,利⽤更多的资料学习成长⽐⾃⼰琢磨更快哦!
编程学习书籍:
编程学习视频:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论