menu 牢记自己是菜
春秋实验室2017年全国大学生信息安全竞赛 填数游戏
186 浏览 | 2020-04-29 | 阅读时间: 约 3 分钟 | 分类: 春秋实验室 | 标签:
请注意,本文编写于 214 天前,最后修改于 214 天前,其中某些信息可能已经过时。

0x1 前言

由于还在隔离期,体育课取消,又有一个小小的空闲。于是我就在春秋上又摸了一道题(疯狂摸鱼),200pt题目中规中矩,其实一开始我以为是一道算法题目,所以选择了这道题目。毕竟我的算法一直都很成问题,还有虚拟机,下道题目还是摸一道虚拟机的题目吧。这道题目的风格与之前XCTF里面的魔方题目很像,整道题目的难点就在与看一堆摸不到头脑的代码然后去猜测整道题目的目的与功能。以后在做题的时候还是要留意一下题目的名称,好好的思考一下名称到底提示了什么。


0x2 开始题目

由于一开始我是想做一道算法题目的,于是就按算法题目的基本方法进行了一下尝试。首先我们查壳,运行,打开OD,拖入IDA。首先程序无壳,运行直接进入输入窗口,我们随便输入弹出来一个fail。于是我们跟进IDA,搜索一下就成功的定位到了关键的主函数。仔细看一下,发现整个程序很想一个C++的程序,简单来说就是直观视觉不是很好。我们看见有两个判断,我们进入OD定位到第一个判断,随便输入,发现有些时候可以命中断点,有些时候则不行,于是我觉得这应该是一个判断字符串是否合法的函数,所以我们先跳过它。

进入关键判断,发现这个判断是由3个小判断组成的,要想进入成功的分支,则返回值必须为1。

进入第一个函数研究一下这个函数在干嘛,首先他初始了一个V2数组,然后将输入进行了循环,如果每次都可以使V2全部清零,则可返回1。由于是指针,所以V3,V4运算结果会指向输入里面的一个值,然后再将他放入V2中。于是我写了脚本,打出了所有V2的下标,可怕的是,我发现最大的下标居然达到了300多。这里只有两种可能一个就是flag很长,另一种就是我搞错了(证明是我搞错了)。然后我继续观察,发现有一个初始数据的函数,我们把他dump出来,由于dump出来的是c数组所以我选择了C++求解。

一导出数据我就知道之前的问题出在什么地方了,又是8位保存一位数据,因为初始化的时候循环中在不停的*4。于是修改了一下脚本。

for i in range(0,9,1):
    for k in range(1,10,1):
        a=3*int(i/3)+int(k/3)
        b=3*(i%3)+k%3
        #print('V4='+str(3*int(i/3)+int(k/3)))
        #print('V3='+str(3*(i%3)+k%3))
        print('add='+str((a*9+b)))
    print('*****')


到这里我就没啥思路了,上床碎午觉了,真的是对亏这午觉。在床上流口水的时候,我猛然想起来,我之前在写代码的时候,经常喜欢使用一个数组,然后如果1出现一次就执行V[1]++最终完成计数的功能。这里的V2也是,只不过它的功能很想if(i==1)V[2]=0。所以这段判断代码就是判断在一个范围内是否存在1-9这9个数字。

仔细看看,导出数据是一个99的残缺矩阵,第一个crack则是判断一个33的方格内是否存在1-9。这里我才反应过来,这个程序能可能是一个数独游戏。后面的两个crack验证了我的想法,一个是判断一整行,一个是判断一整列。我们找一个在线的解数独的网站,解出数独。

导出数据'347589162528416937916237458261875349739164825854392716493658271175923684682741593',于是我们把这个数列带回程序验证一下,发现还是fail。头痛,是不是哪里出了问题(阴阳口气),于是打开OD,发现程序在第一个判断就跳飞了,那就是判断出来问题。

仔细看一下,发现我们需要把原先的数据全部置为0。包上flag{}此题结束。


0x3 总结

这类题型我觉得适应性有点强,要是我小时候没玩过数独,那么我可能这辈子也想不出来这道题目到底是什么。所以逆向题目还是要大开脑洞才行。还有就是这题还是太仁慈了,要是我出这道题目,我就直接把一个数独生成器嵌道题目里面,然后输入每个队伍的编码现场生成一个数独,让9*9的矩阵也给它藏起来。不说了,这道题目看看就行了,没有什么需要手操的地方,这种题目一但知道了谜底,就索然无味了。

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!