看雪论坛
发新帖
10

[原创]看雪 2016 CTF 第一题 Solution

HHHso 2016-11-3 07:44 2804
一、 算法在哪里?在提示信息上下文?
(1)    二话不说,附件解压出来直上手头上的IDA6.6, IDA加载自行分析的短暂过程中另一边跑起实例;
(2)    根据提示字符,回到IDA开”String window”;,进行字符串交叉引用溯源【图1.1】;
”so long, try again”,”so short, try again”;”something you lost”选哪个?随便了,也忘记测试过程中哪个出现先,哪个出现后了。
与其花时间思考选哪个跟踪,还不如直上,说不定选择的时间已经足以对三个敏感字符串的引用位置溯源了,事实也是如此。
在【图1.2】处看到了“疑似”提示成功的字符串信息,真是走了狗屎运了。
提示成功的字符串一开始并非如【图1.2】所示明文,而是类似与其下面的xmm指令的操作数类型。
其是在后续对F5出来的伪码分析过程中,包括对”so short, try again”,”so long, try again”在内的字符串操作应用的Unicode类型转换得到:
[IDA->Option->ASCII string style->Unicode->定位字符串开始位置,快捷键”a”]
(3)    字符串的引用都溯源到了同一“消息处理函数”【图1.3】;对“消息处理函数”进行“F5”伪码【图1.4】,很不幸地发现了提示成功的信息字符串。
可惜上下概览了一下上下文没有检验算法。不过留意到成功信息是消息参数0x40B的响应。即若找到了发消息的源发地,估计算法就在那附近了。

【图1.1】

【图1.2】

【图1.3】

【图1.4】


二、 算法在哪里?在0x40B消息参数发起地附近?
(1)    几乎不经大脑,第一个去IDA->Import窗口找SendMessage,还好,SendMessageW的引用地不多【图2.1】;
对老司机而言,纵然有成千上万处引用,也只是几句IDAPython脚本就可以快速选出目标;
这里懒得定制脚本了,直接逐个查看,非常幸运,所有引用都不发0x40B消息,天呀,太难了。
(2)    不过,好像还有PostMessage;换PostMessagW再来,只有两处引用【图2.2】(实际是一处),很不幸,找到了0x40B自定义消息的发源地【图2.3】:0x40B出,城池破。

【图2.1】

【图2.2】

【图2.3】


三、 犹抱琵琶半遮面的算法长啥样?
(1)    在追求时间与效率平衡的问题上,破解攻击过程并没有从头到尾固定的全盘套路。
正如IDA之名所标榜的,“交互反汇编”,都是在实时根据实情变化分析手段的过程。
(2)    在【一】的过程中,有间隔进行了GetWindowTextW的引用分析,引用点不多也不少【图3.1】,简单的引用分析定位不了核心点。
(3)    直接上OD直跑->输入password->断下GetWindowTextW【图3.2】->确认按钮->在GetWindowTextW处断下,如【图3.2】
->dump 定位到参数buffer处【图3.3】,断返回点直跑(或直跑到返回);
->直跑断下,buffer去数据为”1”【图3.4】,一开始不晓得是啥东东,事后当然知道是尝试次序。继续跑->在GetWindowTextW处断下;
->dump 定位到参数buffer处【图3.5】,断返回点直跑(或直跑到返回);
->直跑断下,buffer去数据为password【图3.6】,得到关键引用点位置0x00401C3E;
(4) 【三(3)】得到的关键引用位置0x00401C3E,位于函数Sub_401C00,上下文分析其检测password是否含有”b”【图3.7】,
若不含”b”则会引发消息0x40F(开始判断为异常或其它另类处理,事后分析代表 "Something you lost..."),
则password必须包含”b”;
(5) “401D0F call    sub_402A50”检测password中是否含有”p”【图3.8】;
sub_402A50是Sub_401C00的改进版,后者固定检测’b”,前者检测是否包含输入参char如”p”;
        则password必须包含”p”;
(6) 事后,在调用Sub_401C00的函数sub_401CB0中,还有password的长度限制,为7个字符【图3.9】。
攻击过程中长了就少些,长了就增加些,不一定非得从代码逻辑上确认;
(7) 在检验主要入口函数 sub_401A60中,对password做了初步简单分散xor【图3.10】操作加密再传送给核心检验函数sub_401870;
在sub_401870同样的分散xor【图3.10】操作过程进行了xor解密出院password,
在sub_401870中对password的所有小字母进行了大写转换(如【图3.11】),
在sub_401870中摘取了转换后的password中的所有大写字母(后续会检测其数目,必须为2【图3.12】),
在sub_401870中检测password的第3,4,5,6字符经大写转换后必须为”15PB”(如【图3.12】);
在sub_401740中检测password第1,2字符必须为”12”(如【图3.13】);
在sub_401740中检测第1字符”1”(0x31)跟password[尝试次序,以1开始]和为0x63【图3.14】,
即要求password[尝试次序,以1开始]=”2”,而随后有强制password最后一个字符(第7字符)等于”7”(0x37)加上尝试次序【图3.14】。
(8) ***综合上述分析只有第一次尝试1215pb8才会通过。***

【图3.1】

【图3.2】

【图3.3】

【图3.4】

【图3.5】

【图3.6】

【图3.7】

【图3.8】

【图3.9】

【图3.10】

【图3.11】

【图3.12】

【图3.13】

【图3.14】
上传的附件:
本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (3)
柒小苦瓜 2016-12-4 12:33
2
楼主,为什么我的GetWindowTextW处的断点,执行到返回,可以取到尝试次数的Buffer值。但是第二次断点去取password的时,【执行到返回】,程序就一直在运行。。
blowingluo 2017-1-20 17:13
3
楼主,第7步该怎么快速分析出来?  到了第7步,发现好累啊, 只能看汇编好辛苦 。。。。
在sub_401870同样的分散xor【图3.10】操作过程进行了xor解密出院password,
在sub_401870中对password的所有小字母进行了大写转换(如【图3.11】),
在sub_401870中摘取了转换后的password中的所有大写字母(后续会检测其数目,必须为2【图3.12】),
在sub_401870中检测password的第3,4,5,6字符经大写转换后必须为”15PB”(如【图3.12】);
在sub_401740中检测password第1,2字符必须为”12”(如【图3.13】);
在sub_401740中检测第1字符”1”(0x31)跟password[尝试次序,以1开始]和为0x63【图3.14】,
blowingluo 2017-1-24 12:00
4
终于跟着楼主破完了。。。。。谢谢 ,这个是从ida静态分析的思路破,果然比od破快多了,最开始我用od跟按钮消息跟到后面都累死了
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 微信公众号:ikanxue
Time: 0.012, SQL: 10 / 京ICP备10040895号-17