驱动管家:安全、高效、精准的专业驱动下载站!

什么是缓冲区溢出?缓冲区溢出分析

2018-01-25 18:25:08责编:llp   来源:驱动管家     人气:

缓冲溢出弱点诞生于70年代。Morris Worm(80年代)可以认为是它们的第一次公开应用。从90年代开始,相关的文档,如著名的Aleph1的”Smashing the Stack for Fun and Profit”和代码已经在互联网上公开。

这篇文章是关于某种需要非常重视的主题的系列文章的开始,并且包括了很多的细节;它的目的是解释和阐明非常基本的漏洞类型,即所谓的本地溢出,而且论述了如何编写利用这种漏洞的代码。

为了理解接下来的内容,需要一些C和汇编的知识。虚拟内存,一些操作系统的基本知识例如象一个进程在内存里是如何布局的。你必须知道什么是setuid二进制文件,而且当然你需要至少能够使用UNIX系统。如果你有gdb/cc调试编译的经验,那就非常好了。文档特定在Linux/ix86环境下。细节的不同之处取决于操作系统或者你使用的架构。在接下来的文档里面,将介绍相应的更高级的溢出和shellcode技术。

什么是溢出?

如果你知道C,你肯定知道什么是字符型数组。假设你用C写代码,你应该已经知道数组的基本特性,象:数组拥有同样类型的对象,例如:int,char,float。就像所有的数据结构一样,它们能够被分成是”静态”或者是”动态”。静态变量被填入程序的数据段,然而,动态变量在内存中的可执行程序的堆栈区域分配和重新分配。”基于堆栈”的溢出就在这里发生了,我们在数据结构中填更多的数据,也就是说多于一个数组能够存储的数据,我们忽略许多重要的数据超越这个数组的界限。简单的,拷贝20字节到一个只能存储12字节的数组里。

什么是缓冲区溢出?缓冲区溢出分析

一个Linux ELF格式二进制的存储结构相当的复杂。特别是在ELF (详细内容,在google中搜索”Executable and Linkable Format”)和共享库引入后,它已经变得更加复杂。然而,基本上,每一个进程运行时有3段:

1.文本段,是一个只读部分包括所有的程序指令。对于等同于下面C代码的指令集合将被包括在这段。

