通过覆盖__atexit进行缓冲区溢出攻击 |
| 更新时间:2007-11-22 0:58:47 |
责任编辑:流火 |
|
|
原作者: Pascal Bouchareine <pb@hert.org> 原文: <<__atexit in memory bugs - specific proof of concept with statically linked binaries and heap overflows>> 翻译整理:alert7 <alert7@21cn.com> 主页: http://www.xfocus.org / 时间: 2001-7-19
译者注:这片文章可能很早就出来了,我看国内也没有人介绍,干脆就 翻译出来一块儿共享吧,如有什么错误的地方,欢迎指正。 mailto:alert7@21cn.com
介绍: 本文讨论了类似通过覆盖.dtors进行缓冲区溢出攻击的技术。归根结底 是想方设法改变程序的执行流程,使之最终执行我们想要执行的代码。本文 假设读者熟悉普通的缓冲区溢出技术。
鸣谢: 感谢Andrew R. Reiter看了这片文档,纠正一些错误。
内容:
I. atexit()的基本知识 II. atexit()的执行 III. Exploitation的概念 IV. Eggshell的定位 V. 一个exploit的例子
I. atexit()基本知识
先让我们看看手册:
NAME atexit - 注册一个在exit时候被调用的函数
SYNOPSIS #include <stdlib.h>
int atexit(void (*function)(void))
DESCRIPTION atexit()函数注册一个给定的函数,该函数在程序exit时候被调用 (不管是通过exit(3)或者还是通过从程序的main函数中返回)。 注册的函数是反序被调用的;没有参数。至少32个函数总是可以被注册 的,只要有充分的分配的内存,更多的函数也是允许的。
看看下面程序的基本指令:
char *glob;
void test(void) { printf("%s", glob); }
void main(void) { atexit(test); glob = "Exiting.\n"; } 当执行时,应该在标准输出上显示"Exiting" .
II. atexit()的执行
atexit是做为libc函数导出的。 执行过程使用了一个静态的atexit结构,该结构包含了那些在退出时候被 调用的函数的一个数组,在调用atexit函数的时候会插入一个结构(我们 将称它为"fns"),在fns中有一个变量保存着下一个空的索引(我们称 它为"ind"),当fns满的时候,一个指针(我们称为next)指向了下一个 被使用的atexit结构.
struct atexit { struct atexit *next; /* next in list */ int ind; /* next index in this table */ void (*fns[ATEXIT_SIZE])(); /* the table itself */ };
当atexit()被调用时,它填充fns[ind],增加ind,这时ind就是下一个在fns中空的索引。 当fns满的时候,一个新的atexit的结构被分配,并且它的next变量指向了最后 被使用的那个。
注意:一般atexit的使用的是不需要next的,它在初始化的时候被设置为 NULL。
1 2 3 下一页 | | |