StackGuard 漏洞
发布日期:1999-11-16
更新日期:1999-11-16
受影响系统:Linux
Unix
描述:
StackGuard是一种用来防止堆栈溢出攻击的编译器。由Crispin Cowan及ImmuniX开发小组维护。用它编译的程序可以有效的防止堆栈溢出问题。它的工作原理是在调用函数时,将返回地址压栈后,再将一个随机产生的字也压入堆栈。当函数调用完毕返回时,查看是否这个随机字被修改,若已被改动,则说明有溢出发生。自从1998年1月StackGuard推出以来,还没有发现它有任何的弱点。但不久前Mariusz Woloszyn(emsi@itl.pl)发现在特定的条件下,可以绕过StackGuard的保护机制,可能获得非法的特权。
详细描述:
让我们考虑一下下面这段有弱点的代码:
foo(char * arg) {
char *p = arg; // 有弱点的指针 p
char a[25]; // 这个字符缓冲区可能导致p指针被覆盖
gets(a); // gets()没有长度限制,因而可能导致缓冲区溢出
gets(p);
}
堆栈内容:
地址: AA BB CC DD EE
[a buffer][ p ][ebp][Random Canary][eip]
地址低端 地址高端
为了改变字符型指针p的值,攻击者会首先让a[25]溢出,用一个特定的值来覆盖p。这样p指针就可能指向内存中的任意位置,比如当前栈帧中的返回地址。
地址: AA BB CC DD EE
[shellcode][ EE][ebp][Random Canary][eip]
地址低端 地址高端
当程序继续执行gets(p)的时候,就会将数据存储在该返回地址,从而改变返回地址的值,当该函数返回时,会跳到修改过的地址去执行,就象普通的溢出攻击一样。
地址: AA BB CC DD EE
[shellcode][ EE][ebp][Random Canary][AA]
地址低端 ^ | 地址高端
|_____________________________________|
上述攻击对于随机字堆栈保护机制是有效的。因为这种保护机制假设攻击者的攻击是线形的,即要想覆盖掉返回地址,必须先覆盖随机字。因此对于这种绕过随机字直接修改返回地址的非线形攻击,这种保护机制就无能为力了。
注意:
目前还没有听说有这种漏洞的实例,但带这种弱点程序是很可能存在的。
建议:
新版本的StackGuard 1.21使用了一种新的保护机制:异或随机字。将原来产生的随机字与返回地址进行异或,然后新产生的随机字就与返回地址相关了。具体实现步骤:
* 设置一个激活记录:当调用一个函数时:
1. 压入返回地址
2. 为当前函数获取一个随机字
3. 将随机字与返回地址异或
4. 将异或的结果压栈,储存在返回地址的下面
* 结束一个激活记录:当从函数返回时:
1. 从堆栈中获得随机字
2. 将随机字与返回地址异或
3. 比较异或结果和与当前函数相关的随机字是否相同
通过这种方法,攻击者要修改返回地址,就必须修改随机字。
StackGuard 1.21可以从下列地址获得:
http://immunix.org/downloads.html#sg1.21
浏览次数:8889
严重程度:0(网友投票)