可爱的栈溢出

来源:互联网 发布:如何用记事本写java 编辑:程序博客网 时间:2024/05/17 06:04

图文并茂版本,虽然技术老了点,但是很适合对Stack Overflow感兴趣的朋友,

嗯。。。适合初学者,对于正在成为牛和已经成为牛的家伙们,请当没有该文档,

谢谢牛们不看这篇文档,谢谢-_-~

PDF Version Download:

http://www.cisrg.cn/forum/viewtopic.php?id=2397


可爱的栈溢出

 

现今的概念开始明确起来,以前的堆栈溢出先被明确为缓冲区溢出,又再次的被明确为栈溢出,其实这种漏洞类型也很明显的体现了堆和栈的区别。

记得在刚开始学C的时候,也总是堆栈不分,也喜欢很酷的把基于栈的缓冲区溢出漏洞,呼喊成堆栈溢出。单实际上,堆和栈是完全不同的东西。好了,废话少说了,我们来看下栈溢出。

缓冲区溢出漏洞,是由于大的缓冲区数据覆盖了小的缓冲区数据所致;从Intel架构来考虑,由于前期给变量分配的内存空间比较小,而把一个大于该变量内存空间的数据复制到了该变量的内存中,从而导致覆盖掉了前面保存的栈数据,触发缓冲区溢出漏洞;使程序可以被攻击者控制。缓冲区溢出多发生在strcpystrcatsprintffgetsstrncpystrncatsnprintfsscanffscanfvscanf这些函数上,实际情况下,我们不要错误的认为strncpy这样的函数是安全函数,因为程序员的编码不谨慎则会触发安全漏洞。

敏感函数导致栈溢出的例子:

还有很多存在栈溢出的原因是程序员自己的编码错误,针对敏感函数的例子已经给出了,现在我们来看个实际的程序员编码错误导致栈溢出的例子。

观察下图的函数,看是否存在栈溢出呢?

(自定义函数)

通过观察这个测试函数,我们可以得到下面的结论:

A、  该函数如果正常调用的话,不会出发缓冲区溢出。

B、  该函数被错误调用,则被触发栈溢出。

C、  如果上述函数的参数被黑客所控制,那么就可在某种程度上构造长字符串,实现栈溢出。

 

下面是我们错误传值的情况,很多情况下,程序员都无法100%的保证自己书写代码的安全性。

 

经过上面的错误传值过程,我们看到程序执行出错了:)

 

开启默认的调试器进行调试。

 

由于大数据覆盖掉小数据,使原先的栈空间保存的ESP寄存器数值被覆盖,导致EIP执行出错,0x61616161很明显是aaaa16进制,

 

下面我们来分析下导致栈溢出的原因。

函数入栈前的情况:

Eaxsrc

Ecxdst

刚进入函数内部的汇编代码,该处的汇编代码主要为创建栈框架,遵循Intel创建栈的规则。

下面来看下ESP的数据情况:

0040108A这个地址是否熟悉?看上图请。

0012FF70是否熟悉?参数1的地址。

0012FB70是否熟悉?参数2的地址。

看该处,在ret返回前ESP的值已经被N多的61覆盖,那么此时如果ret指令往下执行,则EIP为可控制。