第九届全国电信和互联网行业网络安全管理技能竞赛

在最后10分钟拿到这个题的二血,hhh。

Re

gogogo

image-20201106230503034

从文件名字及程序中的字符串:runtime~可以知道这是一个go语言写的程序,然后使用IDAGolangHelper脚本还原程序的符号表。这下从函数名称可以极大的减少工作量。

找到main函数,简单分析一下可以知道这是一个虚拟机类型的题目:

image-20201106210626460

提取出opcode表:

image-20201106210922720

知道了操作码的功能,从7的数据个数可以知道我们要输入的字符长度是24,5 ~其实就是一个取下个数据值。然后对于code = 4,,1*1的操作虽然值没改变但其实在改变取数据index。而对于操作码5 1 4算是多余的类似花指令吧。如果对这个十分熟悉之后可以直接根据opcode和密文逆向flag的,但我还是调试单步调试来做的:

image-20201106212942973

image-20201106212508124

整理了前面几个字符的笔记:后面还有对数据乘法加法的操作,直接调试着走就是。

1
2
3
input[0],input[1] = -input[1], input[2] = -input[2], input[3]*input[4]*input[5],
f,l,a,g,{I
从开始的几个字符操作调试得出结果flag{,又从input[3]*input[4]*input[5] == E1CA5h, 算出input[5] = 'I'

这里有一个小技巧:调试时每次输入一个递增的数据,这样还在调试的dump窗口看我们的数据有没有变化。

最后调试完一遍得到flag:flag{I_am_the_last_one}

赛后我也直接根据操作码走了一遍程序的流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[5, 1635, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1,
5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5,
1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1,
5, 1, 5, 3, 5, 1, 5, 2, 5, 1, 5, 2, 9,
5, 1, 5, 1, 5, 1, 5, 1, 9, 5, 1, 5, 1,
5, 1, 5, 1, 5, 1, 5, 1, 7, 5, 1, 7, 2,
5, 1, 7, 2, 5, 1, 7, 5, 1, 4, 7, 4, 5,
1, 4, 7, 4, 5, 1, 2, 7, 4, 5, 1, 5, 1,
5, 1, 5, 1, 7, 4, 5, 1, 4, 3, 7, 5, 1,
5, 1, 5, 1, 3, 3, 3, 5, 1, 4, 2, 3, 4,
3, 7, 5, 1, 5, 1, 5, 1, 5, 1, 4, 7, 5,
1, 5, 1, 5, 1, 4, 5, 1, 4, 3, 4, 7, 5,
1, 5, 1, 5, 1, 4, 5, 1, 7, 5, 1, 5, 1,
5, 1, 4, 5, 1, 4, 7, 4, 3, 5, 1, 7, 5,
1, 5, 1, 5, 1, 4, 3, 5, 1, 3, 7, 5, 1,
5, 1, 4, 5, 1, 3, 5, 1, 3, 7, 5, 1, 5,
1, 5, 1, 4, 5, 1, 7, 5, 1, 5, 1, 5, 1,
5, 1, 4, 5, 1, 7, 5, 1, 5, 1, 5, 1, 5,
1, 4, 3, 5, 1, 9, 3, 4, 7, 5, 1, 5, 1, 5,
1, 3, 5, 1, 4, 3, 7, 5, 1, 5, 1, 5, 1, 5,
1, 4, 3, 4, 5, 1, 4, 3, 4, 7, 5, 1, 5, 1,
5, 1, 4, 3, 5, 1, 4, 7, 5, 1, 5, 1, 5, 1,
5, 1, 4, 3, 4, 5, 2222, 8, 0]
//7:input, 2:-, 3:+, 4:*
-------------本文结束感谢您的阅读-------------