for (i = 0; i

2.数据段是初始化了的和未初始化的数据(也被认为是BBS段)所在的块。

if you code;

int i;

the variable is an uninitialized variable, and it'll be stored in

the "uninitialized variables" part of the Data Segment. (BSS)

and, if you code;

int j = 5;

the variable is an initialized variable, and the the space for

the j variable will be allocated in the "initialized variables"

part of the Data Segment.

3.一个被称为”堆栈”的段,在这里动态变量(或者在C里面叫自动变量)被分配和重新分配;并且为函数返回临时存储地址。例如,在下面代码片段中,i变量在堆栈中产生,仅仅在函数返回后,它就消亡了。

int myfunc(void)

{

int i;

for (i = 0; i 如果我们用符号表示堆栈:

0xBFFFFFFF ---------------------

.|

.|

.|

.|

etc |

env/argv pointer. |

argc|

-------------------|

stack|

V|

/ /

\ \

^|

heap|

-------------------|

bss|

-------------------|

initialized data|

-------------------|

text|

-------------------|

shared libraries|

etc. |

0x8000000|-------------------|

_* STACK *_

堆栈在基本术语里面是一个数据结构,你们都可以从你们的数据结构课程记起来。它有同样的基本操作。它是一个LIFO(后进,先出)的数据结构。它的处理过程通过一些特殊的指令象PUSH和POP由CPU直接控制。你PUSH一些数据到堆栈里面,又POP一些其它的数据。不论谁最后到,它将是最先出来的那个。因此,用专业术语说,第一个将被从堆栈中推出来的是最后一个被推进去的。

在CPU中注册的SP(堆栈指针)包括将要从堆栈中推出来的数据地址。不论SP指向最后的数据还是堆栈中最后数据的后面数据是CPU-specific的;然而,我们的目标ix86结构,SP指向堆栈中最后数据的地址。在ix86保护模式(32位/双字)下,PUSH和POP指令在4字节单元中完成。在这里要说的另外一个重要的细节是堆栈向下增长,也就是,如果SP是0xFF,执行PUSH EAX指令后,SP将变成0xFC并且EAX的值将被放到0xFC地址里。PUSH指令将从ESP(回顾一下上面的图)中减去4个字节,并且将推入一个双字到堆栈,放置双字到ESP寄存器所指的地址中。另一方面,POP指令,读取ESP寄存器中的地址,POP掉堆栈地址所指的值,并且加4到ESP(加4到ESP寄存器中的地址)。假设ESP初始化为0x1000,让我们观察下面的汇编代码:

PUSH dword1 ;value at dword1: 1, ESP's value: 0xFFC (0x1000 - 4)

PUSH dword2 ;value at dword2: 2, ESP's value: 0xFF8 (0xFFC - 4)

PUSH dword3 ;value at dword3: 3, ESP's value: 0xFF4 (0xFF8 - 4)

POP EAX ;EAX' value 3, ESP's value: 0xFF8 (0xFF4 4)

POP EBX ;EBX's value 2, ESP's value: 0xFFC (0xFF8 4)

POP ECX ;ECX's value 1, ESP's value: 0x1000 (0xFFC 4)

当堆栈被用做动态变量的临时存储的时候,它被用来存储一些调用存储临时变量函数的地址和在函数间传递参数。而且,当然,这也是邪恶的来场。

EIP寄存器,CALL和RET指令

在每一个机器周期中,CPU查询指令指针寄存器存储中存储的内容(在ix86 32位保护模式中是EIP-扩展指令指针)来知道下一步要执行什么。下一个将要执行的指令地址存储在EIP寄存器中。通常,地址是连续的,意味着下个将要执行的下个指令在内存中比当前指令靠前几个字节。CPU根据当前指令是几个字节长度计算出”靠前的几个字节”,然后把这几个字节值加到当前地址。举个例子,假设当前指令地址是0x8048438。这是写在EIP中的值。因此,CPU执行在内存地址:0x8048438中找到的指令。比方说,是一个PUSH指令:

push 雙

CPU知道一个PUSH指令是1字节长,因此下一个指令将在0x8048439,可能是

mov%esp,雙

在执行PUSH时,CPU将把MOV地址放到EIP中。

好了,我们说将被放到EIP中的值是CPU自身计算出来的。如果我们JMP到一个函数又是什么样子的呢?函数中指令的地址将在内存中的其它地方。它们执行后,CPU是如何知道到哪里继续调用程序执行呢?为了这个目的,在我们JMP到函数前,我们在一个临时寄存器中保存下一个指令地址,比如说在EDX中;并且在从函数返回之前,我们又把EDX中的地址写回EIP。如果我们使用JMP来跳转到函数地址,那将可能实际上是一个非常烦人的工作。

然而,ix86处理器家族给我们提供了两个指令:CALL和RET,使我们的生活简单!CALL指令把”函数返回后下个要被执行的指令”写入堆栈。它PUSH地址到堆栈,并且把函数地址写入EIP。因而,一个函数调用就产生了。另一方面,RET指令从堆栈中POP出”返回地址”,并且把地址写入EIP。因而,我们将从函数安全地返回,而且继续了程序的下一步执行。

让我们看看下面的代码片段:

x = 0;

function(1, 2, 3);

x = 1;

在几个汇编指令运行(x=0)之后,我们需要到function()所在的内存位置。就如我前面所说的,为了实现这一目标,首先我们拷贝返回地址的地址(在这个例子里是x=1的指令地址。)到一些临时空间(可能是一个寄存器)用JMP跳转到函数的地址空间,而且,在函数结束时我们恢复我们将要拷贝到EIP的返回地址。

感谢上帝,所有这些麻烦的操作都由CPU自身通过CALL和RET为我们做了,而你能从上面的篇章中得到相关细节。 一般地,程序堆栈区域能够象这样表示:

_parameter_I____| ESP 8

_parameter II___| ESP 4

_return address_| ESP

Figure X : Stack

ESP,EBP

如我们已经说过的,堆栈同样被用来存储动态变量。动态地,程序请求新的空间时,CPU PUSH一些数据而我们的程序释放一些数据时它就POP一些数据。为了给内存编址,我们使用”相对寻址”。也就是说,我们在我们的堆栈中给数据编址,与一些标准相关。而这个标准就是ESP,它是Extended Stack Pointer首字母缩写。这个寄存器指向堆栈的顶端。考虑这个:

void f()

{

int a;

}

可以看出,在f()函数中,我们为一个名为a的整型变量分配空间。整型变量a的空间将在堆栈中分配。而计算机将引用它的地址作为ESP- 的一些字节。因此堆栈指针对程序执行是非常重要的。若我们调用一个函数呢?这个调用的函数有一个堆栈,它有一些局部变量,意味着它将要利用堆栈指针寄存器。同样地,内部被调用的函数将有局部变量而且它也将需要堆栈指针。

为了克服这个,我们保存老的堆栈指针。就象我们对返回地址所做的那样,我们PUSH老的ESP到堆栈,并且利用另外一个名为EBP的寄存器来引用被调用函数的局部变量。

  • vmware是什么?vmware软件存在允许用户获得权限提升和拒绝服务漏洞

    vmware是什么?vmware软件存在允许用户获得权限提升和拒绝服务漏洞

    描述: BUGTRAQ ID: 28289 CVE(CAN) ID: CVE-2007-5618,CVE-2008-1364,CVE-2008-1340VMWare是一款虚拟PC软件,允许在一台机器上同时运行两个或多个Windows、DOS、LINUX系统。VMWare产品中存在多个安全漏洞

    详情2018-01-23 17:00:10责编:llp   来源:驱动管家     
  • openbsd是什么?openbsd系统有什么漏洞?

    openbsd是什么?openbsd系统有什么漏洞?

    受影响系统:OpenBSD OpenBSD 4 2OpenBSD OpenBSD 4 1OpenBSD OpenBSD 4 0描述:BUGTRAQ ID: 25984CVE(CAN) ID: CVE-2007-5365OpenBSD是一款开放源代码Unix类操作系统。OpenBSD系统的DHCP协议实现上存

    详情2018-01-24 16:40:45责编:llp   来源:驱动管家     
  • 微软浏览器接口有漏洞?ie7浏览器的漏洞说明

    微软浏览器接口有漏洞?ie7浏览器的漏洞说明

    漏洞警告:通过对微软浏览器IE6跨域漏洞的深入研究,我们发现实际上即使在安装了IE7浏览器的操作系统中,也一样存在类似的问题。这个漏洞并不单独存在于IE6中,而是存在于微软提供的浏览器接口中。在微软提供的浏

    详情2018-01-14 15:01:43责编:llp   来源:驱动管家     
  • 手机电池小心充电 充电时间超过十二小时很危险

    手机电池小心充电 充电时间超过十二小时很危险

    近年来手机爆炸致人死伤事件时有发生,这让手机电池的稳定性和安全性成为消费者关注的焦点。手机电池的爆炸都是由手机电池引起。如何选用一块安全可靠的电池,如何正确使用手机电池,降低事故发生呢?在买手机或

    详情2018-01-17 11:34:10责编:llp   来源:驱动管家     
  • 什么是电脑肉鸡?电脑沦为肉鸡有哪些表现?

    什么是电脑肉鸡?电脑沦为肉鸡有哪些表现?

    “肉鸡”在黑客里面的一个专有名词,意思是你的电脑已经完全被黑客所控制,他可以控制你电脑里面的一切资料,甚至是记录你输入的QQ密码,银行密码。同时,他还可以利用你的电脑去攻击其它人的电脑。很多朋友的电

    详情2018-01-22 15:11:47责编:llp   来源:驱动管家     
  • 怎么使用cryptsetup加密u盘?如何在ubuntu里创建一个加密u盘?

    怎么使用cryptsetup加密u盘?如何在ubuntu里创建一个加密u盘?

    首先讲讲保护U盘的重要性笔记本和U盘被盗,是过去几年数据泄露的主要原因之一。然而比起笔记本电脑,人们通常不太重视U盘这个小玩意儿的安全。但是如果罪犯偷窃了一枚价值只有12美元的U盘,也许会让一家公司付出

    详情2018-01-04 12:22:51责编:llp   来源:驱动管家     
  • 什么是rootkit病毒?rootkit病毒的类型及对应措施

    什么是rootkit病毒?rootkit病毒的类型及对应措施

    Rootkits病毒主要分为两大类:第一种是进程注入式Rootkits,另一种是驱动级Rootkits。第一种Rootkits技术通常通过释放动态链接库(DLL)文件,并将它们注入到可执行文件及系统服务进程中运行,阻止操作系统及应用

    详情2018-01-13 11:34:20责编:llp   来源:驱动管家     
  • 破解rar密码有什么方法?可以使用rar password cracker软件破解rar密码

    破解rar密码有什么方法?可以使用rar password cracker软件破解rar密码

    当一个非常重要的RAR文件因为忘记密码无法解压缩时,你是不是就这样抛弃它了呢?当然不是,你可以使用RAR Password Cracker这个软将加密的RAR文件破解出来。安装后运行程序里的RAR Password Cracker Wizard

    详情2018-01-14 14:03:37责编:llp   来源:驱动管家     
  • 网页病毒入侵windows系统有哪些途径?

    网页病毒入侵windows系统有哪些途径?

    网络的流行,让我们的世界变得更加美好,但它也有让人不愉快的时候。比如,当你收到一封主题为“I Love You”的邮件,兴冲冲的双击附件想欣赏一下这封“情书”的时候,却在无意当中成为了病毒的受害者和传播者

    详情2018-01-13 16:51:16责编:llp   来源:驱动管家     
  • 什么是手机病毒?手机病毒怎么传播?

    什么是手机病毒?手机病毒怎么传播?

    手机病毒是病毒的一个分支,虽然其存在只有短短数年,但在将来很可能会随着3G的推广而大量涌现。病毒类型:手机病毒病毒目的:破坏手机系统,狂发短信等手机病毒的始作俑者我用手机的时间很长了,大概在上世纪90

    详情2018-01-07 10:13:29责编:llp   来源:驱动管家