02 缓冲区溢出原理.ppt

上传人:s****8 文档编号:68608601 上传时间:2022-12-29 格式:PPT 页数:23 大小:387KB
返回 下载 相关 举报
02 缓冲区溢出原理.ppt_第1页
第1页 / 共23页
02 缓冲区溢出原理.ppt_第2页
第2页 / 共23页
点击查看更多>>
资源描述

《02 缓冲区溢出原理.ppt》由会员分享,可在线阅读,更多相关《02 缓冲区溢出原理.ppt(23页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、代码安全机制与实现技术 缓冲区溢出原理缓冲区溢出原理教学课件教学课件:ftp:/218.193.154.238/public/姚砺/代码安全机制与实现技术代码安全机制与实现技术课程概述课程概述第四章栈溢出利用n缓冲区溢出:就是在大缓冲区中的数据向小缓冲区复制的过程中,由于没有注意小缓冲区的边界,“撑爆”了较小的缓冲区,从而冲掉了和小缓冲区相邻内存区域的其他数据而引起的内存问题。缓冲溢出是最常见的内存错误之一,也是攻击者入侵系统时所用到的最强大、最经典的一类漏洞利用方式。n成功地利用缓冲区溢出漏洞可以修改内存中变量的值,甚至可以劫持进程,执行恶意代码,最终获得主机的控制权。要透彻地理解这种攻击方

2、式,需要计算机体系架构方面的基础知识,理解CPU、寄存器、内存是怎样协同工作而让程序流畅执行的。课程概述课程概述系统栈的工作原理n内存的不同用途根据不同的操作系统,一个进程可能被分配到不同的内存区域去执行。但是不管什么样的操作系统、什么样的计算机架构,进程使用的内存都可以按照功能大致分成以下4 个部分。(1)代码区:这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行。(2)数据区:用于存储全局变量等。(3)堆 区:进程可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。动态分配和回收是堆区的特点。(4)栈 区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回

3、时恢复到调用函数中继续执行。在Windows平台下,高级语言写出的程序经过编译链接,最终会变成第2章介绍过的PE文件。当PE文件被装载运行后,就成了所谓的进程。PE文件代码段中包含的二进制级别的机器代码会被装入内存的代码区,处理器将到内存的这个区域一条一条地取出指令和操作数,并送入算术逻辑单元进行运算;如果代码中请求开辟动态内存,则会在内存的堆区分配一块大小合适的区域返回给代码区的代码使用;当函数调用发生时,函数的调用关系等信息会动态地保存在内存的栈区,以供处理器在执行完被调用函数的代码时,返回母函数。这个协作过程如下图所示。课程概述课程概述进程的内存使用示意图课程概述课程概述课程概述课程概述

4、栈与系统栈n系统栈系统栈由系统自动维护,它用于实现高级语言中函数的调用。对于类似C语言这样的高级语言,系统栈的PUSH、POP等堆栈平衡细节是透明的。一般说来,只有在使用汇编语言开发程序的时候,才需要和它直接打交道。n系统栈在其他文献中可能曾被叫做运行栈、调用栈等。课程概述课程概述函数调用时发生了什么函数调用时发生了什么intfunc_B(intarg_B1,intarg_B2)intvar_B1,var_B2;var_B1=arg_B1+arg_B2;var_B2=arg_B1-arg_B2;returnvar_B1*var_B2;intfunc_A(intarg_A1,intarg_A2)

5、intvar_A;var_A=func_B(arg_A1,arg_A2)+arg_A1;returnvar_A;intmain(intargc,char*argv)intvar_main;var_main=func_A(4,3);returnvar_main这段代码编译后,各个函数对应的机器指令在代码区中可能是这样分布的(我们可以简单地把它们在内存代码区中的分布位置理解成是散乱无关的)。课程概述课程概述图4.1.4系统栈在函数调用时的变化如图4.1.4所示,在函数调用的过程中,伴随的系统栈中的操作如下:(1)在main函数调用func_A的时候,首先在自己的栈帧中压入函数返回地址,然后为fun

6、c_A创建新栈帧并压入系统栈;(2)在func_A调用func_B的时候,同样先在自己的栈帧中压入函数返回地址,然后为func_B创建新栈帧并压入系统栈;(3)在func_B返回时,func_B的栈帧被弹出系统栈,func_A栈帧中的返回地址被“露”在栈顶,此时处理器按照这个返回地址重新跳到func_A代码区中执行;(4)在func_A返回时,func_A的栈帧被弹出系统栈,main函数栈帧中的返回地址被“露”在栈顶,此时处理器按照这个返回地址跳到main函数代码区中执行。课程概述课程概述寄存器与函数栈帧n每一个函数独占自己的栈帧空间。当前正在运行的函数的栈帧总是在栈顶。Win32系统提供两个

7、特殊的寄存器用于标识位于系统栈顶端的栈帧。n(1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。n(2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。n注意:注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。严格说来,“栈帧底部”和“栈底”是不同的概念,也就是,每个函数都有自己独立的EBP和ESP;所以,每个函数运行时都要将EBP和ESP的值切换成自己的值。课程概述课程概述图4.1.5栈帧寄存器ESP与

8、EBP的作用寄存器与函数栈帧n函数栈帧:ESP和EBP之间的内存空间为当前栈帧,EBP标识了当前栈帧的底部,ESP标识了当前栈帧的顶部。在函数栈帧中,一般包含以下几类重要信息。(1)局部变量:为函数局部变量开辟的内存空间。(2)栈帧状态值:保存前栈帧的顶部和底部(实际上只保存前栈帧的底部,前栈帧的顶部可以通过堆栈平衡计算得到),用于在本帧被弹出后恢复出上一个栈帧。(3)函数返回地址:保存当前函数调用前的“断点”信息,也就是函数调用前的指令位置,以便在函数返回时能够恢复到函数被调用前的代码区中继续执行指令。课程概述课程概述函数调用过程n函数调用大致包括以下几个步骤。(1)参数入栈:将参数从右向左

9、依次压入系统栈中。(2)返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行。(3)代码区跳转:处理器从当前代码区跳转到被调用函数的入口处。(4)栈帧调整:具体包括。n保存当前栈帧状态值,已备后面恢复本栈帧时使用(EBP入栈)。n将当前栈帧切换到新栈帧(将ESP值装入EBP,更新栈帧底部)。n给新栈帧分配空间(把ESP减去所需空间的大小,抬高栈顶)。课程概述课程概述/假设该函数有3个参数,将从右向左依次入栈push参数3push参数2push参数1call函数地址;call指令将同时完成两项工作:a)向栈中压入当前指令在内存;中的位置,即保存返回地址。b)跳转到所调

10、用函数的入口地址函;数入口处pushebp;保存旧栈帧的底部movebp,esp;设置新栈帧的底部(栈帧切换)subesp,xxx;设置新栈帧的顶部(抬高栈顶,为新栈帧开辟空间)图4.1.7函数调用时系统栈的变化过程课程概述课程概述函数调用过程n函数返回的步骤:(1)保存返回值:通常将函数的返回值保存在寄存器EAX中。(2)弹出当前栈帧,恢复上一个栈帧。n具体包括:a)在堆栈平衡的基础上,给ESP加上栈帧的大小,降低栈顶,回收当前栈帧的空间;b)将当前栈帧底部保存的前栈帧EBP值弹入EBP寄存器,恢复出上一个栈帧;c)将函数返回地址弹给EIP寄存器。(3)跳转:按照函数返回地址跳回调用函数中继

