近年来,安全问题成为愈发重要的问题,以堆栈溢出为代表的缓冲区溢出成为最普遍的安全漏洞。历史上最著名的缓冲区溢出攻击可能要算是1988年11月2日的MorrisWorm所携带的攻击代码了。这个因特网蠕虫利用了fingerd程序的缓冲区溢出漏洞,给用户带来了很大危害。此后,越来越多的缓冲区溢出漏洞被发现。最近学了一门信息安全的课,今天就来简单说一下Linux下缓冲区的溢出的简单原理以及这种溢出的简单对策。
说到缓冲区溢出,首先要说一下Linux下进程在内存中的组织形式。Linux环境下,进程分为三部分,文本区域,数据区域和堆栈区域。文本区域包括代码和一些只读数据,文本区域是只读的,任何对于文本区域的写操作都会引起段错误。数据区域包括初始化的数据和未初始化的数据,其中静态数据就在文本区域。堆栈区一般存放局部变量,函数实参,函数返回地址等。缓冲区溢出攻击主要是利用堆栈区的地址关系,用一些无用的字符串来使一些局部变量越界,掩盖真正的返回地址,从而让函数不能正确返回。后来发展为让函数返回到一个黑客预先写好的恶意代码我们称之为shellcode的地址,从而控制函数的执行流,执行一些恶意功能。所以堆栈区是我们的主要研究部分,在以下几个部分会详细介绍,下图为进程的组织形式:
/------------------\ 内存低地址
| |
| 文本 |
| |
|------------------|
| (已初始化) |
| 数据 |
| (未初始化) |
|------------------|
| |
| 堆栈 |
| |
\------------------/ 内存高地址