2017看雪秋季赛 第三题
自己做的时候。
照样IDA先找找字符串,会发现这个。
经常打CTF,做misc和crypto的话,第一反应这是一个莫尔斯电码。可能和加密数据有关系。
OD调试单步可以走到这里来,DialogBoxParamA是弹框的函数。再单步执行点击验证会崩溃。程序大概率是加了反调试的(每次碰到这种我就***了)
IDA里搜索字符串很明显可以找到这么多的动态工具。一定是加了各种反调试的。
始学习之
下面开始学习之路。
先来记录下看到的对我印象很大的一句话:新手用OD,高手看汇编!以后会大大改善自己的学习习惯和方法的。
要习惯IDA来找算法入口,直接绕过所有的调试和反调试。
这些函数是可以用来读取用户输入的。
View - Open Subview - Cross References
利用好IDA的字符串功能和导入函数imports和导出函数功能,OD的中文智能搜索也是一个好工具。
提示我们字符串长不够
(从这里就能猜到base64的使用,个人觉得还是很牵强。。。但是可以作为一种思路猜想,去验证)
看到了MessageBoxA的ok!激动不激动,说明找到了正确的处理地方。
在这里
通过交叉引用找到了对的地方。函数434EF0。
这么多的Exit,很明显就是反调试检测到了些什么东西,然后强制程序退出。可以直接看后面的算法部分。
从GetDlgItemTextA看起,第三个参数是我们的输入,标记一下。
然后往下看,哪些地方用了我们的input。
这里为什么是memset和base64的解密函数等会儿解答,从这里我们可以看到是把我们的输入经过了两次相同的处理,然后保存了起来,继续往下看。
然后,我们的inputdecode(就是经过两次相同处理后的input),分别进入了两个不同的函数处理
得到了v19和afterSM3decode(这个等会儿解释)。sub_42DF05函数是把这个值转换成了16进制(02x,不够的前置填充0),所以,SM3Hash这个字符串是64字节长度的。
v6呢,是我们的输入连接上一个啥玩意,相当于输入
这里看到,v6和我们的SM3Hash有个比较,那一定是字符串比较对吧
看到MessageBoxA是输出我们的ok成功字符串,那这个if语句也要成功
基本逻辑分析完了,我们需要解决的几个函数:为什么是base64,SM3,迷宫,还有一开始看到的莫尔斯在哪儿?程序是怎么匹配的。
memset函数戳进去,发现基本都是赋值0的语句。
而且在都是在函数调用和运算之前,那么很大可能性是初始化赋值0的语句
一般写法是memset(a,0,sizeof(a)),正好符合IDA反汇编之后的格式了
base64函数:点进去看到的是sub_434990.
看到了%4,看到了=号,看到了对不同的模数分情况讨论
见过C语言实现的base64encode和base64decode解码的会习惯这种<<和>>去操作每一个字符ascii码值,然后去相加计算的
因为是每次取4个,变成3个。所以是base64的解密过程。
SM3:会跳转到sub_437E70函数。
看到这个玩意,每个函数都点一点,因为是个加密解密模块,可能会有MAGIC(每个加解密函数独有的字段,也就是特征值)
百度一下,发现是SM3压缩加密,是一个摘要算法,弄出来就是64字节,也符合了我们的猜想,为什么转成另外一个数组
迷宫怎么猜到的:
那个if语句需要为真,v19是我们的input经过两次base64解密,再转换的(无论怎么样,都是输入)
那么这个函数和第一个参数就是我们需要认真查看的东西
函数在435400,看到了四个判断,分别是z,l,p,q,猜测是上下左右,那么第一个参数就会是地图
如何对应上呢?
分析一个p作为例子,判断的是v7+v11>=0,发现v7是一个常数-1,那么v11一定是当前坐标的某一个,然后发现v改变的是4个单位,如果是4个单位为一步的话,那么减一步就是向左了。截图如下:
同理分析我们可以得到,z下,l右,q上,p左
那么去数组里找需要的地图
刚才在函数里看到了,4个为一组,40个为行的跳跃。所以10个字符为一行。把数据扣出来得到地图
0111111110
0011111000
1000001011
11111010#1
1000101001
1010001011
1011111001
1000011100
1111000010
1111111000
有个值是不能走的在地图里用#标注,#的本来的意思是排除迷宫的多解,因为有(8,3)的检验。从(0,0)开始,走到终点?
这就是这个题的bug了!只判断了地图中不能走到1的位置,所以从左上角出发,不碰到障碍物即可,不需要走到终点,先按照作者意思来
那么,我的输入转换之后是:
zlzllllzzzppqppzzzlllzlllzllqqpqpqqqqqllq
现在就到了需要研究函数42D96A的时候了,调用的是435DE0.
首先可以看到的是判断字符是空格还是斜杠
然后对于空格的分为三类,42D7B2处理一类,42E414处理一类,另外一个函数是报错的
42D7B2戳开,调用435AA0函数,发现了这个
看到加‘0’,那一定是转换0-9
然后找到if里面的调用的435D00,看到了这个
这个26和‘a’说明了一定是在处理小写字母,我们戳开49B2A0,可以发现:和我们想要的莫尔斯联系上了
综上,我们的逻辑思路和程序的判断思路已经对上了。
输入进来先两次base64的解码,再用莫尔斯电码转成zlpq的方向走迷宫,从左上角到右上角,成功即可
看到匹配时候的负号,说明是倒着匹配的,那么说明SM3作为后缀添加上的
(可能觉得练习得很牵强,怎么就猜到了,逆向提供的只是一个框架,一个思路,剩下的靠验证就可以)
去找到zlpq的莫尔斯
于是得到了这个
s = 'zlzllllzzzppqppzzzlllzlllzllqqpqpqqqqqllq'
m = ""
for i in s:
if i == 'z':
m += '--..'
elif i == 'l':
m += '.-..'
elif i == 'p':
m += '.--.'
else:
m += '--.-'
print m
#m = '--...-..--...-...-...-...-..--..--..--...--..--.--.-.--..--.--..--..--...-...-...-..--...-...-...-..
--...-...-..--.---.-.--.--.-.--.--.---.---.---.---.-.-...-..--.-'
以这个字符作为结尾,所以放进去
再用base64两次加密,第一次得到
LS0uLi4tLi4tLS4uLi0uLi4tLi4uLS4uLi0uLi0tLi4tLS4uLS0uLi4tLS4uLS0uLS0uLS4tLS4uLS0uLS0uLi0tLi4tLS4uLi0uLi4tLi4uLS4uLS0
uLi4tLi4uLS4uLi0uLi0tLi4uLS4uLi0uLi0tLi0tLS4tLi0tLi0tLi0uLS0uLS0uLS0tLi0tLS4tLS0uLS0tLi0uLS4uLi0uLi0tLi0v
到了这里,就需要用到patch反调试了,不然没法动态OD看到SM3的加密结果