详解缓冲区溢出攻击以及防范⽅法字符串函数应用详解
缓冲区溢出是⼀种在各种操作系统、应⽤软件中⼴泛存在普遍且危险的漏洞,利⽤缓冲区溢出攻击可以导致程序运⾏失败、系统崩溃等后果。更为严重的是,可以利⽤它执⾏⾮授权指令,甚⾄可以取得系统特权,进⽽进⾏各种⾮法操作。第⼀个缓冲区溢出攻击--Morris蠕⾍,发⽣在⼗多年前,它曾造成了全世界6000多台⽹络服务器瘫痪。⼀、缓冲区溢出的原理:当正常的使⽤者操作程序的时候,所进⾏的操作⼀般不会超出程序的运⾏范围;⽽⿊客却利⽤缓冲长度界限向程序中输⼊超出其常规长度的内容,造成缓冲区的溢出从⽽破坏程序的堆栈,使程序运⾏出现特殊的问题转⽽执⾏其它指令,以达到攻击的⽬的。造成缓冲区溢出的原因是程序中没有仔细检查⽤户输⼊的参数,属于程序开发过程考虑不周到的结果。当然,随便往缓冲区中填东西造成它溢出⼀般只会出现“分段错误”(Segmentation fault),⽽不能达到攻击的⽬的。最常见的⼿段是通过制造缓冲区溢出使程序运⾏⼀个⽤户shell,再通过shell执⾏其它命令。如果该程序属于root且有suid权限的话,攻击者就获得了⼀个有root权限的shell,可以对系统进⾏任意操作了。缓冲区溢出攻击之所以成为⼀种常见安全攻击⼿段其原因在于缓冲区溢出漏洞普遍并且易于实现。⽽且缓冲区溢出成为远程攻击的主要⼿段其原因在于缓冲区溢出漏洞给予了攻击者他所想要的⼀切:植⼊并且执⾏攻击代码。被植⼊的攻击代码以⼀定的权限运⾏有缓冲区溢出漏洞的程序,从⽽得到被攻击主机的控制权。在1998年Lincoln实验室⽤来评估⼊侵检测的的5种远程攻击中,有2种是缓冲区溢出。⽽在1998年CERT的13份建议中,有9份是是与缓冲区溢出有关的,在1999年,⾄少有半数的建议是和缓冲区溢出有关的。
在Bugtraq的调查中,有2/3的被调查者认为缓冲区溢出漏洞是⼀个很严重的安全问题。缓冲区溢出漏洞和攻击有很多种形式,会在第⼆节对他们进⾏描述和分类。相应地防卫⼿段也随者攻击⽅法的不同⽽不同,将在第四节描述,它的内容包括针对每种攻击类型的有效的防卫⼿段。⼆、缓冲区溢出的漏洞和攻击:缓冲区溢出攻击的⽬的在于扰乱具有某些特权运⾏的程序的功能,这样可以使得攻击者取得程序的控制权,如果该程序具有⾜够的权限,那么整个主机就被控制了。它的具体实现过程是这样的:⾸先攻击者对ROOT程序进⾏试探性攻击,然后执⾏类似“exec(sh)”的执⾏代码来获得具有root权限的shell。为了达到这个⽬的,攻击者必须达到如下的两个⽬标: 1、在程序的地址空间⾥安排适当的代码; 2、通过适当的初始化寄存器和内存,让程序跳转到⼊侵者安排的地址空间执⾏。根据这两个⽬标来对缓冲区溢出攻击进⾏分类,缓冲区溢出攻击分为代码安排和控制程序执⾏流程两种⽅法: 1、在程序的地址空间⾥安排适当的代码的⽅法:(1)植⼊法:攻击者向被攻击的程序输⼊⼀个字符串,程序会把这个字符串放到缓冲区⾥。这个字符串包含的资料是可以在这个被攻击的硬件平台上运⾏的指令序列。在这⾥,攻击者⽤被攻击程序的缓冲区来存放攻击代码。缓冲区可以设在任何地⽅:堆栈(stack,⾃动变量)、堆(heap,动态分配的内存区)和静态资料区。(2)利⽤已经存在的代码:有时攻击者想要的代码已经在被攻击的程序中了,攻击者所要做的只是对代码传递⼀些参数。例如攻击代码要求执⾏exec (“/bin/sh”),⽽在libc库中的代码执⾏exec (arg),其中arg使⼀个指向⼀个字符串的指针参数,那么攻击者只要把传⼊的参数指针改向指向/bin/sh。 2、控制程序转移到攻击代码的⽅法:所有的这些⽅法都是在寻求改变程序的执⾏流程,使之跳转到攻击代码。最基本的就是溢出⼀个没有边界检查或者其它弱点
的缓冲区,这样就扰乱了程序的正常的执⾏顺序。通过溢出⼀个缓冲区,攻击者可以⽤暴⼒的⽅法改写相邻的程序空间⽽直接跳过了系统的检查。分类的基准是攻击者所寻求的缓冲区溢出的程序空间类型。原则上是可以任意的空间。实际上,许多的缓冲区溢出是⽤暴⼒的⽅法来寻求改变程序指针的。这类程序的不同之处就是程序空间的突破和内存空间的定位不同。主要有以下三种: 1、活动纪录(Activation Records):每当⼀个函数调⽤发⽣时,调⽤者会在堆栈中留下⼀个活动纪录,它包含了函数结束时返回的地址。攻击者通过溢出堆栈中的⾃动变量,使返回地址指向攻击代码。通过改变程序的返回地址,当函数调⽤结束时,程序就跳转到攻击者设定的地址,⽽不是原先的地址。这类的缓冲区溢出被称为堆栈溢出攻击(Stack Smashing Attack),是⽬前最常⽤的缓冲区溢出攻击⽅式。 3、函数指针(Function Pointers):函数指针可以⽤来定位任何地址空间。例如:“void (* foo)()”声明了⼀个返回值为void的函数指针变量foo。所以攻击者只需在任何空间内的函数指针附近到⼀个能够溢出的缓冲区,然后溢出这个缓冲区来改变函数指针。在某⼀时刻,当程序通过函数指针调⽤函数时,程序的流程就按攻击者的意图实现了。它的⼀个攻击范例就是在Linux系统下的superprobe程序。 4、长跳转缓冲区(Longjmp buffers):在C语⾔中包含了⼀个简单的检验/恢复系统,称为setjmp/longjmp。意思是在检验点设定“setjmp(buffer)”,⽤“longjmp(buffer)”来恢复检验点。然⽽,如果攻击者能够进⼊缓冲区的空间,那么“longjmp(buffer)”实际上是跳转到攻击者的代码。象函数指针⼀样,longjmp缓冲区能够指向任何地⽅,所以攻击者所要做的就是到⼀个可供溢出的缓冲区。⼀个典型的例⼦就是Perl 5.003的缓冲区溢出漏洞;攻击者⾸先进⼊⽤来恢复缓冲区溢出的的longjmp缓冲区,然后诱导进⼊恢复模式,这样
就使Perl的解释器跳转到攻击代码上了。 2、代码植⼊和流程控制技术的综合分析:最简单和常见的缓冲区溢出攻击类型就是在⼀个字符串⾥综合了代码植⼊和活动纪录技术。攻击者定位⼀个可供溢出的⾃动变量,然后向程序传递⼀个很⼤的字符串,在引发缓冲区溢出,改变活动纪录的同时植⼊了代码。这个是由Levy指出的攻击的模板。因为C在习惯上只为⽤户和参数开辟很⼩的缓冲区,因此这种漏洞攻击的实例⼗分常见。代码植⼊和缓冲区溢出不⼀定要在在⼀次动作内完成。攻击者可以在⼀个缓冲区内放置代码,这是不能溢出的缓冲区。然后,攻击者通过溢出另外⼀个缓冲区来转移程序的指针。这种⽅法⼀般⽤来解决可供溢出的缓冲区不够⼤(不能放下全部的代码)的情况。如果攻击者试图使⽤已经常驻的代码⽽不是从外部植⼊代码,他们通常必须把代码作为参数调⽤。举例来说,在libc(⼏乎所有的C程序都要它来连接)中的部分代码段会执⾏“exec(something)”,其中somthing就是参数。攻击者然后使⽤缓冲区溢出改变程序的参数,然后利⽤另⼀个缓冲区溢出使程序指针指向libc中的特定的代码段。三、缓冲区溢出攻击的实验分析:2000年1⽉,Cerberus 安全⼩组发布了微软的IIS 4/5存在的⼀个缓冲区溢出漏洞。攻击该漏洞可以使Web服务器崩溃,甚⾄获取超级权限执⾏任意的代码。⽬前微软的IIS 4/5 是⼀种主流的Web服务器程序;因⽽该缓冲区溢出漏洞对于⽹站的安全构成了极⼤的威胁;它的描述如下:浏览器向IIS提出⼀个HTTP请求,在域名(或IP地址)后,加上⼀个⽂件名,该⽂件名以“.htr”做后缀。于是IIS认为客户端正在请求⼀个“.htr”⽂件,“.htr”扩展⽂件被映像成ISAPI(Internet Service API)应⽤程序,IIS会复位向所有针对“.htr”资源的请求到 ISM.DLL程序
ISM.DLL 打开这个⽂件并执⾏之。浏览器提交的请求中包含的⽂件名存储在局部变量缓冲区中,若它很长(超过600个字符时),会导致局部变量缓冲区溢出,覆盖返回地址空间使IIS崩溃。更进⼀步在2K缓冲区中植⼊⼀段精⼼设计的代码,可以使之以系统超级权限运⾏。四、缓冲区溢出攻击的防范⽅法:缓冲区溢出攻击占了远程⽹络攻击的绝⼤多数,这种攻击可以使得⼀个匿名的Internet⽤户有机会获得⼀台主机的部分或全部的控制权。如果能有效地消除缓冲区溢出的漏洞,则很⼤⼀部分的安全威胁可以得到缓解。⽬前有三种基本的⽅法保护缓冲区免受缓冲区溢出的攻击和影响: 1、通过操作系统使得缓冲区不可执⾏,从⽽阻⽌攻击者植⼊攻击代码; 2、强制写正确的代码的⽅法; 3、利⽤编译器的边界检查来实现缓冲区的保护,使得缓冲区溢出不可能出现,从⽽完全消除了缓冲区溢出的威胁。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。