首页
社区
课程
招聘
[原创] PEDIY-JD CTF 2018 Windows CrackMe 题目及设计思路
2018-6-11 02:00 7755

[原创] PEDIY-JD CTF 2018 Windows CrackMe 题目及设计思路

2018-6-11 02:00
7755

CrackMe 设计思路

序及瞎扯淡

本来之前说好, 今年年中开源一个 VM 壳的, 在不使用密码学强度的算法同时, 做到即使开源也难以破解... 但是由于这几个月打了几场比赛, 平常偷懒玩游戏, 以及处理自己实验室的诸多事情, 到现在也没写出来. 正值此次看雪 CTF, 在下选了几个思路, 出到这个 CrackMe 里面, 也算是在下对软件保护这个领域未来方向的一些思考和试探吧.

设计哲学

说哲学有点玄, 但是这个的确是方向性的东西, 而不是各种技巧之类的.
首先, 这个 CrackMe 的目标不是为了难. 如果单纯为了难度, 在下可以使用各种技巧能把这个程序难度再拔高一个层次. 恰恰相反, 在下尽力把一些不必要的难度去除. 比如使用清晰的结构, 关闭编译器优化, 避免高度内联化, 循环展开, 避免使用向量指令, 等等.
其次, 这次逆向题避开了大多传统的代码保护技术, 包括加壳, 反调试, 虚拟机保护, 自修改程序, 常量展开, 花指令等等. 其实, 这个 CrackMe 专注于一些新的方法. 可能效果不如传统方法, 但是希望能给大家更广阔的思路, 也是希望大家能多指点在下.

大致流程

本 CrackMe 按照惯例开源, 源代码见附件. 曾经某届看雪 CTF 在下开源过一些现在看起来非常糟糕的代码, 如今回想起还十分愧疚... 这次依旧能力有限, 不过代码质量应该勉强能入各位法眼.
这次题目有点俄罗斯套娃, 实际上是有 5 个不同的操作拼接而成. 而其中两个操作是利用了隐蔽信道的技术, 所以这题叫做暗风吹雨, 取 暗风吹雨入寒窗 之意.

  1. 要求输入为 16 个数字字母组合
  2. Base64 解码成 96 位. 每 32 位为一大组.
  3. 对数据进行 5 个操作, 分别为 T0, C0, T1, C1, T2. T 的意思是 transform, 数据的混淆主要靠 T 操作. C 意为 covert, 即更为隐蔽的操作.
  4. 将变换后的结果与预设值比较. 作为判断 Flag 的依据.

所有的操作设计上都可逆, 故而此算法可逆. 而每个操作都使用了一种代码保护思路:

T0

T0 里面用到了异构计算. 微软于 2012 年左右提出的 C++ AMP, 是一个基于 DirectX 的异构计算标准, 2016年以后基本已经不在维护了. 可是即使如此, 其相对于其他标准如 OpenCL 和 CUDA 来说有着很多优势. 为了兼容性以及代码体积考虑, 故选择了 C++ AMP.
T0 实际上做了一次 GF(2) 上的矩阵乘法. 矩阵由随机数生成器由固定种子生成. 且其逆矩阵验算后存在, 故而也可逆. 实际上许多串行算法完全可以挪到 GPU 上, 天然的异构指令集, 稀缺的文档, 是一个非常不错的代码保护方法.

C0

C0 是一个利用 Cache 命中的侧信道来执行的一个 SBox. 侧信道的第一个好处, 就是隐蔽. 如果不是如本程序刻意降低难度的话, 对于数据的 cross reference 根本无法溯源到原始信息. 加上侧信道甚至可以在进程之间通信, 一个高手的设计可以让数据泥牛入海, 无迹可寻.
其第二个好处, 就是能破坏 Taint 分析. 因为污点分析是基于数据流的, Covert Channel 则在显式的数据流之外打通了新的数据流. 同理对于 Concolic Execution 也具有相当的抵抗力.
但是缺点也很严重, 就是其不稳定性. 侧信道很容易受外界因素影响, 所以实际应用中会增加诸如 BCH 编码之类的纠错码. 而且, 难以避免的 RDTSC/RDTSCP 指令也使得这个方法在程序中十分显眼.

T1

T1 里面利用了多线程的 Race Condition. 多个线程对同一个数赋值, 只有最慢的线程的结果保留了下来. 而类似于停机问题, 得到任意程序的执行时间是一个不可解的问题. 故而可以构造出不同速度的线程, 对数据进行不同的操作, 从而实现代码混淆.
T1 开了 4 个线程, 每个线程的速度和数据的高两位有关. 然后对数据的低 30 位进行循环移位和异或.
这种方法虽然是在下提出, 但研究的也并不够成熟, 具体效果看看实战吧.

C1

C1 实际上是利用了今年的 Spectre 漏洞. 目前 Intel 和 AMD 似乎尚无硬件解决的意向. 故而可以故意构造出这样一个信道. 通过训练分支预测器, 使得推测执行能够 touch 到目标内存区域. 错误的输入数据无法训练好分支预测, 通过检测目标区域是否缓存命中, 故而可以做到代码混淆.

T2

T2 里面有很多浮点数运算, 实际上是由两个简易的神经网络拼接而成.
第一个网络有 32 个输入, 两个隐藏层都有 32 个神经元, 激活函数是 Sigmoid, 然后到 8 个输出, 激活函数是 round 取整.
这个网络的作用主要是 permutation.
然后, 对于每一个输出, 作为第二个小网络的输入. 第二个网络有 16 个输出, 相当于一个分类器, 实际上是一个 SBox.
这个结构被串联在一起, 不容易看出. 如果注意到, round 函数作为激活函数可以说是非常之罕见. 应该就能把两个网络分离开来.

