WEB开发网
开发学院软件开发VC 缓冲区溢出攻防 阅读

缓冲区溢出攻防

 2010-02-19 20:33:10 来源:WEB开发网   
核心提示:防御措施有攻就有防,缓冲区溢出危害虽大,缓冲区溢出攻防(6),防起来却不难,最简单有效的方法莫过于写代码时小心一点了,我只是想更深入的和大家讨论一下缓冲区溢出问题,如果您有其他看法,比如在victim中,如果我们多传递给GetComputerName一个参数来标志缓冲区的长度

防御措施

有攻就有防,缓冲区溢出危害虽大,防起来却不难。最简单有效的方法莫过于写代码时小心一点了。比如在victim中,如果我们多传递给GetComputerName一个参数来标志缓冲区的长度,并在GetComputerName进行检查,那么悲剧就能避免了。

如果你比较懒,不想做这些琐事,编译器也能帮你。从vs.net开始,编译器支持了一个新的选项:/GS。打开它后,编译器就会检查每一个函数是否有发生溢出的可能。如果有,它就向这个函数中插入检测代码,比如前面的ShowComputerName经过处理后就会变成类似下面的样子。其中__security_cookie是编译器插入程序的一个全局变量,进程启动时,会根据大量信息使用哈希算法对它进行初始化,所以它的值具有很好的随机性(具体的初始化过程请见“seccinit.c”)。

void ShowComputerName(SOCKET sck)
{
  DWORD_PTR cookie = __security_cookie; //编译器插入的代码
   char szComputer[16];
  RecvComputerName(sck, szComputer);
  printf(szComputer);
  __security_check_cookie(cookie); //编译器插入的代码
}

如代码所示,进入ShowComputerName后,程序所作的第一件事就是把__security_cookie 的值复制一份到局部变量cookie中。注意:cookie是ShowComputerName的第一个局部变量,所以它在栈中的位置是在返回地址和其它局部变量之间,如果拷贝字符串到szComputer中时发生了缓冲区溢出,cookie肯定先于返回地址被覆盖,而它的新值几乎没有可能继续与__security_cookie相同,因而函数最后的__security_check_cookie就可以使用下面的代码检测溢出了(这段代码其实不是给x86 cpu用的,但它更易理解,且逻辑上没有区别,具体请见“secchk.c”)。

void __fastcall __security_check_cookie(DWORD_PTR cookie)
{
  /* Immediately return if the local cookie is OK. */
  if (cookie == __security_cookie)
    return;
  /* Report the failure */
  report_failure();
}

整个实现非常之简洁高效,不信就请试一下看看效果。但这种机制也有不足,一是检测到溢出后就会使程序终止运行;二是不能检测所有的溢出,还有漏网之鱼。具体就请参考相关资料和做实验吧。

谁之过

据说已发现的安全漏洞中有50%以上根缓冲区溢出有关,我们姑且不管这一数字是否准确,但它确实说明缓冲区溢出给计算机世界造成的危害的严重性。而人们也普遍认为是因为程序员的“不小心”才会有这么多的漏洞。但责任真的都应该程序员来负吗?我觉得不然。首先,x86 cpu的设计就有一些问题:函数的返回地址和普通数据放在同一个栈中,给了攻击者覆盖返回地址的机会;而栈从高地址向低地址的增长方向又大幅提高了这一几率。其次,c标准库设计时对内存占用和执行效率的斤斤计较又造就了许多类似strcpy的危险函数。当然,我并不想指责它们的设计者,我也没有资格,我只是想更深入的和大家讨论一下缓冲区溢出问题。如果您有其他看法,欢迎和我交流。

本文配套源码

上一页  1 2 3 4 5 6 

Tags:缓冲区 溢出 攻防

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接