前情提要: 栈爆了-精要介绍栈溢出相关
想覆盖返回地址你就盖?
在程序开始算出个随机值Cookie用于放在每个关键的ret地址前。
我知道你的第一想法是猜测这个值,但可能不大:
Cookie的产生使用了很多随机量,而你只有一次机会。
如果你覆盖ret就会覆盖它上面的Cookie。不得不承认这真是一个好方法。
而执行ret之前在代码中进行一次检查:
值得注意的其使用了rep retn这个语句,在OD中错误的显示为:
有一次我跟踪时遇到这种情况,以为是什么错误干扰。
其实这是编译器对AMD64的分支预测作出的优化=ret。
我抄一段到下面:
gogdizzy:
找到答案了,看来还是得用google才行啊。
摘自http://board.flatassembler.net/topic.php?t=6264
其中提到AMD64的优化指南中提到,这么做是为了优化,在两种条件下无法发挥cpu的分支预测功能:
1> 一个分支,里面带有near-return(opcode C3h),例如
label:
ret
2> 一个判断条件紧跟着就是near-return,例如
jle label2
ret
为了使得代码还是能够用得上cpu的分支预测(branch prediction),最简单的解决办法就是在ret前面插入rep,这称之为two-byte ret,使得性能可以提高。
我上面的问题应该是第二种情况,所以要用rep ret。
这样一来,但凡利用覆盖ret的栈溢处攻击遇到狡诈的cookie都失效了。
小黑:这怎么办呀,我这几天学的岂不是白学了。栈溢出原来是个已经解决的历史性问题啊!
老黑点了一只烟,悠悠道:我考考你windows中哪些机制能跳过正常执行流程?
小黑:这个我知道,中断呗。
就不懂得发散一下思维,买的书白花钱了!老黑莫名生气。
小黑:您老别太生气,都怪我平时没学好,好像还有SEH,VEH什么的。
老黑:这也不怪你,只凭书本,不实践怎么会记得,那让我们看黑客们是如何突破cookie的封印的。
长些再长些
前面谈到ret上面按了一个cookie仿佛是特工夹在门缝里的一根见光死,反正你就是告诉你:小盆友不要碰哟。
自从有个这个机制后,安全人员和黑客都在寻找其中的漏洞,直到目光被聚集在高于正常执行流程的机制上。
只有在执行cookie检查之前拿到所有权才是生存之道,方法之一是首先构造出了一个异常通过超长的Shell数据来引发异常,而在覆盖的过程中其实我们已经接管了异常处理程序SEH。让我们为所欲为吧。
且慢-再来个SEH的Cookie
小黑:这群搞安全的还有完没完啊
老黑:都几点了,还快去睡觉。
2016年10月10日星期一 22:31