11、续执行。addesp,xxxpopebpretn课程概述课程概述函缓冲区溢出的原理n缓冲区溢出的原理缓冲区溢出的原理通过上一节,我们已经知道了函数调用的细节和栈中数据的分布情况。函数的局部变量在栈中一个挨着一个排列。如果这些局部变量中有数组之类的缓冲区,并且程序中存在数组越界的缺陷,那么越界的数组元素就有可能破坏栈中相邻变量的值,甚至破坏栈帧中所保存的EBP值、返回地址等重要数据。注意:大多数情况下,局部变量在栈中的分布是相邻的,但也有可能出于编译优化等需要而有所例外。具体情况我们需要在动态调试中具体对待,这里出于讲述基本原理的目的,可以暂时认为局部变量在栈中是紧挨在一起的。课程概述课程概述#

12、include#definePASSWORD1234567intverify_password(char*password)intauthenticated;charbuffer8;/addlocalbufftobeoverflowedauthenticated=strcmp(password,PASSWORD);strcpy(buffer,password);/overflowedhere!returnauthenticated;voidmain()intvalid_flag=0;charpassword1024;while(1)printf(pleaseinputpassword:);sc

13、anf(%s,password);valid_flag=verify_password(password);if(valid_flag)printf(incorrectpassword!nn);elseprintf(Congratulation!Youhavepassedtheverification!n);break;这段代码执行到 intverify_password(char*password)时的栈帧状态如下图所示。分析分析:在verify_password 函数的栈帧中,局部变量authenticated恰好位于缓冲区buffer8的“下方”。authenticated为int类型,

