首页
社区
课程
招聘
[原创]CTF2018第十三题分析(qwertyaa)
发表于: 2018-7-10 22:26 2901

[原创]CTF2018第十三题分析(qwertyaa)

2018-7-10 22:26
2901

首先看一遍main函数,如下:

里面的所有字符串都简单加密了一下,动态调试即可得他们分别是key len error.key char error%lfOhhh.Try againCome on, go onCongratulation

程序里的fabs和浮点取负似乎不一定能够识别出来,在了解到COERCE_UNSIGNED_INT64用于将参数强制转换为unsigned __int64(等价于*(unsigned __int64*)(&x))以及double的最高位是符号位后很容易手工识别出来。

而程序中的exp函数可以通过函数中的一些魔数识别,sqrt可以通过异常处理时用的字符串识别,将这两个函数重新命名后按F5可以识别出不少东西来。

而开头的initValssub_401C50似乎是在初始化一些东西,或许是在训练网络,里面的GetTickCount似乎用于反调试,这一点和 lelfei 以前的CM很像。

输入后是判断输入的key是否长度为10,并将其进行“hex2bin”,然后将结果放到两个double高2/3byte上去。

接下来将其传入一个函数记作nnRun,通过传递地址返回一个double,接下来进行一些检查:

而阅读nnRun可知,但传入double不在(1,10)的范围内时返回的double必为10.0,而这显然不满足条件1,而double最高位是符号位,接下来是阶码,后面才是尾数,而改变key改变的是这两个double的高位内容,所以所剩的key的可能数不多了(总共仅几百万种可能)。

但是由于前面两个用于初始化的函数执行的很慢,所以我们要直接Dump初始化结果,并自已实现一遍nnRun才能较快穷举。

仔细看几遍,就可写出nnRun的代码如下:

其中的wei*是被前面所述的两个函数初始化的内容。

这似乎是一个两层的神经网络,第一层有sigmoid函数,第二层直接乘权重,最后求和,这里似乎是在用神经网络模拟加法。(然而我并不懂神经网络,这些都是瞎猜的。(懂了似乎对这道题解题也没太大帮助。))

毕竟即使懂,由于神经网络很难被人类直接看懂,暴力是个不错的选择。

由第一段可知,所剩下的可能数已经不多,枚举可知double的最高两bit必须在3ff1h-4023h的范围内。

暴力的程序如下("defs.h"是IDA的plugins文件夹下的头文件):

这个程序最后还会把枚举出来的正确密钥用NNCrackme.exe来验证一遍,当然这个其实是不必要的(因为我一开始省略了一些条件判断让NNCrackme.exe来直接判断)。

最后得到的key为F13FE02140

 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-7-10 22:39 被qwertyaa编辑 ,原因: 校对
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//