《网络安全技术原理与实践缓冲区溢出攻击.pptx》由会员分享,可在线阅读,更多相关《网络安全技术原理与实践缓冲区溢出攻击.pptx(29页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、6.1 缓冲区溢出基本概念缓冲区溢出基本概念 缓冲区是程序运行的时候机器内存中用于存放数据的临时内存空间,它的长度事先已经被程序或操作系统定义好。缓冲区在系统中的表现形式是多样的,高级语言定义的变量、数组、结构体等在运行时可以说都是保存在缓冲区内的,因此所谓缓冲区可以更抽象地理解为一段可读写的内存区域。第1页/共29页6.2 缓冲区溢出攻击方式目前的缓冲区溢出攻击,可以按照以下方法进行分类:(1)按照溢出位置分类:栈溢出、堆溢出和BSS段溢出。(2)按照攻击者欲达到的目标分类:在程序的地址空间里植入适当的代码以及通过适当地初始化寄存器和存储器从而控制程序转移到攻击者安排的地址空间去执行。(3)
2、按照攻击目标分类:攻击栈中的返回地址、攻击栈中保存的旧框架指针、攻击堆或BSS段中的局部变量或参数、攻击堆或BSS段中的长跳转缓冲区。第2页/共29页6.2.1 栈溢出攻击原理 栈是一种数据结构,是一种先进后出的数据表。在Windows 平台下,寄存器“EBP”和“ESP”分别指向当前栈帧的栈底和栈顶。函数调用时,一般需要经过以下步骤:1)参数入栈:参数按一定的顺序压入系统栈,在Std Call约定的情况下,从右到左的顺序压入系统栈。2)返回地址入栈:将当前代码区调用指令的下一条指令存入栈中,函数返回时,继续执行。第3页/共29页3)指令代码跳转:中央处理器从当前的代码区跳转到被调用函数的入口
3、处。在示例代码中,就是跳转到function函数的入口。示例代码void function(char*p)char out10;strcpy(out,p);/*主函数*/main()char a=”AAAABBBBCC”;function(a);第4页/共29页4)栈桢调整:首先保存当前栈桢,也就是将前栈桢压入栈,将当前栈桢切换到新栈桢,为新的函数栈桢分配存储空间。被调用函数执行完之后,返回到调用函数继续执行,包括以下步骤:o 保存返回值:通常将函数的返回值传给EAX寄存器。o 恢复栈顶:在堆栈平衡的基础上,弹出原先保存的EBP值,并修改ESP值,使调用函数的栈桢成为系统当前栈桢。o 指令地址
4、返回:将先前保存的函数返回地址传给指令指针寄存器。第5页/共29页函数调用时栈桢变化图第6页/共29页6.2.2 堆溢出攻击原理 所谓堆,就是由应用程序动态分配的内存区。操作系统中,大部分的内存区是在内核一级被动态分配的,但段是由应用程序来分配的,它在编译的时候被初始化。非初始化的数据段用于存放程序的静态变量,这部分内存都是被初始化为零的。在大部分的系统包括系统中,段是向上增长的,向高地址方向增长。堆管理系统主要有三类操作:堆块分配,堆块释放和堆块合。堆溢出时单链表在删除节点第7页/共29页堆溢出攻击主要有为以下几类。(1)内存变量:修改能够影响程序执行的重要标志变量,例如更改身份验证函数的返
5、回值就可以直接通过认证。(2)代码逻辑:修改代码段重要函数的关键逻辑,有时可以达到一定的攻击效果。(3)函数返回地址:通过修改函数的返回地址能够改变程序执行流程,堆溢出可以利用Arbitrary Dword Reset更改函数返回地址。(4)异常处理机制:当程序产生异常时,Windows执行流程会转入异常处理例程。(5)函数指针:系统有时会使用函数指针,例如C+中的虚函数、动态链接库中的导出函数等。修改这些函数指针后,函数调用时,就可以成功地劫持进程。第8页/共29页6.2.3 流程跳转技术 缓冲区溢出的一个非常关键的步骤就是要实现进程执行流程跳转,这也正是缓冲区溢出攻击的首要目的。只有实现了
6、流程的跳转,才能在被攻击的主机上执行所植入的代码,实现控制被攻击主机的目的。要实现执行流程跳转,攻击者可以通过缓冲区溢出漏洞修改有关执行流程的管理信息,如返回地址。缓冲区溢出攻击示意图第9页/共29页6.3 缓冲区溢出攻击步骤6.3.1 获取漏洞信息 缓冲区溢出漏洞信息的获取,主要有两种途径,一是自己挖掘,二是从漏洞公告中获得。当前,公布漏洞信息的权威机构主要有 公共漏洞公告(Common Vulnerabilities and Exposures,CVE)和计算机应急响应小组(Computer Emergency Response Team,CERT)中获取漏洞信息,如图所示。第10页/共2
7、9页6.3.2 定位漏洞位置 漏洞位置定位是指确定缓冲区溢出漏洞中发生溢出的指令地址(通常称为溢出点),并可以在跟踪调试环境中查看与溢出点相关的代码区和数据区的详细情况,根据此信息,精心构造注入的数据。具体来说,通常使用以下三种方法。1)如果受影响程序有源代码,那么通过调试程序、确定漏洞所在位置,修改源程序就可修复漏洞。2)如果存在缓冲区溢出漏洞的程序,没有源代码,则一般采用反汇编法和探测法定位漏洞。3)如果能够获得厂商提供的漏洞补丁程序,那么一个有效的办法是使用补丁比较法。第11页/共29页6.3.3 更改控制流程 更改控制流程是将系统从正常的控制流程转向到攻击者设计的执行流程,其实质就是要
8、执行刚刚注入的SHELLCODE代码。因为程序执行完函数后会返回到EIP所指向的地址继续执行,因此覆盖返回地址可以控制程序的执行流程。该方法是缓冲区溢出漏洞利用时用得最多的一种方法。其它的还有改写函数指针和改写异常处理指针。(1)改写函数指针。(2)改写异常处理指针。第12页/共29页6.4 缓冲区溢出攻击的防范方法 目前有三种基本的方法保护缓冲区免受缓冲区溢出的攻击和影:o强制写正确的代码的方法o基于探测方法的防御o对缓冲区溢出漏洞检测研究主要分为如下的三类:1)基于源代码的静态检测技术 2)基于目标代码的检浏技术 3)基于源代码的动态检测技术o 基于操作系统底层的防御 1)库函数的保护 2
9、)操作系统内核补丁保护(a)NOEXEC技术(b)ASLR(Address Space Layout Randomization,地址空间结构随机化)第13页/共29页1.实验环境Windows XP SP3 32-bitVisual C+6.0OllyDbg6.5 缓冲区攻击实验第14页/共29页2.实验步骤编写具有缓冲区溢出的程序,程序代码如下:#include#include#include#define TEMP_BUFF_LEN 8int bof(const char*buf)char tempTEMP_BUFF_LEN;strcpy(temp,buf);return 0;int m
10、ain()char buff=1234567;MessageBox(NULL,SampleBOF Test,SampleBOF,MB_OK);bof(buff);printf(SampleBOF Endn);return 0;第15页/共29页编译上述代码,生成可执行文件。在OllyDbg中打开程序,如图所示。第16页/共29页 上图中标注了每个窗口的用途,向下移动“反汇编窗口”可以看到程序的主入口函数“main”函数,以及调用的“bof”函数,如图所示。第17页/共29页 通过“F2”快捷键在“main”和“bof”所在行下断点,利用快捷键“F9”执行到断点处,“F8”单步执行,如图所示。第
11、18页/共29页 在“MessageBox”后下断点,如下图所示,程序在为调用“bof”函数准备必要参数,并压入栈中。第19页/共29页 接下来,仔细分析“bof”函数的调用过程,该函数的全部汇编代码如下图所示。第20页/共29页 从汇编代码可以看到,函数“bof”首先将“EBP”入栈保存,紧接着将“ESP”赋值给“EBP”。在调用“bof”函数时,程序将参数的地址压栈保存,而在进入“bof”函数之后,程序为了保存上一个栈的基址,又进行了一次压栈操作,因此“bof”函数的参数的地址应该位于“ebp+8”的位置处(注意在windows平台栈是向下生长的)。为了调用“strcpy”函数,程序首先取
12、得“buf”参数的地址并压栈,接着获取“temp”变量的地址并压栈保存,所有参数准备完全,就可以执行“strcpy”函数的调用了。在调用“strcpy”函数之后,程序就执行必要的清理工作然后返回,这就是上面示例代码所做的工作。在调用“strcpy”函数时,我们并没有检查“temp”变量是否有足够的空间来保存“buf”中的内容,若“buf”中的内容超出“temp”变量的大小,在“buf”内容超过“temp”变量的空间时所引发的错误。通常情况下,这类错误会导致程序的异常退出。第21页/共29页缓冲区溢出利用的实验代码如下:#include#include#include#define TEMP_B
13、UFF_LEN 8int bof(const char*buf)char tempTEMP_BUFF_LEN;strcpy(temp,buf);return 0;int sbofa()MessageBox(NULL,Congratulations!You have the basic principles of buffer overflow.,SampleBOF,MB_OK);return 0;int main()MessageBox(NULL,SampleBOF Test,SampleBOF,MB_OK);char buff=1234567;bof(buff);printf(SampleB
14、OF Endn);return 0;第22页/共29页 函数地址上述代码在原有代码的基础上只增加了一个“sbofa”函数,注意到我们并没有调用该函数,而我们需要做的就是通过修改“main”中“buff”的值,使得程序执行“sbofa”函数。同样,使用“OllyDbg”打开程序,找到程序的入口函数及“sbofa”和“bof”函数。如下图所示:第23页/共29页 从图中可以看到,函数在调用时,通常是由调用者负责保存返回地址,然后被调用者负责保存调用者的栈帧(EBP),接下来就是函数的临时变量空间。因此,只要被复制的内容长度大过12,就会覆盖掉返回地址。知道如何覆盖返回地址,接下来就只需要知道“sb
15、ofa”函数的地址就可以了。程序栈结构第24页/共29页如下所示修改“buff”的内容,编译运行。第25页/共29页思思 考考1.从函数地址图中可以看到“sbofa”函数的地址为“0040100F”,为什么“buff”的内容却被修改为123456781234x0fx10 x40?2.程序栈图中返回地址之上的内容是什么?3.经过上面修改后,能够执行“sbofa”函数,但是程序依然异常退出,这是为什么?第26页/共29页4.利用缓冲区溢出原理,修改“sbofa”函数,使程序正常退出。提示:int sbofa()char tempTEMP_BUFF_LEN;char buffer=modify;MessageBox(NULL,Congratulations!You have the basic principles of buffer overflow.,SampleBOF,MB_OK);strcpy(temp,buffer);return 0;第27页/共29页谢 谢!第28页/共29页感谢您的观看!第29页/共29页