14、在内存中占4个字节。所以,如果能够让buffer数组越界,buffer8、buffer9、buffer10、buffer11将写入相邻的变量authenticated中。如果我们输入的密码超过了7个字符(注意:字符串截断符NULL将占用一个字节),则越界字符的ASCII码会修改掉authenticated的值。如果这段溢出数据恰好把authenticated改为0,则程序流程将被改变。课程概述课程概述突破密码验证程序实验环境要求:推荐使用的环境备 注操作系统Windows XP sp2其他Win32操作系统也可进行本实验编译器Visual C+6.0如使用其他编译器,需重新调试编译选项默认编译

15、选项VS2003和VS2005中的GS编译选项会使栈溢出实验失败build版本debug版本如使用release版本,则需要重新调试课程概述课程概述BigEndian和LittleEndian的区别n谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用bigendian方式存储数据,而x86系列则采用littleendian方式存储数据。那么究竟什么是bigendian,什么又是littleendian呢?n其实bigendian是指低地址存放最高有效字节(MSB),而littleendian则是低地

16、址存放最低有效字节(LSB)。n比如数字0 x12345678在两种不同字节序CPU中的存储顺序如下所示:BigEndian低地址高地址-|12|34|56|78|LittleEndian低地址高地址-|78|56|34|12|课程概述课程概述修改函数返回地址修改函数返回地址n上节实验介绍的改写邻接变量的方法是很有用的,但这种漏洞利用对代码环境的要求相对比较苛刻。更通用、更强大的攻击通过缓冲区溢出改写的目标往往不是某一个变量,而是瞄准栈帧最下方的EBP和函数返回地址等栈帧状态值。n回顾上节实验中输入7个q程序正常运行时的栈状态,如下表所示。局部变量名局部变量名内内存存地地址址偏移偏移3处的值处

17、的值偏移偏移2处的值处的值偏移偏移1处的值处的值偏移偏移0处的值处的值buffer0 x0012FB180 x71(q)0 x71(q)0 x71(q)0 x71(q)0 x0012FB1CNULL0 x71(q)0 x71(q)0 x71(q)authenticated0 x0012FB200 x000 x000 x000 x01前栈帧前栈帧EBP0 x0012FB240 x000 x120 xFF0 x80返回地址返回地址0 x0012FB280 x000 x400 x100 xEB如果继续增加输入的字符,那么超出buffer8边界的字符将依次淹没authenticated、前栈帧EBP、

18、返回地址。也就是说,控制好字符串的长度就可以让字符串中相应位置字符的ASCII码覆盖掉这些栈帧状态值。课程概述课程概述控制程序的执行流程控制程序的执行流程n攻击设计:n(1)要摸清楚栈中的状况,如函数地址距离缓冲区的偏移量等;n(2)要得到程序中密码验证通过的指令地址,以便程序直接跳去这个分支执行;n(3)要在password.txt文件的相应偏移处填上这个地址。n这样,verify_password函数返回后就会直接跳转到验证通过的正确分支去执行了。课程概述课程概述控制程序的执行流程控制程序的执行流程课程概述课程概述控制程序的执行流程控制程序的执行流程局部变量名内存地址偏移3处的值偏移2处的

19、值偏移1处的值偏移0处的值buffer030 x0012FB140 x31(1)0 x32(2)0 x33(3)0 x34(4)buffer470 x0012FB180 x31(1)0 x32(2)0 x33(3)0 x34(4)authenticated(被覆盖前)(被覆盖前)0 x0012FB1C0 x000 x000 x000 x01authenticated(被覆盖后)(被覆盖后)0 x0012FB1C0 x31(1)0 x32(2)0 x33(3)0 x34(4)前栈帧前栈帧EBP(被覆盖前)(被覆盖前)0 x0012FB200 x000 x120 xFF0 x80前栈帧前栈帧EBP

20、(被覆盖后)(被覆盖后)0 x0012FB200 x31(1)0 x32(2)0 x33(3)0 x34(4)返回地址返回地址(被覆盖前)(被覆盖前)0 x0012FB240 x000 x400 x110 x07返回地址返回地址(被覆盖后)(被覆盖后)0 x0012FB240 x000 x400 x110 x22课程概述课程概述代码植入代码植入n代码植入原理代码植入原理天外飞仙天外飞仙 在buffer里包含我们自己想要执行的代码,然后通过返回地址让程序跳转到系统栈里执行,即让进程去执行本来没有的代码!课程概述课程概述代码植入代码植入n实验目的实验目的 通过向password.txt文件里植入二进制的机器码,并用这段机器码来调用Windows的一个API函数MessageBoxA,最终在桌面上弹出一个消息框并显示“failwest”字样。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com