破坏力依然不可小视 缓冲区溢出攻防
2006-11-07 20:09:59 来源:WEB开发网找到了漏洞,下一步要做的就是分析漏洞来找到具体的攻击方法。我们来看一下ShowComputerName的编译结果,每条c/c++语句下面注释中就是其编译后对应的汇编代码。对这些代码,我要说明两点:①这里使用的是stdcall调用约定,它是windows程序中最常用的调用约定,下文中的示例代码如果没有特别说明都将使用这种约定。有关各种调用约定的含义和区别,请参考相关资料。②因编译器、编译选项的不同,编译结果也可能不一样,后面的攻击代码是根据上面的编译结果编写的,我无法保证它在你的环境中也能正确执行。
我在程序中标注了三个标号,下图从左至右分别是程序执行完三个标号对应的代码后堆栈的状态及esp寄存器的指向,其中每个小格代表一个字,即四字节。
从图中可以看出,当main调用ShowComputerName时,程序会首先将它的参数压栈,然后再将其执行完毕后的返回地址压栈。进入ShowComputerName后,程序再调整esp寄存器,为局部变量分配存储空间。而ShowComputerName返回时执行的“ret 4”指令不仅让程序跳转到返回地址继续运行,还会将返回地址、函数参数从栈中弹出,使栈恢复到调用前的状态。
很明显,如果UNC字符串中的机器名超过了16字节,函数ShowComputerName就会发生缓冲区溢出。为了讲解方便,下面我就开始从攻击者的角度来分析如何构造这个字符串才能让程序执行一些“意外”的代码。
你可能已经发现:函数ShowComputerName的返回地址就存放在“szComputer+16”处。所以,如果我们能把返回地址改成“szComputer+20”,并从地址“szComputer+20”开始填上一些我们需要的指令对应的数据,那么我们就能达到目的了。很高兴你能想到这些,但这是不可能的,因为我们既要根据szComputer来构造字符串,又要在szComputer确定前完成构造完字符串。所以,此路不通,我们必须拐个弯才行。
更多精彩
赞助商链接