如何编写自己的缓冲区溢出利用程序?

2008-04-09 04:00:00来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

如何编写自己的缓冲区溢出利用程序?


本文出自:http://xfocus.org/ 作者:黑猫(virtualcat@hotmail.com)


内容: 本文主要讲解有关Buffer Overflow的原理, 以及结合实战范例介绍Linux和Solaris下的漏洞利用.
本文并不介绍如何编写shell code.

要求: 读者要有一点C和汇编语言基础.

目标: 希望本文能够尽量做到通熟易懂,使得稍有计算机基础知识的朋友看后能够亲自动手写自己的Exploit
如果你觉得自己对这些都懂了, 就请不要再往下看了.


第一部份 概述篇

1. Buffer overflow是如何产生的?
所谓Buffer overflow, 中文译为缓冲区溢出. 顾名思意, 就是说所用的缓冲区太小了, 以至装不下
那么多的东西, 多出来的东西跑出来了. 就好象是水缸装不了那么多的水, 硬倒太多会溢出来一样;)
那么, 在编程过程中为什么要用到buffer(缓冲区)呢? 简单的回答就是做为数据处理的中转站.

2. UNIX下C语言函数调用的机制及缓冲区溢出的利用.
1) 进程在内存中的影像.
我们假设现在有一个程序, 它的函数调用顺序如下.
main(...) -> func_1(...) -> func_2(...) -> func_3(...)
即: 主函数main调用函数func_1; 函数func_1调用函数func_2; 函数func_2调用函数func_3

当程序被操作系统调入内存运行, 其相对应的进程在内存中的影像如下图所示.

(内存高址)
--------------------------------------
| ...... | ... 省略了一些我们不需要关心的区
--------------------------------------
| env strings (环境变量字串) | \
-------------------------------------- \
| argv strings (命令行字串) | \
-------------------------------------- \
| env pointers (环境变量指针) | SHELL的环境变量和命令行参数保存区
-------------------------------------- /
| argv pointers (命令行参数指针) | /
-------------------------------------- /
| argc (命令行参数个数) | /
--------------------------------------
| main 函数的栈帧 | \
-------------------------------------- \
| func_1 函数的栈帧 | \
-------------------------------------- \
| func_2 函数的栈帧 | \
-------------------------------------- \
| func_3 函数的栈帧 | Stack (栈)
...................................... /
| | /
...... /
| | /
...................................... /
| Heap (堆) | /
--------------------------------------
| Uninitialised (BSS) data | 非初始化数据(BSS)区
--------------------------------------
| Initialised data | 初始化数据区
--------------------------------------
| Text | 文本区
--------------------------------------
(内存低址)

这里需要说明的是:
i) 随着函数调用层数的增加, 函数栈帧是一块块地向内存低地址方向延伸的.
随着进程中函数调用层数的减少, 即各函数调用的返回, 栈帧会一块块地
被遗弃而向内存的高址方向回缩.
各函数的栈帧大小随着函数的性质的不同而不等, 由函数的局部变量的数目决定.
ii) 进程对内存的动态申请是发生在Heap(堆)里的. 也就是说, 随着系统动态分
配给进程的内存数量的增加, Heap(堆)有可能向高址或低址延伸, 依赖于不
同CPU的实现. 但一般来说是向内存的高地址方向增长的.
iii) 在BSS数据或者Stack(栈)的增长耗尽了系统分配给进程的自由内存的情况下,
进程将会被阻塞, 重新被操作系统用更大的内存模块来调度运行.
(虽然和exploit没有关系, 但是知道一下还是有好处的)
iv) 函数的栈帧里包含了函数的参数(至于被调用函数的参数是放在调用函数的栈
帧还是被调用函数栈帧, 则依赖于不同系统的实现),
它的局部变量以及恢复调用该函数的函数的栈帧(也就是前一个栈帧)所需要的
数据, 其中包含了调用函数的下一条执行指令的地址.
v) 非初始化数据(BSS)区用于存放程序的静态变量, 这部分内存都是被初始化为零的.
初始化数据区用于存放可执行文件里的初始化数据.
这两个区统称为数据区.
vi) Text(文本区)是个只读区, 任何尝试对该区的写操作会导致段违法出错. 文本区
是被多个运行该可执行文件的进程所共享的. 文本区存放了程序的代码.

2) 函数的栈帧.
函数调用时所建立的栈帧包含了下面的信息:
i) 函数的返回地址. 返回地址是存放在调用函数的栈帧还是被调用函数的栈帧里,
取决于不同系统的实现.
ii) 调用函数的栈帧信息, 即栈顶和栈底.
iii) 为函数的局部变量分配的空间
iv) 为被调用函数的参数分配的空间--取决于不同系统的实现.

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:RSA加密实例分析

下一篇:一种简单注册码加密的例子分析