缓冲溢出是一个普遍的编程错误。存在于任何操作系统中。它能够造成极其严重的安全问题。系统很容易被入侵。
先说说程序是在内存是如何组织和运行的。
不同结构体系的计算机,不同的操作系统,程序在内存的组织是不一样的。我主要讨论x86系列中C程序在内存组织
代码
初始化数据
|
堆(向下生长)
|
|
堆栈(向上生长)
当分配一数据,有三种方式,1,静态全局变量(初始化数据)。 2。动态从堆分配(malloc, new)。3.动态从堆栈分配。
这3种方式都有可能导致缓存溢出。其中以第三种最为致命。
下面看看这段程序
function
foo(int a, int b)
{
char c[256]
for(inti=0;i<512;i++)
c(i)=i;
}
这程序中,
数组c是动态从堆栈分配的。在编译过程中,编译器在这个函数中加了一段初始化代码。从当前堆栈中分配一段内存给数组c使用。运行中,其堆栈组织如下
{
c []
.....
...
...
..
i
控制连接纪录(control link record)
返回地址
a
b
}
不幸的是,有些程序员忽略了对输入数据的边界检查。而使用了一些不做边界条件检查的函数。如strcpy,
strcat,sprintf等等。造成缓存溢出。说道这里,不禁想起java,
java确实一个很安全的程序。它对所有的数组都会先做边界检查。我以上说的主要针对c/c++的。而大多数应用程序却是由C写的。
通过精心构造数据,就可以覆盖掉原来的返回地址。甚至可以让返回地址指向我们插入的程序。从而实现运行我们指定代码的目的。比如使用这类输入
[aaaaaaaa.....aaaaa][返回地址][要执行的代码。。。], 有时系统会对过滤掉特殊字符,这时就要做些伪装工作。
缓存溢出分为本地溢出和远程溢出。。。。
本地溢出通过运行程序来提升自己的权限。
2000/nt里就是拿到admin,unix里就是拿到root. 缺点就是要有个本地账号。。nt不打after
sp6的补丁的sp6版,依然有程序能拿到admin。unix这类漏洞更多了。
远程溢出就简单了,你不一定要有本地账号就可以侵入系统。原来有个IiShack就臭名昭著。很倒的是,现在原来做黑客程序的现在都摇身一变成了安全公司拉。
在[晕倒死]下,如弹出一个窗口,出现以下信息“XXX.dll caused an invalid page in module YYY
at memory xxxx:bbbb00000”,多半是出现了内存溢出错误。
如果你能确定是一串输入造成的溢出,那就发现了一个bug拉。你可以414用“aaaaaaaaaaaa..."作为输入,前面出错信息中的地址为
xxxx:61616161,恭喜,你发现了一个堆栈溢出的错误了。a的16进制的值是61
接下来的工作就是繁琐并且需要耐心的定位工作。。。跟踪一堆dll的调用不是件轻松的活。最后就是构造出shellcode,
并用编写个简单的程序完成破解工作。。。让每个菜鸟都能体会到其中的乐趣。。。。嗬嗬。。
今天就倒这里。。
感兴趣的可以找些red
code的资料看看。它就是个典型缓冲溢出的案例。网上有原程序分析。。。
如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐
jill.jiang@amt.com.cn | 021-51096826-112 |
在线联系