专栏名称: 看雪学苑
致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
目录
相关文章推荐
嘶吼专业版  ·  超过 1000 个 ServiceNow ... ·  2 天前  
安天集团  ·  启航新篇章,共筑安全梦 — ... ·  4 天前  
杭州发布  ·  最新提醒:节后,杭州这些道路出行有变! ·  6 天前  
杭州发布  ·  最新提醒:节后,杭州这些道路出行有变! ·  6 天前  
51好读  ›  专栏  ›  看雪学苑

看雪.WiFi万能钥匙 CTF 2017第五题 点评及解题思路

看雪学苑  · 公众号  · 互联网安全  · 2017-06-11 18:37

正文

本周最后一天,看雪CTF 2017 比赛进行至第五题

截止至今天中午12点,第四题破解人数为22人!


攻击方排名前十名稍有变动,比赛排名有人升、有人降。

第五题结束后,

HHHso一举冲到第7位,lacoucou也突进第十位,

随着比赛的进行,选手的表现给了我们越来越多的惊喜!


大家继续加油!

接下来我们来回顾一下第五题

看看看雪评委和出题者是怎么说的ヾ(๑╹◡╹)ノ"



看雪评委 netwind 点评


作者限定了注册码为6个字符,用驱动进行了简单的反调试,并在驱动里用简单的算法对注册码进行了处理,最后在应用层通过md5对比验证来判断注册码是否正确,此题需要暴力枚举才能得到结果。


作者简介:


独行孤客-80后,广西玉林人,高二即开始自学c/c++/汇编,2008年注册看雪账号。同年入读柳州师专网络专业。先后任职过反病毒工程师,某事业单位信息安全研究员,负责软件开发与逆向,软件漏洞的挖掘与利用,计算机病毒技术的研究等。业余时间喜欢钻研书法碑帖,取法多参以二王与唐楷。


看雪 CTF2017 第五题设计思路


1. CM分两部分,分别为应用层的CrackMe.exe,以及由CrackMe.exe生成的驱动vmxdrv.sys(加载进内核后被删除)。

2. CM只能正常运行在XP系统上。

3. 安全软件可能会报异常,但本人并没有在CM中添加任何恶意代码,除了多开几个线程会多占资源之外,以及驱动有可能不稳定产生系统崩溃,所以请选手及时备份资料。

4. 用户层显示GUI界面并接受选手的输入,选手输入完成后按回车确认。CM将对答案作简单处理后下发到驱动层模块,由驱动对答案进行处理,具体说是对处理后的答案再进行md5计算。

由用户层通过ReadFile读取计算结果,并再次对中间结果进行md5计算等操作。最后比对正确答案并在正确的情况下给选手以提示。CM的正确答案为:su1986,只接受六个字符。理论上在限制的时间内可以穷举。

5. 驱动层除了负责一部分加密运算,还负责反调试,通过IOCTL分发函数对客户端的eprocess中的调试端口进行清0操作。而客户端则开启多个线程循环发送此IOCTL控制码。

6. CM会在验证答案时检测是否被调试,如发现IsDebuggerPresent返回真则不执行验证流程.

7. 对选手的tips:安全软件报毒可放在虚拟机中运行,保存重要资料以防系统崩溃,软件需要回车确认答案。

下面选取攻击者lacoucou的破解分析


查看程序

1. 题目提示要在xp下运行,看了看资源,发现有驱动,将文件提取出来,用PEID的算法插件KANAL扫描驱动,发现有MD5算法:

2. 用OD加载程序CrakeME,下断点CreateFileA,一次断在释放驱动的时候,另一次断在加载驱动的时候:

在CreateFileA 的下一条指令下断点,运行程序,程序直接出错退出。

有反调试,用IDA打开程序,发现了IsDebuggerPresent,这个应该不会导致程序崩溃。

接着找,发现了一个线程:

线程中死循环在发送控制码,打开驱动,找到对应的控制码:

嘿嘿,EPROCESS,最后有个清零的动作,这里就是反调试了吧。没有查这个结构体,据猜测应该是把调试端口清零了。