破解思路

破解 T0 需要逆向 Shader 代码, 这个得看 MSDN 上的文档. 网络上也有相关工具.
T0 中的矩阵是可逆, 计算出逆矩阵后乘以程序中的结果, 可恢复 T0 的计算.
T1 根据头两位计算出实际有效的线程id, 然后据此恢复.
T2 需要观察网络的输出, 据此猜测网络的作用. 小网络可以直接爆破.
C0 和 C1 实际上看懂了就能做出来. 基本没有变换.

技术总结

其实程序无非就是两个方面, 数据流和控制流. 放在逆向 CrackMe 上面, 就是要么跟着输入走, 要么跟着代码走.
几个 T 操作, 实际上混淆的是控制流. 把代码变成 Direct X Shader Blob, 或者变成神经网络的运算, 都相当于异构. 而 T2 这样, 用并行的线程, 同时读写一块内存, 也是相当于打乱了控制流分析.
几个 C 操作, 则实际上是隐藏了数据流. 因为都不是通过 CPU 显式访存访问到的.
如果是多线程, 通过 prime & probe, 和 race condition 来访存呢? 即打乱了代码执行顺序, 也打乱了数据流向. 这也大概是我那个尚未完成的 VM 代码保护的主要思路之一了.

尾声

首先, 很感谢看雪论坛举办的这次比赛, 能给我的一些不成熟的想法一个实践的机会. 我也很喜欢这个技术交流的平台, 衷心希望它越做越好.
其次, 很感谢 @poyoten 在我学习逆向的过程中的很多指导, 虽然素未蒙面, 也算是在下的逆向导师了. 还有感谢 @swings 老师的亲自授课, 虽然我啥都没学会... 但是好歹知道了大佬大概应该长什么样. 以及上次 @渡 的信手一笔, 给我的逆向学习指点了方向.
最后感谢 @netwind 的许多建议, 这次题目一改再改, 不断进步, 很多都是在其忠告之下完善的. 还有曾经 @linhanshi 于我的指点, 以及看雪群里各位大佬的讨论, 都给了我诸多启发, 这里就不再一一感谢了.

 

在比赛开始之后看到后面 lelfei 有一道 NeuralCrackme, 令我感到很惊喜, 因为竟然有人也想到了使用神经网络来混淆代码. 有一种道不孤矣的感觉. 在下和 lelfei 之间并没有交流过这方面的技术, 也希望这次比赛结束后多多探讨. 这道题里神经网络的部分, 也正好算作抛砖引玉了.

main.cpp 是程序源码.
CrackMe.7z 是程序.
reverse.c 是逆向程序的代码.
wp.md 是简单的 writeup
ann.c 是神经网络训练的代码

 

Flag 为 ThisIsAnEasyFlag
程序在 Windows 7 x64 SP1 上, 安装 MSVC 2015 运行库, Universal CRT, .NET 4.7 后测试通过.
Windows 10 17868 x64 上同样测试通过. 其他高于 Windows 7 的系统在安装运行库后应该能正常运行.
不支持 Windows XP.

 

可执行程序的 SHA-256 为 5c455acfb6c36bd5d271af208e4b51cee617814c7fb07f7b8adc780d834aaa72.


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2018-7-7 20:30 被半盲道人编辑 ,原因:
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (12)
雪    币: 8188
活跃值: (4243)
能力值: ( LV15,RANK:2459 )
在线值:
发帖
回帖
粉丝
ccfer 16 2018-7-6 14:17
2
0
太深奥了,完全不懂
雪    币: 459
活跃值: (652)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ssarg 2018-7-6 14:51
3
0
破解 > 逆向。而很哲学的保护无非是最大可能阻止逆向而已。
他们之间的哲学关系,太深奥了,完全不懂。
雪    币: 124
活跃值: (4749)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
wsc 2018-7-6 15:55
4
0
已经很强了
雪    币: 1982
活跃值: (1173)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
十八垧 1 2018-7-6 16:04
5
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
holing 15 2018-7-6 17:33
6
0
这我看着WP和源码都做不出
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2018-7-6 18:39
7
0
看了你的题目介绍,我感到非常汗颜,跟你的设计哲学相比,我的cm估计能被虐的不成样子,以后多多向你请教!
雪    币: 13713
活跃值: (2851)
能力值: ( LV15,RANK:2663 )
在线值:
发帖
回帖
粉丝
poyoten 22 2018-7-7 16:20
8
0
牛皮得一踏糊涂
雪    币: 1610
活跃值: (548)
能力值: ( LV12,RANK:382 )
在线值:
发帖
回帖
粉丝
半盲道人 3 2018-7-7 20:31
9
0
lelfei 看了你的题目介绍,我感到非常汗颜,跟你的设计哲学相比,我的cm估计能被虐的不成样子,以后多多向你请教!
不敢不敢, 一起探讨.
雪    币: 4
活跃值: (170)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Vuler 2018-7-17 22:59
10
0
楼主还在读书吗?实验室还招人吗.....
雪    币: 1620
活跃值: (17)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
chkds 2018-7-20 08:53
11
0
望天。。。膜一波大佬,试着跟wp调一调看看有多少坑吧
雪    币: 3712
活跃值: (1271)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
不知世事 1 2018-8-15 19:27
12
0
学习了,感谢分享
雪    币: 12042
活跃值: (3308)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
zeroghost 1 2019-12-11 17:01
13
0
tql,膜一波dalao先
游客
登录 | 注册 方可回帖
返回