前言
一道简单题,签到题难度,但是排在了第七题的位置,简简单单的一道Go逆向,思路还是比较新,作者重写了标准库的函数,做了个简单的校验,但是静态就可以看出来逻辑,甚至通过校验部分可以直接猜到出题思路,以至于最终没有分析完就得到了答案。至于没有分析完的,也懒得分析了,就是个需要花费至多十多分钟去分析的一个赋值操作,wp在看雪发了一份,很开心混了10rank值,博客上也备份一篇(改都没改)
今天晚些时候,key告诉我说我的分析文章上了看雪公众号了!!!是真的!而且key第四题的wp也上了公众号,哈哈哈哈哈,太秀了简直是,真的是没想到,可能是大佬觉得这题太简单了,所以就不想写太细,于是我们这些新手就有了机会,太感动了,我爱死看雪了!给了我极大的信心!哈哈哈哈,我好开心啊!真想把第八题也做出来!
Step1
运行程序,随便进行一些输入,根据反馈可以得出:
Step2
将程序拖入IDA,发现是Go写的。所以先用Go的反编译插件解析一遍。然后进入main_main查看主要逻辑:
- 最早弹出的提示”请输入7位数字”,不在循环内,因此只会在第一次打开程序时提示一次
- 蓝色方框位于大循环中的第一个小循环里,通过读取输入的字符串,并判断字符串的长度是否为7,否则就会在循环里提示”请输入长度7”。
- 橙色方框在一个for循环中对字符串进行校验,若存在数字之外的字符,则会提示”请输入数字”
- 若字符串均为数字,则会在for循环执行结束后,从LABEL_11进入粉色方框
Step3
在前一步中,存在一个问题,按照正确逻辑,当程序进入粉色方框后,fmt_Println_0
应该打印出”fail!!!”的提示,但实际并没有任何回显,接下来就看一看这个fmt_Println_0
通过与标准库中的
fmt_Println
比较,可以发现fmt_Println_0
多了一大段的校验判断过程在x64dbg中找到最后一个if的位置,将这里的jne给patch掉,再运行一遍看看情况如何
可以看到提示了”success”,也就意味着,输入的flag需要能够过掉上方的校验即可
Step4
通过交叉引用,可以找到给变量赋值的地方,发现位于
fmt_Print
中,也就是打印提示”->”的地方。由于这些变量的地址是连续的,所以可以直接转换为数组来看(默认名为fmt_Abc)此时再来看校验的地方就清晰很多,可以将其转换为一个4X4的矩阵,然后就可以得到如下的逻辑:
这里需要保证,矩阵每行每列,以及框出的4个四宫格的元素之和,必须为10。这里刚好有7个0,而要求输入的字符串刚好是7位数字,所以这里猜测是用输入的7位数字,填充这7个0的位置,从而满足校验这里通过交叉引用看一下这些原先值为0的位置被哪些地方修改过,最终会发现,在
bufio__ptr_Reader_ReadString
中有一段用输入字符串给fmt_Abc数组元素赋值的操作,也就验证了之前的猜想。最终,根据4X4矩阵填充的值,可以得到flag字符串为”4224131”