这次是不小心捡到一个poc.doc文档,导致Word出错来展开分析的。首先打开poc.doc时候,出现Access Violation错误(即EIP=0x41414141)。
此时可以从栈中回溯到上层调用函数的返回地址,可见0x275C8A0A处,难道我们当前出错函数就是mscomctl.275C876D了吗?那我们在0x275C8A05处打上断点探究一下...
当我们再次打开poc.doc运行来看时发现,真正Crack的地方是在0x275C8A56处的ret 8,这说明之前某个部分复制数据到栈上导致栈溢出覆盖掉了原本的返回地址了。
这次我们单步运行发现复制的地方处于0x275C87CD处的rep指令,此时我们将rep指令所处函数命名为VulnFunc,将之前ret 8所处函数命名为CrackFunc。那么我们在IDA Pro中解析可以得到如下代码,
VulnFunc第一次调用,使得程序从文件中获得dwBytes(dwBytes=0x00008282)和v5(0x6A626F43),而dwBytes>=8,使得VulnFunc第二次调用,从文件从复制dwBytes字节数据到&dst(&dst=bp-8,也就是栈上的位置)处,之后再判断overwritten_bytes([bp-4])是否为0,如是即返回。我们再来看看VulnFunc中的内容,
VulnFunc大致是先从堆中申请dwBytes字节空间,然后将文件内容复制到此处空间内,最后再从堆中将数据复制到dst处(qmemcpy(...)),导致外层函数栈溢出了。
以上所需关键数据0x6A626F43、0x00008282、0x41414141都可以在poc.doc中找到,
因为CrackFunc返回前需要判断overwritten_bytes,所以0x1309-0x1320都必须是‘0’,有因为返回指令是ret 8,所以“41414141”后面16字节不能存在payload。所以最终的shellcode=‘0’*24+ROP(jmp esp)+‘0’*16+payload。
-----------------------------------------------------------------------------------------------效果如上图