您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 05(缓冲区溢出与中间人欺骗)
网络安全攻击术缓冲区溢出与中间人欺骗1.缓冲区溢出缓冲区溢出攻击是目前很流行的一种攻击技术。当目标系统收到了超过了它的最大能接收的数据量的时候,将发生缓冲区溢出。这些多余的数据将覆盖实际的程序数据,缓冲区溢出使目标系统的程序被修改,经过这种修改的结果是在系统中产生一个后门或者使系统产生严重错误。通过缓冲区溢出进行的攻击占所有系统攻击总数的50%以上。1.1缓冲区溢出的原理缓冲区是内存中存放数据的地方。在程序试图将数据放到计算机内存中的某一位置,但没有足够空间时会发生缓冲区溢出。通常为了不占用太多的内存,程序在运行时才决定给他们分配多少内存。如果程序在动态分配缓冲区放入太多的数据就会溢出,漏到了别的地方。一个程序在内存中通常分为代码段、数据段和堆栈段三部分。代码段里放着程序的机器码和只读数据。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。1.1缓冲区溢出的原理堆栈是内存中的一个连续的块。堆栈指针寄存器(SP)指向堆栈的栈顶。堆栈的底部是一个固定地址。堆栈有一个特点就是,后进先出。它支持两个操作,PUSH和POP。PUSH是将数据放到栈的顶端,POP是将栈顶的数据取出。在高级语言中,程序函数调用和函数中的临时变量都用到堆栈。参数的传递和返回值是也用到了堆栈。通常对局部变量的引用是通过给出它们对SP的偏移量来实现的。1.1缓冲区溢出的原理1.1缓冲区溢出的原理当程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器(IP)中的内容作为返回地址(RET);第三个放入堆栈的是基址寄存器(BP);然后把当前的栈指针(SP)拷贝到BP,做为新的基地址;最后为本地变量留出一定空间,把SP减去适当的数值。1.1缓冲区溢出的原理voidfunc1(char*input){charbuffer[16];strcpy(buffer,input);}voidmain(){charlongstring[256];inti;for(i=0;i255;i++)longstring[i]='B';func1(longstring);}当调用函数func1()时,堆栈如下:BufferEBPEIP*Input程序执行的结果是“Segmentationfault”或类似的出错信息。因为从buffer开始的256个字节都将被*input的内容'B'覆盖,包括EBP,EIP,甚至*input。'B'的16进值为0x41,所以函数的返回地址变成了0x41414141,这超出了程序的地址空间,所以出现段错误。1.1缓冲区溢出的原理单单的缓冲区溢出,并不会产生安全问题。只有将溢出送到能够以root权限运行命令的区域才行。这样,一个缓冲区利用程序将能运行的指令放在了有root权限的内存中,从而一旦运行这些指令,就是以root权限控制了计算机。缓冲区溢出攻击通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。1.1缓冲区溢出的原理1.2缓冲区溢出漏洞攻击方式缓冲区溢出漏洞可以使黑客取得机器的控制权甚至是最高权限。一般利用缓冲区溢出漏洞攻击root程序。黑客要达到目的通常要完成两个任务:1.在程序的地址空间里安排适当的代码;2.通过适当的初始化寄存器和存储器,让程序跳转到安排好的地址空间执行。A.在程序的地址空间里安排适当的代码在程序的地址空间里安排适当的代码往往是相对简单的。如果要攻击的代码在所攻击程序中已经存在了,那么就简单地对代码传递一些参数,然后使程序跳转到目标中就可以完成了。另一种方式称之为“植入法”。当向要攻击的程序里输入一个字符串时,程序就会把这个字符串放到缓冲区里,这个字符串包含的数据是可以在这个所攻击的目标的硬件平台上运行的指令序列。缓冲区可以设在:堆栈和静态数据区(初始化或者未初始化的数据)等的任何地方。也可以不必为达到这个目的而溢出任何缓冲区,只要找到足够的空间来放置这些攻击代码就够了。B.控制程序转移到攻击代码的形式缓冲区溢出漏洞攻击都是在寻求改变程序的执行流程,使它跳转到攻击代码,最为基本的就是溢出一个没有检查漏洞的缓冲区,这样做就会扰乱程序的正常执行顺序。原则上来讲攻击时所针对的缓冲区溢出的程序空间可为任意空间。但因不同地方的定位相异,所以也就带出了多种转移方式。(1)ActivationRecords(激活记录)当一个函数调用发生时,堆栈中会留驻一个ActivationRecords,它包含了函数结束时返回的地址。执行溢出这些自动变量,使这个返回的地址指向攻击代码,再通过改变程序的返回地址。当函数调用结束时,程序就会跳转到事先所设定的地址,而不是原来的地址。这样的溢出方式也是较常见的。(2)FunctionPointers(函数指针)FunctionPointers可以用来定位函数的地址空间,攻击时只需要在任意空间里的FunctionPointers邻近处找到一个能够溢出的缓冲区,然后用溢出来改变FunctionPointers。当程序通过FunctionPointers调用函数,程序的流程就会实现。C.植入综合代码和流程控制常见的溢出缓冲区攻击类是在一个字符串里综合了代码植入和ActivationRecords。攻击时定位在一个可供溢出的自动变量,然后向程序传递一个很大的字符串,在引发缓冲区溢出改变ActivationRecords的同时植入代码。植入代码和缓冲区溢出不一定要一次性完成,可以在一个缓冲区内放置代码(这个时候并不能溢出缓冲区),然后通过溢出另一个缓冲区来转移程序的指针。这样的方法一般是用于可供溢出的缓冲区不能放入全部代码时的。如果想使用已经驻留的代码不需要再外部植入的时候,通常必须先把代码的地址做为参数。溢出根源在于编程缓冲区溢出是由编程错误引起的。如果缓冲区被写满,而程序没有去检查缓冲区边界,也没有停止接收数据,这时缓冲区溢出就会发生。缓冲区边界检查被认为是不会有收益的管理支出,计算机资源不够或者内存不足是编程者不编写缓冲区边界检查语句的理由,然而摩尔定律已经使这一理由失去了存在的基础,但是多数用户仍然在主要应用中运行十年甚至二十年前的程序代码。溢出根源在于编程一些编程语言对于缓冲区溢出是具有免疫力的,但是被广泛使用的C语言却没有建立检测机制。标准C语言具有许多复制和添加字符串的函数,像对sprintf和strcpy的调用,这两个函数都不会检查参数输入的长度。这使得标准C语言很难进行边界检查。C++略微好一些,但是仍然存在缓冲区溢出。缓冲区溢出的保护方法1、强制写正确的代码的方法编写正确的代码是一件非常有意义但耗时的工作,特别像编写C语言那种具有容易出错倾向的程序,这种风格是由于追求性能而忽视正确性的传统引起的。尽管花了很长的时间使得人们知道了如何编写安全的程序,具有安全漏洞的程序依旧出现。因此人们开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序。虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点,这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少缓冲区溢出的可能,并不能完全地消除它的存在。缓冲区溢出的保护方法2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码这种方法有效地阻止了很多缓冲区溢出的攻击,但是攻击者并不一定要植入攻击代码来实现缓冲区溢出的攻击,所以这种方法还是存在很多弱点的。3、利用编译器的边界检查来实现缓冲区的保护这个方法使得缓冲区溢出不可能出现,从而完全消除了缓冲区溢出的威胁,但是相对而言代价比较大。4、在程序指针失效前进行完整性检查虽然这种方法不能使得所有的缓冲区溢出失效,但它的确阻止了绝大多数的缓冲区溢出攻击,而能够逃脱这种方法保护的缓冲区溢出也很难实现。2.中间人攻击ARP欺骗IP欺骗DNS欺骗ICMP重定向IP欺骗IP欺骗是一种中间人攻击。IP欺骗不是进攻的结果,而是进攻的手段。进攻实际上是信任关系的破坏。IP欺骗是多种网络攻击的必要步骤。IP欺骗原理信任关系假如在主机A和B上各有一个帐户,则在主机A上使用时需要输入在A上的相应帐户,在主机B上使用时必须输入在B上的帐户,主机A和B把你当作两个互不相关的用户,显然有些不便。为了减少这种不便,可以在主机A和主机B中建立起两个帐户的相互信任关系。则可以毫无阻碍地使用远程登录而无口令验证的麻烦。这些命令将允许以地址为基础的验证,或者允许或者拒绝以IP地址为基础的存取服务。这里的信任关系是基于IP地址的。IP欺骗原理IP只是发送数据包,并且保证它的完整性。如果不能收到完整的IP数据包,IP会向源地址发送一个ICMP错误信息,希望重新处理。由于IP是无连接的,所以不保持任何连接状态的信息。每个IP数据包被松散地发送出去,而不关心前一个和后一个数据包的情况。由此看出,可以对IP包进行修改,在源地址和目的地址中放入任意满足要求的IP地址,也就是说,提供虚假的IP地址。IP欺骗原理TCP提供可靠传输。可靠性是由数据包中的多个控制字段来提供的,其中最重要的是数据序列和数据确认。TCP向每一个数据字节分配一个序列号,并且可以向已成功接收的、源地址所发送的数据包表示确认(目的地址ACK所确认的数据包序列是源地址的数据包序列,而不是自己发送的数据包序列)。ACK在确认的同时,还携带了下一个期望获得的数据序列号。显然,TCP提供的这种可靠性相对于IP来说更难于作假。IP欺骗原理接收端利用序列号确保数据的先后顺序,除去重复的数据包。TCP序列编号可以看作是32位的计数器。它们从0至232-1排列。每一个TCP连接交换的数据都是顺序编号的。在TCP数据包中定义序列号(SEQ)字段于数据段的前端。确认序号(ACK)对所接收的数据进行确认,并且指出下一个期待接收的数据序列号。IP欺骗原理TCP标志位:RST、PSH和FIN如果RST被接收,TCP连接将立即断开。RST通常在接收端接收到一个与当前连接不相关的数据包时被发送。当TCP模块需要立即传送数据而不能等整段都充满时再传,一个高层的进程将会触发在TCP头部的PSH标示,并且告诉TCP模块立即将所有排列好的数据发给数据接收端。FIN表示一个应用连接结束。当接收端接收到FIN时,确认它,认为将接收不到任何数据了。TCP序列号预测TCP连接建立包括3次握手的序列。客户选择和传输一个初始的序列号SEQ_C,并设置标志位SYN。服务器确认这个传输,并发送它本身的序列号SEQ_S,并设置标志位ACK,同时告知下一个期待获得的数据序列号是SEQ_C+1。客户再确认它。C---S:SYN(SEQ_C)S---C:SYN(SEQ_S),ACK(SEQ_C+1)C---S:ACK(SEQ_S+1)C必须得到SEQ_S确认。SEQ_S可能是一个随机数。了解序数编号如何选择初始序列号和如何根据时间变化是很重要的。当主机启动后序列编号初始化不会简单地=1。初始序列号是由tcp_init函数确定的。SEQ每秒增加128000,如果有连接出现,每次连接将把计数器的数值增加64000。很显然,这使得用于表示SEQ的计数器在没有连接的情况下每9.32小时复位一次。之所以这样,是因为这样有利于最大限度地减少旧有连接的信息干扰当前连接的机会。如果初始序列号是随意选择的,那么不能保证现有序列号是不同于先前的。以此保证不会有旧的数据出现在新的连接上。TCP序列号预测IP欺骗的步骤假定:首先,目标主机已经选定。其次,信任模式已被发现,并找到了一个被目标主机信任的主机。步骤:使得被信任的主机丧失工作能力;采样目标主机发出的TCP序列号;猜测出它的数据序列号;伪装成被信任的主机,同时建立起与目标主机基于地址验证的应用连接;如果成功,黑客可以使用一种简单的命令放置一个系统后门,以进行非授权操作。序列号取样和猜测先与被攻击主机的一个端口建立起正常的连接。
本文标题:05(缓冲区溢出与中间人欺骗)
链接地址:https://www.777doc.com/doc-3125705 .html