分享
 
 
 

Heap/BSS溢出机理分析

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

作者:lyc125@sina.com

[前言: ]

[ 这篇文章主要是基于w00w00发表的: ]

[w00w00 on Heap Overflows]

[By: Matt Conover & w00w00 Security Team ]

[-----------------------------------------------------------------------]

[Copyright (C) January 1999, Matt Conover & w00w00 Security Development]

[ 也补充了一些程序和自己的想法.]

[ 非常感谢Matt Conover给予的热情帮助. ]

[ (Thank Matt for his great work and help) ]

[ 你可以从下面的地址获取原文:]

[ http://http://www.w00w00.org/articles.html]

[ 由于时间较紧,疏漏之处难免,任何意见和建议请发给warning3@hotmail.com ]

虽然基于Heap(堆)/BSS的溢出现在是相当普遍的,但并没有多少介绍它的资料。

本文将帮你理解什么是Heap溢出,也介绍了几种常用的攻击方法,同时给出了一些可

能的解决方案。阅读本文,您需要了解一些汇编,C语言以及堆栈溢出的基本知识。

一.为什么Heap/BSS溢出很重要?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

堆栈溢出的问题已经广为人知,越来越多的操作系统商家增加了不可执行堆栈的补

丁,一些个人也提供了自己的补丁,象著名的Solar Designer提供的针对Linux的不可

执行堆栈的kernel patch(目前已经推出了用于2.2.13内核的patch),也有一些人开发

了一些编译器来防止堆栈溢出,象Crispin Cowan等开发的StackGuard等等。这些方法

都一定程度上可以减少由堆栈溢出导致的安全问题,但是并却不能防止Heap/BSS的溢出。

在大多数的操作系统中,Heap和BSS段都是可写可执行的。这就使得Heap/BSS的溢出成

为可能。

大部分的基于heap的溢出都是不依赖于系统和硬件结构的,这将在后面进一步介绍。

二.一些概念

~~~~~~~~~~~

一个可执行的文件(比如常见的ELF--Executable and Linking

Format格式的可执行

文件)通常包含多个段,比如:PLT(过程连接表),GOT(全局偏移表),init(包含在初始化

时执行的指令),fini(包含程序终止时要执行的指令),以及ctors和dtors(包含一些全

局构造指令和析构指令)

所谓HEAP,就是由应用程序动态分配的内存区。在这里,"由应用程序"来分配是值得特别注

意的,因为在一个好的操作系统中,大部分的内存区实际上是在内核一级被动态分配的,而

Heap段则是由应用程序来分配的。它在编译的时候被初始化。

BSS段包含未被初始化的数据,在程序运行的时候才被分配。在被写入数据前,它始终保持

全零(至少从应用程序的角度看是这样的)

在大部分的系统中,Heap段是向上增长的(向高址方向增长)。因此,当我们说"X在Y的

下面"时,就是指"X的地址低于Y的地址"。

注意:下面提到的"基于heap的溢出"既包含HEAP段的溢出,也包含BSS段的溢出。

三.Heap/BSS溢出攻击

在这一部分中我们将介绍几种不同的利用Heap/BSS溢出的方法。大部分的例子都是针对

x86

Unix系统的。做一些适当的改变,也可以用于DOS和Windows系统。我们也介绍了几种专

门针对DOS/Windows的攻击方法。

注意:

在本文中,为了简单起见,我们使用了精确的偏移量。偏移量必须与实际的值相等,攻

击程序才能工作。当然你也可以象通常的堆栈攻击方法那样,通过提供多个返回地址及插入

空指令等方法以增加成功的机率。

下面的这个例子是给那些不熟悉Heap溢出的人看的,我会做一些简单的解释:

-----------------------------------------------------------------------------

/* 演示在heap段(已初始化的数据)发生的动态缓冲区溢出*/

#include

#include

#include

#include

#define BUFSIZE 16

#define OVERSIZE 8 /* 我们将覆盖buf2的前OVERSIZE个字节 */

int main()

{

u_long diff;

char *buf1 = (char *)malloc(BUFSIZE), *buf2 = (char *)malloc(BUFSIZE);

diff = (u_long)buf2 - (u_long)buf1;

printf("buf1 = %p, buf2 = %p, diff = 0x%x (%d)bytes\n", buf1, buf2,

diff, diff);

memset(buf2, 'A', BUFSIZE-1), buf2[BUFSIZE-1] = '\0';/*

将buf2用'A'填充 */

printf("before overflow: buf2 = %s\n", buf2);

memset(buf1, 'B', (u_int)(diff + OVERSIZE)); /*

用diff+OVERSIZE个'B'填充buf1 */

printf("after overflow: buf2 = %s\n", buf2);

return 0;

}

-----------------------------------------------------------------------------

当我们运行它后,得到下面的结果:

[warning3@testserver basic]$ ./heap1 8

buf1 = 0x8049858, buf2 = 0x8049870, diff = 0x18 (24)bytes

before overflow: buf2 = AAAAAAAAAAAAAAA

after overflow: buf2 = BBBBBBBBAAAAAAA

我们看到buf2的前8个字节被覆盖了。这是因为往buf1中填写的数据超出了它的边界进入了

buf2的范围。由于buf2的数据仍然在有效的heap区内,程序仍然可以正常结束。另外我们

可以注意到,虽然buf1和buf2是相继分配的,但他们并不是紧挨着的,而是有8个字节的间

距,这个间距可能随不同的系统环境而不同。

buf1 间距buf2

覆盖前:[xxxxxxxxxxxxxxxx][xxxxxxxx]低址 -----------------------------------高址覆盖后:[BBBBBBBBBBBBBBBB][BBBBBBBB][BBBBBBBBAAAAAAA]注意:一个阻止heap溢出的可能的方法就是在heap段的所有变量之间放一个"canary"值(就象StackGuard中所做的那样),若这个值在执行中被改变,就认为发生了溢出。为了解释BSS段的溢出,我们来看下面这个例子:-----------------------------------------------------------------------------/* 演示在BSS段(未被初始化的数据)的静态缓冲区溢出 */#include#include#include#include#include#define ERROR -1#define BUFSIZE 16int main(int argc, char **argv){u_long diff;int oversize;static char buf1[BUFSIZE], buf2[BUFSIZE];if (argc{fprintf(stderr, "Usage: %s\n", argv[0]);fprintf(stderr, "[Will overflow static buffer by]\n");exit(ERROR);}diff = (u_long)buf2 - (u_long)buf1;printf("buf1 = %p, buf2 = %p, diff = 0x%x (%d) bytes\n\n",buf1, buf2, diff, diff);memset(buf2, 'A', BUFSIZE - 1), memset(buf1, 'B', BUFSIZE - 1);buf1[BUFSIZE - 1] = '\0', buf2[BUFSIZE - 1] = '\0';printf("before overflow: buf1 = %s, buf2 = %s\n", buf1, buf2);oversize = diff + atoi(argv[1]);memset(buf1, 'B', oversize);buf1[BUFSIZE - 1] = '\0', buf2[BUFSIZE - 1] = '\0';printf("after overflow: buf1 = %s, buf2 = %s\n\n", buf1, buf2);return 0;}-----------------------------------------------------------------------------当我们运行它后,得到下面的结果:[warning3@testserver basic]$ ./heap2 8buf1 = 0x8049874, buf2 = 0x8049884, diff = 0x10 (16) bytesbefore overflow: buf1 = BBBBBBBBBBBBBBB, buf2 = AAAAAAAAAAAAAAAafter overflow: buf1 = BBBBBBBBBBBBBBB, buf2 = BBBBBBBBAAAAAAA和heap溢出类似,buf2的前8个字节也被覆盖了。我们也可以注意到,buf1和buf2是紧挨着的,这意味着我们可以不用猜测buf1和buf2之间的间距.buf1buf2覆盖前:[BBBBBBBBBBBBBBBB]低址 ----------------------高址覆盖后:[BBBBBBBBBBBBBBBB][BBBBBBBBAAAAAAA]从上面两个简单的例子,我们可以应该已经了解Heap/BSS溢出的基本方式了。我们能用它来覆盖一个文件名,口令或者是保存的uid等等...下面这个例子演示了一个指针是如何被覆盖的:-----------------------------------------------------------------------------/* 演示在BSS段(未被初始化的数据)中的静态指针溢出 */#include#include#include

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有