发表在著名hack杂志Phrack上的文章 Smashing The Stack For Fun And Profit 第一次具体详细描述了如何实施buffer overflow[缓存溢出]攻击[其作者就是著名的Elias Levy]。

Basic Idea

Buffer Overflow的主要思路是通过向一个缓存空间填充一个超越其大小的数据使其溢出,并达到修改函数返回地址RET的目的,从而改变函数的执行流程使其执行预先定义的恶意代码进行攻击。

文章中描述的攻击是基于linux系统和Stack的,使用C++语言。基于Stack的原因是其内存是向低地址方向增长,所以才有可能会overflow函数返回地址,如果是基于heap的那么其内存是向高地址方向增长就不会overflow函数RET。

Shell Code

文中介绍了一个名为Shell Code的代码,通过buffer overflow的方式来获得系统的root权限,当然如果能够获得root权限,基本上就是控制了该台计算机。其实现原理是通过buffer overflow使函数返回地址被修改为指定执行代码的地址,该指定代码为shell code来进行shell操作,因为一般C++程序拥有root权限,从C++程序执行的shell也会拥有root权限。这里有两个trick的地方需要注意,一是如何定位到指定运行的程序,二是如何定位需要进行overflow的buffer。第一个问题的解决方案是使用JMP和CALL结合的方式,这两个指令,可以通过相对地址的方式来定位运行的程序。第二个问题并没有一个一劳永逸的方式,只能靠猜,但是可以通过填充NOP指令方式来提高猜中概率。这个设计比较巧妙,因为NOP是一个可执行的但是不会执行任何操作的空指令,所以在shell code前填充一些NOP,那么虽然没有准确猜到地址,只要猜到这些NOP那么程序就会继续执行下去直到shell code

Defense

解决方案有很多,其中一个比较直观的解决方案是,内存空间的随机化。因为buffer overflow的攻击方式一大限定条件就是几个重要变量的内存地址需要有一定的位置关联,如果这个条件被打破那么适用buffer overflow几乎就是不太可能的了。