解决办法:

1.

通过资源工具导出驱动,然后修改驱动中的sub_10486函数(即上图的fantishi_10486):

这样就不会清空端口了。

然后用loadpe修改驱动的校验和。修改方法详见:http://bbs.pediy.com/thread-185490.htm

用winhex修复crakeme,修复后的程序见附件。

2.跟踪流程

跟踪了几次之后,理出来的流程大致如下:

1.sub_4013E0 主要负责释放驱动,启动驱动,还有反调试

2.sub_4013E0 是按下enter之后的处理函数

主要流程:

1)sub_4182FA((CString *)&v7);   // 获取注册码

2)sub_4182FA((CString *)&v7);   //注册码转小写  CString::MakeLower

3)sub_41830C((CString *)&v7);   //注册码倒序    CString::MakeReverse

4)  if ( *(_DWORD *)(v7 - 8) != 6 || IsDebuggerPresent() )  判断注册码长度是否等于6 加反调试

5)Sub_401D50(v1, v3, (size_t)v5);  这个函数主要功能:把获取到的注册码发送到驱动层,计算 hash后载读取回来。


DeviceIoControl 这个地方是个坑,原来以为只是用来反调试的,后续发现它会设置一个全局变量dword_114D8 = 1; 

这个变量在驱动层计算md5中要使用,没有这个,每次不管输入的是什么,驱动层返回的md5都一样。

WriteFile 用来发送我们输入的注册码。

ReadFile 用来读取计算出来的hash.

接着说说计算hash(md5)的算法--驱动中:

圆圈中圈住的就是上边说的全局变量。

方框中圈的也与正规的md5算法不同:

多了一些莫名其妙的操作。是一个变形的MD5算法。

6)获取到驱动返回的MD5之后:

(1).sub_417D43((CString *)&v4, (LPCSTR *)v1 + 23);  

返回类似md5值的字符串形式  md5_like=md5_(userInput)

(2).sub_401920(v4, (CString *)v5);  将上述md5字符串再计算一次md5

   Md5=sub_401920(md5_like)

(3).mid_415A78((LPCSTR *)&v8, (int)&v9, 2, 0xAu);

   subMd5=mid(md5,2,10)

   将md5字符串从位置2处截取10个字符。

(4)if ( _mbsicmp(v8, a888aeda4ab) ) 

  截取的字符串与888aeda4ab 比较。

(5)show_success_402030  拼接字符串Success^^! 并显示在窗体上。

整个算法用伪代码描述就是:

subString=string_substr(md5(md5_like(CString::MakeReverse(CString::MakeLower(userInPut)))),2,10)

已知条件,输入字符串长度为6最终的subString 为888aeda4ab 。求输入字符串。

所以只能乖乖的爆破。

由于驱动中的md5是非标准版算法,这里也不再详细跟了,直接自己写程序调用他的驱动,Crakeme内的驱动为标准算法,直接找一个md5源码就可以了。

找一个加载驱动的工具加载导出的驱动,然后运行下面的算法:

代码如下:

最终:

程序中没有出来倒序的问题,因此这里反过来输入就可以了。



最后感谢 WiFi 万能钥匙安全应急响应中心的赞助支持,

接下来的比赛大家一定要使出洪荒之力哦!↖(^ω^)↗

比心 


赞助商

上海连尚网络科技有限公司成立于 2013 年,是一家专注于提供免费上网和内容服务的移动互联网企业。连尚网络自主研发的核心产品 WiFi 万能钥匙,以分享经济的模式,通过云计算和大数据技术,利用热点主人分享的闲置WiFi资源,为用户提供免费、稳定、安全的上网服务,以帮助更多的人上网,找到属于他们的机会,改变自己的命运。


往期热门内容推荐



更多比赛详情,长按下方二维码,“关注看雪学院公众号”查看!

看雪论坛:http://bbs.pediy.com/

微信公众号 ID:ikanxue

微博:看雪安全

商务合作[email protected]




阅读原文了解更多