《缓冲区溢出攻击精选PPT.ppt》由会员分享,可在线阅读,更多相关《缓冲区溢出攻击精选PPT.ppt(65页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、缓冲区溢出攻击第1页,此课件共65页哦微软安全中心微软每月第二周的周二发布补丁(BLACK TUESDAY),许多黑客通宵达旦去研究这些补丁PATCK了哪些漏洞,并写出EXPLOIT,因为在补丁刚发布的一段时间内,并非所有用户能及时修复。公布漏洞的两个权威机构CEV、CERT。第2页,此课件共65页哦二进制文件PE(PORTABLE EXECUTABLE)是WIN32平台下可执行文件(EXE、DLL)的数据格式。一个可执行文件除包含二进制的机器代码外,还带有字符串、菜单、图标、位图、字体等,PE文件格式规定了这些信息在可执行文件中如何组织,在程序被执行时,OS会按照PE文件格式的约定去相应的地
2、方精确地定位各种资源,并分别装入内存的不同区域。第3页,此课件共65页哦PE文件格式PE文件格式把可执行文件分成几个数据节(SECTION),不同的资源存放在不同的节中。TEXT由编译器产生,存放二进制的机器代码,是反汇编和调试的对象。DATA初始化的数据块,如宏定义、全局变量、静态变量等。IDATA可执行文件所使用的动态链接库等外来函数与文件的信息。RSRC存放程序的资源,如图标、菜单等。第4页,此课件共65页哦PE文件格式其他的节RELOCEDATATLSRDATA使用VISUAL C+中的编译指示符#PRAGMA DATA_SEG()可把代码中的任意部分编译到PE的任意节中,节名也可任意
3、定义。如可执行文件经过了加壳处理,PE得节信息会变得古怪,在CRACK和反病毒分析中要经常处理这些古怪的PE文件第5页,此课件共65页哦虚拟内存WINDOWS的内存分成两个层面:物理内存和虚拟内存。物理内存很复杂,需进入WINDOWS内核级别RING0才能看到。在用户模式,我们用调试器看到的内存地址都是虚拟内存。每个进程都相信自己拥有独立的4GB内存空间。第6页,此课件共65页哦WINDOWS虚拟内存与物理内存进程1进程1的虚拟内存(4GB)进程2进程3进程2的虚拟内存(4GB)进程3的虚拟内存(4GB)虚拟内存管理器真正的物理内存512M第7页,此课件共65页哦PE文件与虚拟内存之间的映射在
4、调试漏洞时,要做两件操作(1)用静态反汇编工具看到的PE文件中某条指令的位置是相对于磁盘文件而言的,即所谓的文件偏移,我们还需要知道这条指令在内存中的位置,即虚拟内存地址(VA)。(2)在调试时看到的摩条指令的地址是虚拟内存地址,我们需要回到PE文件中找到这条指令对应的机器码。第8页,此课件共65页哦PE文件地址与虚拟内存地址之间的映射关系文件偏移地址(FILE OFFSET)数据在PE文件中的地址为文件偏移地址,这是文件在磁盘上存放时相对于文件开头的偏移。装载基址(IMAGE BASE):PE文件装入内存时的基地址。默认情况下,EXE文件在内存中的基址是0X00400000,DLL文件是0X
5、10000000。这些位置可通过修改编译选相更改。第9页,此课件共65页哦PE文件地址与虚拟内存地址之间的映射关系虚拟内存地址(VIRTUAL ADDRESS,VA)PE文件中的指令被装入内存后的地址。相对虚拟地址(RELATIVE VIRTUAL ADDRESS,RVA)相对虚拟地址是内存地址相对于映射基址的偏移量。他们间的关系:VA=IMAGE BASE+RVA第10页,此课件共65页哦PE文件与虚拟内存的映射关系PE文件 内存其他DATA节RDATA节TEXT节文件头、节表等DATA节RDATA节TEXT节文件头、节表等PE文件起始0字节0X200字节0X200字节0X200字节装载基址
6、0X004000000X1000字节0X1000字节0X1000字节第11页,此课件共65页哦PE文件与虚拟内存的映射关系在上图中,在默认情况下,一般PE文件的0字节将映射到虚拟内存的0X00400000位置,即为装载基址(IMAGE BASE)。文件偏移是相对于文件开始处0字节的偏移,RVA是相对于装载基址0X00400000处的偏移,OS在装载时基本上保持PE中的各种数据结构,所以文件偏移地址和RVA有很大的关系。第12页,此课件共65页哦基本的理由PE文件中的数据按照磁盘数据标准存放,以0X200字节为基本单位进行组织。一个数据节(SECTION)不足0X200字节时,以0X00填充,因
7、此PE数据节的大小是0X200的整数倍。同理,当代码装入内存后,按照内存数据标准存放,以0X1000字节为基本单位进行组织,因此内存中的数据节的大小是0X1000的整数倍。第13页,此课件共65页哦节偏移由于内存中数据节相对于装载基址的偏移量和文件中数据节的偏移量有上述差异,在进行文件偏移到虚拟内存地址之间的换算时要考虑到所转换的地址位于第几个节中。这种由存储单位差异引起的节基址差称为节偏差第14页,此课件共65页哦转换关系文件偏移地址=虚拟内存地址(VA)-装载基址(IMAGE BASE)-节偏移=RVA-节偏移一些PE工具提供了这类地址转换,如LORD PE,他也可用来查看PE文件中的节信
8、息。第15页,此课件共65页哦系统栈的工作原理内存的不同用途缓冲区溢出就是在大缓冲区中的数据向小缓冲区复制的过程中,由于没注意小缓冲区的边界,”撑破“了较小的缓冲区,从而覆盖了与小缓冲区相邻内存区域的其他数据而引起的内存问题。缓冲区溢出是攻击者入侵系统时所用到的最强大、最经典的一种漏洞利用方式。利用缓冲区溢出漏洞可以修改内存中变量的值,可以劫持进程,执行恶意代码,最终控制主机。第16页,此课件共65页哦理解缓冲区溢出攻击的条件CPU、寄存器、内存的协同工作让程序流畅地执行。第17页,此课件共65页哦内存的不同用途不同的OS,一个进程可被分配到不同的内存区域去执行,但进程使用的内存可按功能大致分
9、成4个部分。代码区:存储被装入执行的二进制机器代码,处理器会到这个区域取指令并执行。数据区:存储全局变量等。堆区:进程可在堆区动态请求一定大小的内存,并在用完后还给堆区,是动态分配和回收。第18页,此课件共65页哦内存的不同用途栈区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行。深入理解程序的运行机制,请参阅深入理解计算机系统一书。在WINDOWS平台,高级语言写的程序经过编译连接后变成了PE文件。当PE文件被装载运行后,就成了所谓的进程。第19页,此课件共65页哦程序运行的协作过程PE文件代码段中包含的二进制机器代码会被装入内存的代码区(TEXT),处理器
10、会到内存的这个区域一条一条地取出指令和操作数,并送入算术逻辑单元进行运算。如代码请求开辟动态内存,则会在内存的堆区分配一块大小合适的区域返回给代码区的代码使用。如函数调用发生时,函数的调用关系等信息会动态地保存在内存的栈区,以供处理器在执行完被调用函数的代码时,返回母函数。第20页,此课件共65页哦协作过程PE文件装载运行-XOR EBX,EBXMOV BH,4SUB ESP,EBPMOV BX,3234PUSH EBXPUSH 723456PUSH ESPXOR EDX,EDX-进程的虚拟内存空间堆数据区(全局变量)当前函数的栈帧函数栈帧函数栈帧函数栈帧-函数栈帧ESPEBPEIP第21页,
11、此课件共65页哦缓冲区的分类进程中所用的缓冲区可以是堆区、栈区和存放静态变量的数据区。缓冲区溢出的利用方法和缓冲区到底属于上面哪个内存区域密不可分,我们主要针对系统栈的情形。第22页,此课件共65页哦栈与系统栈 栈是一种数据结构,是一种先进后出的数据表,他有两种常见操作:压栈(PUSH)、弹栈(POP),标示栈顶(TOP),栈低(BASE)。内存的栈区实际上指的就是系统栈,由系统自动维护,它用于实现高级语言中函数的调用,对类C的高级语言来说,PUSH和POP是透明的,在用汇编语言设计程序时,才需和它直接打交道。第23页,此课件共65页哦函数调用时发生了什么先看一段代码:intfunc_B(in
12、t arg_B1,int arg_B2)int var_B1,var_B2;var_B1=arg_B1+arg_B2;var_B2=arg_B1-arg_B2;return var_B1*var_B2;intfunc_A(int arg_A1,int arg_A2)int var_A;var_A=func_B(arg_A1,arg_A2)+arg_A1;return var_A;int main(int argc,char*argv,char*envp)int var_main;var_main=func_A(4,3);return var_main;第24页,此课件共65页哦机器指令在代码区
13、中的分布上段代码经过编译器编译后,各个对应的机器指令在代码区中可能是这样分布的-(其他指令)-(FUNC_A的指令)-(MAIN函数指令)-(其他指令)-FUNC_B的指令-第25页,此课件共65页哦机器指令在代码区中的分布依据OS的不同,编译器和编译选项的不同,同一文件不同函数的代码在内存代码区中的分布可能相邻,也可能相离甚远,可能先后有序,也可能无序,但他们都在同一个PE文件的代码所影射的一个节里。当CPU在执行调用FUNC_A函数时,会从代码区中MAIN函数对应的机器指令的区域跳转到FUNC_A函数对应的机器指令区域,在那里取指并执行;当FUNC_A函数执行完毕,需返回时,又会跳回到MA
14、IN函数对应的机器指令区域,紧接着调用FUNC_A函数后面的指令继续执行MAIN函数的代码。第26页,此课件共65页哦CPU在代码区中的取指轨迹MAIN函数入口-CALL FUNC_A后继的指令-返回指令FUNC_B函数入口-返回指令FUNC_A函数入口-CALL FUNC_B后继的指令-返回指令返回到上层函数的代码空间,紧接着执行函数调用的后继指令处理器跳转去FUNC_A的代码空间去继续执行跳转去FUNC_B的代码空间取指执行第27页,此课件共65页哦系统栈的作用CPU是如何知道要去FUNC_A的代码区取指,在执行完FUNC_A后又是如何知道跳回到MAIN函数(而不是FUNC_B的代码区)?
15、CPU从何得知这些函数的调用及返回信息?在代码区中精确的跳转都是借助系统栈的配合。当函数被调用时,系统栈会为这个函数开辟一个新的栈帧,并把它压入栈中,这个栈帧中的内存空间被它所属的函数独占,是不会和别的函数共享的。当函数返回时,系统栈会弹出该函数所对应的栈帧。第28页,此课件共65页哦系统栈在函数调用时的变化栈顶方向TOP栈底方向BASEMAIN函数栈帧其他函数栈帧-FUNC_A栈帧局部变量返回地址MAIN函数栈帧其他函数栈帧FUNC_B栈帧局部变量返回地址FUNC_A栈帧局部变量返回地址MAIN函数栈帧其他函数栈帧FUNC_A栈帧局部变量返回地址MAIN函数栈帧其他函数栈帧MAIN函数栈帧其
16、他函数栈帧用弹出的返回地址回溯出上一个函数的代码空间用弹出的返回地址回溯出上一个函数的代码空间第29页,此课件共65页哦在函数调用过程中系统栈中的操作MAIN函数调用FUNC_A时,首先在自己的栈帧中压入函数返回地址,然后为FUNC_A创建新栈帧并压入系统栈。在FUNC_A调用FUNC_B时,首先在自己的栈帧中压入函数返回地址,然后为FUNC_B创建新栈帧并压入系统栈。在FUNC_B返回时,FUNC_B的栈帧被弹出系统栈,FUNC_A栈帧中的返回地址被露在栈顶,此时处理器按照这个返回地址重新调到FUNC_A代码区中执行。在FUNC_A返回时,FUNC_A的栈帧被弹出系统栈,MAIN函数栈帧中的
17、返回地址被露在栈顶,此时处理器按照这个返回地址跳到MAIN函数代码区中执行。第30页,此课件共65页哦寄存器与函数栈帧每一个函数独占自己的栈帧空间,当前正在运行的函数的栈帧总是在栈顶。WIN32系统用两个特殊的寄存器来标识位于栈顶的栈帧。ESP:栈指针寄存器(EXTENDED STACK POINTER),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。EBP:基址指针寄存器(EXTENDED BASE POINTER),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。第31页,此课件共65页哦寄存器对栈帧的标识作用栈帧1栈帧2栈帧3栈帧-EBPESP栈顶以上的未使
18、用的内存空间栈帧2栈帧3栈帧-EBPESP栈帧1被释放栈顶以上的未使用的内存空间-第32页,此课件共65页哦函数栈帧ESP和EBP之间的内存空间为当前栈帧,ESP标识了当前栈帧的顶部,EBP标识了当前栈帧的底部。在函数栈帧中,一般包含以下几类重要信息:局部变量:为函数局部变量开辟的内存空间。栈帧状态值:保存前栈帧的顶部和底部(实际上只保存前栈帧的底部),用于在本栈帧被弹出后恢复出上一个栈帧。函数返回地址:第33页,此课件共65页哦EIP指令寄存器(EXTENDED INSTRUCTION POINTER)其内存放着一个指针,该指针永远指向下一条等待执行的指令地址。如控制了EIP指令寄存器的内容
19、,就控制了进程我们让EIP指向哪里,CPU就会去执行那里的指令。第34页,此课件共65页哦EIP指令寄存器的作用-XOR EBX,EBXMOV BH,4SUB ESP,EBPMOV BX,3234PUSH EBXPUSH 723456PUSH ESPXOR EDX,EDX-EIPEIP为指令寄存器,永远指向下一条等待执行的指令。CPU按照EIP寄存器的所指位置取出指令和操作数后,送入算术逻辑单元运算处理。第35页,此课件共65页哦函数调用约定与相关指令函数调用约定描述了函数传递参数方式和栈协同工作的细节。约定:传递参数方式,参数入栈次序,函数返回时恢复堆栈平衡的操作在母还是子函数中进行等。CS
20、YSCALLSTDCALLBASICFORTRANPASCAL参数入栈次序右左右左右左左右左右左右恢复堆栈平衡的操作母函数子函数子函数子函数子函数子函数第36页,此课件共65页哦函数调用约定对于VISUAL C+来说,可支持3种函数调用约定。VC在默认情况下使用_STDCALL调用方式。同段代码不同的编译选项、不同的编译器编译链接后,得到的可执行文件有很多不同。调用约定的声明参数入栈次序恢复堆栈平衡的操作_CDECL右左母函数_FASTCALL右左子函数_STDCALL 右左子函数第37页,此课件共65页哦函数调用大致包括的几个步骤参数入栈:将参数从右向左依次压入系统栈中。返回地址入栈:将当前
21、代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行。代码区跳转:处理器从当前代码区跳转到被调用函数的入口处。第38页,此课件共65页哦函数调用大致包括的几个步骤栈帧调整:具体包括保存当前栈帧状态值,以备后面恢复本栈时使用(EBP入栈)。将当前栈帧切换到新栈帧(将ESP值装入EBP,更新新栈帧底部)。给新栈帧分配空间(把ESP减去所需空间的大小,抬高栈顶)。第39页,此课件共65页哦_STDCALL调用约定时函数调用用到的指令序列;调用前PUSH参数3(设有三个参数)PUSH参数2PUSH参数1CALL函数地址;CALL指令向栈中压入当前指令在内存中的位置,即保存返回地址。然后跳转到被
22、调用函数的入口处。PUSH EBP;保存旧栈帧的底部MOV EBP,ESP;设置新栈帧的底部(栈帧切换)SUB ESP,XXX;设置新栈帧的顶部(抬高栈顶,为新栈帧开辟空间)第40页,此课件共65页哦上段用于函数调用的指令在栈中引起的变化ESPEBP函数调用前当前函数栈帧ARG1ARG2ARG3ESPEBP当前函数栈帧PUSHARG_X函数参数从右到左入栈返回地址ARG1ARG2ARG3ESPEBP当前函数栈帧CALL指令引起的压栈操作。紧接CALL后面那条指令的内存地址被压入栈中,即返回地址EBP返回地址ARG1ARG2ARG3前栈帧EBPESPEBP当前函数栈帧PUSH EBP保存当前栈帧
23、的底部位置,备栈帧恢复时使用前栈帧EBP返回地址ARG1ARG2ARG3前栈帧EBPESPEBP当前函数栈帧MOV EBP,ESP设置新栈帧的底部开始栈帧切换前栈帧EBP返回地址ARG1ARG2ARG3前栈帧EBPEBPESP旧函数栈帧新函数栈帧SUB ESP,XXX设置新栈帧的顶部,新栈帧切换完毕第41页,此课件共65页哦说明前栈帧EBP值既属于上一个栈帧,也属于下一个栈帧,返回地址成为栈帧顶部的数据第42页,此课件共65页哦函数返回时步骤保存返回值:通常将函数返回值保存在EAX寄存器中。弹出当前栈帧,恢复上一个栈帧。具体包括在堆栈平衡的基础上,给ESP加上栈帧的大小,降低栈顶,回收当前栈帧
24、的空间。将当前栈帧底部保存的前栈帧EBP值弹入EBP寄存器,恢复上一个栈帧。将函数返回地址弹给EIP寄存器。跳转:按照函数返回地址跳回母函数中继续执行。第43页,此课件共65页哦WIN32平台函数返回时相关指令序列ADD ESP,XXX;降低栈顶,回收当前栈帧POP EBP;将上一个栈帧底部位置恢复到EBPRETN;弹出当前栈顶元素,即弹出返回地址,栈帧恢复完成。让处理器跳转到弹出的返回地址,恢复调用前的代码区。第44页,此课件共65页哦最终按函数调用约定组织起来的系统栈结构图局部变量VAR_B2局部变量VAR_B1前栈帧EBP返回地址FUNC_B第一个参数ARG_B1FUNC_B第二个参数A
25、RG_B2局部变量VRA_A前栈帧EBP返回地址FUNC_A第一个参数ARG_A1FUNC_A第二个参数ARG_A2局部变量VRA_MAIN前栈帧EBP返回地址MAIN第一个参数INT ARGCMAIN第二个参数CHAR*ARGVMAIN第三个参数CHAR*ENVP其他数据-MAIN栈帧FUNC_A栈帧FUNC_B栈帧ESPEBPFUNC_A代码区-CALL FUNC_BMOV VAR-A,EAX-MAIN代码区-CALL FUNC_AMOV VAR-MAIN,EAX-第45页,此课件共65页哦代码植入原理如果在BUFFER中包含我们自己想要执行的代码,然后通过返回地址让程序跳转到系统栈里执行
26、。在实验中,我们向PASSWORD.TXT文件里植入二进制的机器码,并用这段机器码来调用WINDOWS的一个API函数 MESSAGEBOXA,最终在桌面弹出一个消息框并显示“MAOTEACH”。第46页,此课件共65页哦示例代码#include#include#define PASSWORD 1234567int verify_password(char*password)int authenticated;char buffer44;authenticated=strcmp(password,PASSWORD);strcpy(buffer,password);/over flowed he
27、re!return authenticated;main()int valid_flag=0;char password1024;FILE*fp;LoadLibrary(user32.dll);/prepare for messageboxif(!(fp=fopen(password.txt,rw+)exit(0);fscanf(fp,%s,password);valid_flag=verify_password(password);if(valid_flag)printf(incorrect password!n);elseprintf(Congratulation!You have pas
28、sed the verification!n);fclose(fp);第47页,此课件共65页哦利用栈溢出植入可执行代码-BUFFER(可执行机器码)-(可执行机器码)-(可执行机器码)Authenticated(覆盖)前栈帧EBP(覆盖)返回地址(覆盖)-溢出后被改写的新返回地址-用 包 含 可 正 确 执 行 的机 器 码 填 充 缓 冲 区,并 将 返 回 地 址 覆 盖成 B U F F E R的 起 址,成功后可让程序跳转到 栈 区 执 行 我 们 输 入的代码-CALL verify_passwordADD ESP,4MOV DWORD PTR SS:EBP-4,EAXMOV DW
29、ORD PTR SS:EBP-4,0-正常情况下的返回地址第48页,此课件共65页哦要做的几项工作分析并调试漏洞程序,获得淹没返回地址的偏移。获得BUFFER的起始地址,并将其写入PASSWORD.TXT的相应偏移处,用来覆盖返回地址。向PASSWORD.TXT中写入可执行的机器代码,用来调用API弹出一个消息框。第49页,此课件共65页哦示例代码的说明verify_password函数的局部变量buffer为44个字节,buffer的大小依赖于我们要植入代码的大小。Main函数中使用LoadLibrary(“user32.dll”);用于初始化装载USER32.DLL,以便在植入代码中调用M
30、ESSAGEBOX函数。第50页,此课件共65页哦代码植入的事先分析verify_password函数的局部变量buffer为44个字节,当MAIN函数调用它时,栈的结构为右图。-BUFFER0-3机器码-(可执行机器码)BUFFER40-43机器码Authenticated(覆盖)前栈帧EBP(覆盖)返回地址(覆盖)-44个字节-第51页,此课件共65页哦代码植入的事先分析如在PASSWORD.TXT中恰好写入44个字符,那么第45个隐藏的截断符NULL将覆盖Authenticated底字节中的1。用11组“4321”输入单元来填充buffer。则第12个输入单元将覆盖Authenticat
31、ed;第13个输入单元将覆盖前栈帧EBP;第14个输入单元将覆盖返回地址。接下去我们要验证上述分析的正确性。第52页,此课件共65页哦验证在PASSWORD.TXT中恰好写入44个字符。第53页,此课件共65页哦验证程序运行后,如我们所料,Authenticated被覆盖,程序进入验证通过分支,如下图:第54页,此课件共65页哦验证用OLLYDBG加载这个生成的PE文件进行动态调试,字符串拷贝函数过后的栈状态:第55页,此课件共65页哦buffer44Authenticated前栈帧EBP返回地址第56页,此课件共65页哦验证结果动态调试的结果验证了我们前面分析是正确的。第57页,此课件共65
32、页哦设计植入代码(SHELLCODE)由于我们在植入代码中调用了MESSAGEBOX函数来显示弹出框,为此要先找到MESSAGEBOX函数在内存中的加载位置,找到这个位置后,我们就可用汇编代码到这个地址处去调用MESSAGEBOX函数。第58页,此课件共65页哦MESSAGEBOX函数在内存中的加载位置由于MESSAGEBOX函数是由动态链接库USER32.DLL导出的,所以我们要先找到相关的IBVARVA等值。可用VC自带的工具DEPENDS来加载任一个有图形界面的PE 文件进去即可。第59页,此课件共65页哦USER32.DLL的位置USER32.DLL的加载基址MESSAGEBOX函数的
33、RVA第60页,此课件共65页哦MESSAGEBOX函数的VA计算由上图可知,IM=0 x77d10000,RVA=0 x0004058A,所以VA=IM=0 x77D10000 RVA=0 x0004058A+0X77D5058AVA=第61页,此课件共65页哦设计SHELLCODE机器代码(16进制)汇编指令注释33 DBXOR EBX,EBX压入NULL结尾的”maoteach”53PUSH EBX68 65 61 63 68PUSH 6863616568 6D 61 6F 74PUSH 746F616D8B C4MOV EAX,ESPEAX中是字符串指针53PUSH EBX按从右到左的次序压入4个参数,分别为(0,maoteach,maoteach,0),消息框为默认50PUSH EAX50PUSH EAX53PUSH EBXB8 8A 05 D5 77MOV EAX,0X77D5058A调用MESSAGEBOX函数,注意:不同的机器这里的函数入口地址可能不同,按实际填入FF D0CALL EAX第62页,此课件共65页哦第63页,此课件共65页哦第64页,此课件共65页哦第65页,此课件共65页哦