您好,欢迎访问三七文档
2012-2013学年第2学期《网络安全课程设计》实验报告实验名称:缓冲区溢出——本地缓冲区溢出完成时间:2014.6.18姓名:柳鑫学号:110342118指导教师:崔鸿班级:110342A实验效果实验报告总评任务一利用跳转指令实现缓冲区溢出本练习单人为一组。首先使用“快照X”恢复Windows系统环境。一.溢出程序演示(1)进入实验平台,单击工具栏“演示目录”按钮,进入实验目录。进入Mission1目录,双击overflow_win.exe,加载ShellCode执行溢出操作。二.溢出实现本练习操作通过缓冲区溢出来实现弹出消息框(MessageBox对话框)。针对windows平台实现缓冲区溢出,该实验实现溢出的方式及流程具有着一定的通用性。我们需要开发实现两部分内容:一部分是漏洞程序overflow,该程序通过memcpy函数实现缓冲区溢出(添加shellcode的代码到缓冲区中,使缓冲区溢出),当然你也可以通过其它函数实现溢出。另一部分内容则是生成shellcode,shellcode是程序溢出后欲执行的指令代码,如通过shellcode实现程序溢出后弹出对话框等功能。对照图22-2-1,在程序正常执行时,memcpy函数被执行完毕后,指令指针会返回至ret地址处,继续执行memcpy函数调用处的后续指令;同时,执行完ret指令后ESP指针也会指向堆栈原始区(调用memcpy函数前一时刻的堆栈分布)。因此,我们可以将溢出代码shellcode存在堆栈原始区,而剩下的工作就是在memcpy执行ret返回时让EIP指针指向原始区(也就是ESP指针指向的地址)即可。如何通过ret返回地址确定此时的堆栈ESP指针指向呢?在这里采用的方法是通过跳转指令“jmpesp”(无条件跳转至esp指向处执行)。通过在用户地址空间中查找到包含有“jmpesp”指令的存储地址,用该地址覆盖ret返回地址就可以了。在具体实现时,我们通过三个步骤完成缓冲区溢出:(1)编写前导码。所谓前导码就是用于覆盖局部变量到ret返回地址之间的堆栈空间(不包括ret返回地址空间)的指令码。前导码仅是用于填充堆栈,所以其内容不受限制。我们需要在实际的调试中来确定前导码的大小。「说明」cl、gcc等诸多C编译器在为局部变量申请内存空间时,经常要多出若干字节。(2)查找jmpesp指令地址。用”jmpesp”指令的地址覆盖ret,就可以在memcpy执行返回后,让CPU执行跳转指令,所以首要解决的是在用户空间中找到含有“jmpesp”指令的地址。通过VC++6.0的反汇编功能得到“jmpesp”指令的机器码为0xFFE4。利用FindJmpesp工具进行指令查找,确定一个含有“jmpesp”指令的内存地址。「注」在用户地址空间中会存在多个包含有jmpesp指令的地址。(3)shellcode功能体。shellcode功能体实现了溢出后主要的执行功能,如创建超级用户,提升用户权限等。在这里我们通过自定义指令来实现弹出用户对话框。1.编写前导码单击工具栏“VC6”按钮,启动VC++6.0。选择“File”|“OpenWorkspace…”加载工程文件“C:\ExpNIS\NetAD-Lab\Projects\OverFlow\Mission1\overflow.dsw”,该工程包含两个项目,overflow和CreateShellcode项目,建议在debug版下进行开发调试。将overflow项目设置为启动项目(SetasActiveProject),该项目仅有一个源文件overflow.c,在此源文件中提供了部分代码,注释的地方需要你根据实际调试结果来填写。程序中提供了一个超长前导码,你需要对程序进行调试来确定实际需要的前导码长度。调试过程如图22-2-2所示。实验结果及截图:设置断点:遇到ret返回指令:执行ret指令之后跳转到49484746地址处:0x46,0x47,0x48,0x49被替换,需要替换成JMPESP指令地址:在图22-2-2中可以看出,0x49484746四字节覆盖了ret返回地址,请根据调试结果重新确定shellcode指令集长度,确定ret返回地址能够被前导码的后续4字节覆盖。2.查找jmpesp指令地址我们需要在用户地址空间中找到包含有jmpesp指令(机器码为0xFFE4)的地址。运行FindJmpesp工具,选取一个地址追加到shellcode尾(追加填加地址时注意数组高字节对应地址高位),所选jmpesp指令地址是0x77e424da。跟踪调试程序,确定在memcpy执行返回时jmpesp指令是否被执行。调试过程如图22-2-3所示。「说明」可以在shellcode尾部继续追加空指令(0x90,空指令不进行任何操作),这样便于确定执行jmpesp后指令指针的指向。实现结果及截图:在cmd下查找JMPESP指令的地址:将查找到得JMPESP地址写入shellcode[],并在后边添加0x90空指令用于调试:即将要执行ret返回指令:执行到jmpesp指令处:进入jmpesp指令中执行(我们想要执行jmpesp指令跳转到shellcode程序):从图22-2-3可以看出,在jmpesp指令执行完毕后,指令指针紧接着执行了3个空指令,而空指令是追加在shellcode尾部的。所以我们下一步所要做的工作就是将实现弹出对话框的指令码追加至shellcod中jmpesp指令地址的后面。3.生成实现弹出对话框的指令码我们最终的目的是要通过缓冲区溢出实现弹出消息对话框,而这些功能都应该在shellcode得以实现。通过在shellcode中调用MessageBoxAAPI函数,并确定好MessageBoxA所需的4个参数:窗体句柄、标题显示、内容显示和风格即可以实现弹出指定内容的对话框。根据WindowsAPI文档,MessageBoxA依赖于user32.lib,也就是说它位于user32.dll动态链接库中。单击工具栏“Depends”按钮,启动Depends工具,Depends打开应用程序C:\ExpNIS\NetAD-Lab\Tools\OverFlow\Mission1\overflow_win.exe,可以发现它将加载user32.dll。然后寻找MessageBoxA函数的内存位置。具体操作如图22-2-4所示。(1)在左侧Module树状视图中选中“USER32.DLL”节点;(2)在右侧导出函数列表视图中遍历Function属性列,查找函数“MessageBoxA”(序号480);(3)在下侧Module列表视图中遍历Module属性列,查找模块“USER32.DLL”。在这里的user32.dll中,MessageBoxA(ASCII版本)函数的偏移量(EntryPoint)为0x0003D8DE。User32.dll(Module)在内存中的起始地址(Base)为0x77E10000。将两者相加即可得到MessageBoxA函数的绝对内存地址。所以我们需要在汇编代码中正确设置堆栈并调用MessageBoxA函数的绝对内存地址,该地址为0x0003D8DE+0x77E10000=0x77E4D8DE。另外还需要调用执行函数ExitProcess(位于KERNEL32.dll中),其目的就是在单击弹出框“确定”按钮后程序自动退出,函数ExitProcess的绝对内存地址0x00013039+0x7c800000=0x7c813039。在overflow工程中将Createshellcode项目设置为启动项目,该项目仅有一个源文件Createshellcode.c,在此源文件中提供了全部的代码及注释说明。代码的主体部分是用汇编语言实现的,其功能就是在实现了弹出对话框后自动退出程序。将函数MessageBoxA和ExitProcess的绝对内存地址填写到指定位置。在理解了Createshellcode.c中的汇编部分代码后,就可以利用VC++6.0反汇编功能获取代码字节,调试过程如图22-2-5所示。将代码字节以十六进制数据形式继续追加到shellcode尾。重新编译执行。实验结果及截图:打开C:\ExpNIS\NetAD-Lab\Tools\OverFlow\Mission1\overflow_win.exe:寻找MessageBoxA函数的入口地址,查找到EntryPoint为0x0003D8DE:查找MessageBoxA函数的起始地址(Base)为0x77E10000:寻找执行函数ExitProcess(位于KERNEL32.dll中)的入口地址,查找到EntryPoint为0x00013039:查找ExitProcess函数的起始地址(Base)为0x7C800000:填写绝对地址到源文件Createshellcode.c中:在shellcode尾添加代码:任务二定位参数地址实现缓冲区溢出一.溢出程序演示(1)进入实验平台,单击工具栏“演示目录”按钮,进入实验目录。进入Mission2目录,该目录中有三个文件:OverFlowClient.exe该文件是执行体文件,功能是新建Administrators组用户jlcss,用户密码1234。CreateShellCode.exe该文件是shellcode生成文件,功能是从OverFlowClient.exe文件中提取功能代码,并最终生成完整的shellcode.shc文件。OverFlowServer.exe该文件是漏洞溢出文件,功能是加载shellcode.shc文件,并实现通过缓冲区溢出完成新建Administrators组用户jlcss。(2)执行OverFlowClient执行OverFlowClient文件,当出现“ShellCode执行完毕,请按回车退出”提示信息时,表明程序已被成功执行,退出程序。右键单击“我的电脑”,选择“管理”进入“计算机管理”,依次选择“本地用户和组”|“用户”,查看右侧“jlcss”用户信息及其隶属组。删除jlcss用户。程序已被成功执行:“jlcss”用户信息及其隶属组:删除jlcss用户:(3)执行CreateShellCode执行CreateShellCode文件,当出现“Shellcode指令集生成完毕,请按回车退出”提示信息时,表明程序已被成功执行,并且shellcode.shc文件已成功生成。右键单击生成的shellcode.shc文件,使用“UltraEdit-32”打开,查看shellcode指令码。这些指令码就是CreateShellCode从OverFlowClient.exe中提取出来的功能码。退出UltraEdit-32。执行CreateShellCode文件,shellcode.shc文件成功生成:shellcode指令码:(4)执行OverFlowServer执行OverFlowServer.exe,当出现“溢出成功!请按回车键退出”提示信息时,表明程序已被成功执行,并且缓冲区溢出操作成功。再次打开“计算机管理”查看系统用户jlcss信息。OverFlowServer.exe就是加载了shellcode.shc文件,在缓冲区溢出后执行了其中的指令码。执行OverFlowServer.exe:OverFlowServer.exe就是加载shellcode.shc文件,生成用户jlcss成功:二.溢出实现「注」进行此操作步骤前,删除jlcss用户。1.进入工程单击工具栏“VC6”按钮,启动VC++6.0。选择“File”|“OpenWorkspace…”加载工程文件“C:\ExpNIS\NetAD-Lab\Projects\OverFlow\Mission2\OverFlowServer.dsw”。该工程包含三个项目:CreateShellCode、OverFlowClient和OverFlowServer。项目功能说明见源文件。2.生成shellcode功能体(1)首先设置OverFlowClie
本文标题:练习二-缓冲区溢出
链接地址:https://www.777doc.com/doc-7112028 .html