栈粉碎

当缓冲区溢出覆写分配给执行栈内存中的数据时,就会导致栈粉碎(stack smashing)
栈粉碎对程序的可靠性和安全性造成严重的后果。stack段的缓冲区溢出是的攻击装能修改自动变量的值或执行任意的代码

重点:通过前几小节到现在,也就是讲一个字符串操作错误的问题,现在一个字符串操作导致缓冲区溢出成为了可以被攻击的手段了。

还记得2.3小节中判断输入密码是否正确的问题吗?现在来看一下在栈中的情况

当程序从isPasswdOkay()返回时如图2.5.2,栈恢复到原来的状态,程序根据从isPasswdOkay()函数返回的值继续执行。然而Passwd数组只能包含最多11个字符+结尾的空字符,因此程序存在一个安全缺陷,如图2.3.2中运行结果,当我输入超过12个字符的字符串时很明显程序就卡在那儿了,显示程序崩溃了,当然如果只是超出几个字符也行也还能正常运行,但是那也都是不正确的。当超过12个字符时,那么超过部分的字符串将存储在什么地方呢?在这个找中下面还有一个status也是在栈区。

  1. 那如果超过字符将原来status的值覆写会怎么样呢?
  2. 如果将返回main()的返回地址覆写又会怎么样呢?

当然程序要么就崩溃了,要么运行不正确了。还有空子可以钻了,根据《C和C++安全编码》中2.5小节中,超过4字节中使用”j▼*!”字符,程序可跳过2.3小节中15-18行代码直接进入19行执行,这样就能绕过密码保护逻辑直接登录了。每个字符对应了一个十六进制的值:’j’=0x6A, ‘▼’=0x10, ‘*’=0x2A, ‘!’=0x21,组合起来其实也就是一个四字节的地址

注:

  1. 上面’▼’符号实在是找不到,原文跟这个符号不太一样,也没有现实跳过密码直接登录
  2. 微软已经彻底弃用用gets函数,所以不是很好复现

发表评论

电子邮件地址不会被公开。 必填项已用*标注