由于最近作业以及自己要写工具,所以之前的破文都没来得及写,之后会一一补上,还望评委谅解
注明:以下数字都为16进制
这个CrackMe我是采取"曲线救国"的方式破解的,即通过栈溢出方式绕过算法,直接到达提示成功的代码地址
不得不说样本中的算法确实够难,其中细心的同学可能都发现他的第一个关键比较跳转,其实是费马大定理的衍生, x^n + y^n = z^n,当n大于2时候这个方程没有非0正整数解,但是作者对方程做了一些改动,即会与上FFFFFFFF,且在最后验证加法时候有溢出可能,那这个本不会成立的方程就有了成立的可能, 一开始我也用机器穷举解的集合,但是3个小时过去还是没有得到一个解的集合,因此穷举我就放弃了,采取了"曲线救国"方式尝试破解
首先,对于CrackMe,赛制规则规定不能够修改文件,不能够第三方修改内存(即通过线程注入,模拟加载等方式影响程序),那唯一的解决方式就是在输入提示框输入数据
但是我们可以发现样本程序中,scanf没有对长度做出限定,而且main函数的代码过短,更重要的是程序编译形成后没有用重定位基地址方式编译为PE文件,那即是程序被系统加载后基地址是死地址,400000,没错这个样本存在溢出漏洞,而且程序的代码地址是可以写死的,这就为通过溢出漏洞达到破解提供了充分条件
基本思路为通过scanf输入大量数据,撑爆栈空间,产生栈溢出异常,在输入的数据中存在特殊字符(即成功显示的地址),覆盖SEH链中的处理函数地址为验证成功的代码地址,这样异常处理就直接跳转到显示成功的位置, 即"曲线救国"成功
对样本条件做下梳理:
1.因为scanf没有对长度做出限定,所以可以输入大量数据影响栈
2.因为main函数的代码过短,可以输入大量数据撑爆栈,产生栈溢出异常
3.因为样本代码地址是固定地址,所以可以在输入的数据中,模拟出验证成功的代码地址
开始溢出破解样本:(注明:关于SEH链的结构我这里就不展开了)
首先,程序的成功提示地址为401793,也即是输入正确注册码后到达的地方,这里我就不截图了
我们可以看到,程序的scanf后存储的地址在,18FB48,我们试着输入一个123
而在刚进入main函数后会,压入一个异常处理函数,
这里是栈空间情况:
我们可以看到,压入位置为18FF78后面紧跟着的是处理函数的地址为408AD4,距离scanf后的栈位置不远,那即是我们在scanf输入大量数据就可以替换调这个处理函数地址变为我们想要的地址401793,这样就有了附件中的开头一段数据,那段数据最关键的是最后的"摀@"(PS:中间有个字符论坛输不进去),内存中即是93 93 17 40
为什么没有00呢,因为我们如果直接复制黏贴是无法在控制台中黏贴到00的,需要手工输入ctrl+@
我们看下复制黏贴第一段数据,到样本控制台并手工输入ctrl+@的效果
看到上图中,我们已经成功影响到异常处理函数了,最后就是撑爆栈空间让成功提示的代码去伪处理异常,这样程序就被我们攻破
重新来一遍,先复制黏贴第一段数据,不忙按回车,手工输入ctrl+@,然后随便复制黏贴上超过80字节的数据,目的是撑爆栈,按下回车产生栈溢出异常跳转到成功提示
输入情况:
破解成功:
PS:附件中为输入流程以及数据
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课