查看: 352|回复: 0

[Reverse] 看雪CTFQ2晋级赛第一题神秘来信解题Wirteup

[复制链接]
发表于 2019-6-11 07:49:51 | 显示全部楼层 |阅读模式
这道题目主要考察异常处理机制,题目刚发布的时候出现多解,我现在分析的是作者修复后的。
1. 查壳,无壳的C++程序。
1.png
2. 直接载入OD,看到了异常处理需要的两个函数,SetUnhandledExceptionFilterUnhandledExceptionFilter
SetUnhandledExceptionFilter函数的唯一一个参数为异常处理函数指针。当程序发生异常时,且程序不处于调试模式(VS或者其他调试器里运行)则首先调用该异常处理函数。因此,程序可以主动抛出一个异常来判断当前程序是否正在被调试
2.png
3. 我们现在给SetUnhandledExceptionFilterUnhandledExceptionFilter这两个函数设置断点,运行程序。断在了SetUnhandledExceptionFilter的入口处。我们看下堆栈的情况,正如你所看到的异常处理函数入口地址为00401C8E,我们在命令栏中输入BP 00401C8E给该函数设置断点。
3.png
4. 异常处理函数前面已经设置过了,所以我们将对SetUnhandledExceptionFilter设置的断点删除掉,运行程序,找到获取输入的函数,输入序列号401353(篇幅有限,不演示踩坑,这里直接输入的是真码)。
4.png
5. 输入的长度必须小于7位才可以继续运行
5.png
6. 限定真码的后三位为353
6.png
7. 限定前三位的ascii十六进制之和为0x95,也就是十进制的149,我一次做的时候猜的是212353230353
7.png
8. 把输入的字符串直接转换成整数放到esi
8.png
9. 在0040134E处CALL 00401354,我们知道call是一个组合的指令,call 00401354相当于push 00401353然后jmp 00401354,先压入下一行地址作为返回地址,然后再跳转。但是00401354处执行了pop eax,这样就导致返回地址丢失了,这个程序回不到00401353这个地方了。
9.png
10. 输入正确这里会触发除零异常,然后走异常处理程序,这里就可以看出程序的这部分代码应该是用内联汇编写的,可见作者的良苦用心,如果错误就继续向下执行,提示error,并且程序卡死,因为最后那条jmp是跳向自己的死循环。
10.png
11. 异常处理过程将会断在系统默认的异常处理函数入口处,因为程序有异常发生,并且当前程序正在被调试,所以,并不会首先调用程序之前设置的入口为00401C8E的异常处理函数,而异常转交给调试器处理了,而调试器也无法处理该异常,所以最终调用系统默认的异常处理函数UnhandledExceptionFilter来处理,这个函数里会内嵌ZwQueryInformationProcess函数来检测是否有调试器。
11.png
12. 该函数通过将InfoClass参数设置为7,将可以获取到当前进程是否被调试的信息,该信息将保存在Buffer参数指向的缓冲区中。如果该缓冲区返回的是FFFFFFFF的话表示当前程序正在被调试,我们将其四个字节全修改为零就表示没有调试器了。因为我使用的原版OD,没有任何插件,所以这里要改,如果有strongOD等插件,这里插件会帮你过了反调试。
这里看一下程序的整个流程
12.png
13.png
注意:
1. 此程序直接用IDA可能无法直接F5转换伪代码,因为堆栈不平衡,ida无法正常判断程序的流程,这里需要手动平衡堆栈(用odpop去掉一个再用idaF5
2. 此程序涉及到异常处理,最好用不带插件的原版OD分析,OD需要设置忽略异常。
14.png

题目下载:
MysteriousLetter2.rar (57.45 KB, 下载次数: 0)
温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的最好奖励,还可以获得学币奖励,请尊重作者的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
善莫大焉-2019
关闭

论坛公告上一条 /1 下一条

快速回复 返回顶部 返回列表