-
-
[原创]看雪CTF2017第五题 独行孤客CrackMe的writeup
-
发表于: 2017-6-11 07:28 3901
-
驱动不大,才20多个函数。
从入口开始分析。
用来与应用层通信
主要有三个,read/write/ioctl。
先看f_DrvWrite_1061C,通过irp获取到上层传入的数据,然后通过104b6获取某个输出存入全局变量g_READCC(根据read的分析,可以知道长度为4的4字节数组)。
进入104b6内部,key是个16字节数组,初始化0。然后将上面传下的数据拷贝到key中,长度需要小于16。然后将key进行一下变换。 key[0] ++(反调试标志为1,后面再说),其他key[i] += i
接着通过下面三个函数对key进行计算,输出结果
进入108b2一看就猜测是md5计算,f_Md5_hexdigest将计算结果(32字节字符)保存到md 5字段中输出,设置计算标志。也就是大致确认write是计算md5,然后保存到g_READCC
接着看f_DrvRead_105A8,看刚才的计算标志是否为0,为0就初始化g_READCC一段值(不知道作者意图,迷惑cracker?),如果计算标志是1,就直接返回计算的结果,然后该值返回到用户空间。也就是如果通过write计算了md5,这里就是获取md5计算结果。
最后看f_DrvControl_1071A,支持多个命令号,但只有222004h有用。设置反调试标志为1,然后进入10486看看
枚举进程找到当前进程的eprocess(其实没必要枚举把),置eprocess->DebugPort = NULL,让应用层调试器失效,达到反跳试效果。
这里猜想一下,如果破解者通过应用层patch,不发送222004h命令来解除反跳试的话,那么这里的反跳试标志就是0,然后在write中计算md5时,对key[0]就不会做++操作,那么上层就会获取到一个错误的值,从而影响破解。
首先想到的是将驱动文件patch,也就是DebugPort置零的指令nop掉
通过reshacker将驱动资源导出来,然后hex编辑工具修改104A9的内容(文件内存对齐一样)为7个NOP,然后再将patch驱动文件导入到exe中。
会提示驱动加载失败,可能有校验,不再细跟。
没办法,为了让od能够调试,我写了个简单驱动,在本驱动加载时,将104A进行patch,通过反跳试。
既然知道有驱动了,先找找释放和加载驱动的代码,通过 FindResourceA和CreateService即可定位(不再详述),注意到的是,驱动加载成功会设置一个标志,用于后面验证的判断
然后再找和驱动通信的代码,通过DeviceIoControl找到调用222004命令好的代码。通过创建一个线程,循环调用该接口来清零DebugPort
按理说这里可以patch掉来去掉反跳试,但就会出现我前面分析提到的问题。
通过WriteFile找到调用read/write的位置,也就是计算md5和获取md5的位置。
f_CalcKeyMd5_401D50回溯一层就是输入key回车的响应函数。 这里先通过UpdateData(1)获取输入数据,然后拷贝到局部变量
然后输入进行小写和反转变换
判断输入长度是否为6,不是退出,清除输入,并通过IsDebuggerPresent检查是否在调试(OD直接过),是调试也退出,清理出输入。
满足长度要求,再看驱动是否加载,再调用f_CalcKeyMd5_401D50计算md5. 也就是调用驱动获取md5,记为KeyMd51.
接着下面两个函数,先调用f_GetStrMd5_401920(应用层的Md5,通过调试可以很快确认,内部也有md5特征)计算KeyMd51的Md5,记为KeyMd52,然后调用sub_415A78截取KeyMd52从第3为开始的10字符,记为KeyMd53。
最后KeyMd53与888aeda4ab比较,成功提示Success^^!
总结算法:
由于MD5hash无法逆运算,只能爆破了,刚开始忘了题目key只能是数字和字母,结果我跑了全字符,跑了1天多....没出来,卡hi是怀疑自己
后来改成了数字字母,终于得到答案 su1987
爆破代码如下:
最后结果
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- [原创]逆向分析:修复老古董vs2005笔记 12825
- [原创]LordPE在win10无法工作折腾笔记-死而复生 16121
- [原创]QQ后台读取历史记录?有点冤枉企鹅了! 30621
- [原创]深度探索:解除文件占用那些坑 12701
- [原创]华为电脑管家PcManager多屏协同功能破解 19223