请注意,本文编写于 1419 天前,最后修改于 1419 天前,其中某些信息可能已经过时。
前几天队伍里面的大佬们交换了一下友链,我发现了一个严重的问题,师傅们人均文学带师,就我一个老二刺螈。不过能收获一群师傅的友链我还是蛮开心的,努力学习。这周除了复现了网鼎杯的题目,还看了看GKCTF(BUUCTF),题目不算太难,我不打算单独的写博客了,等我慢慢的把几道题目摸完,把我觉得有意义的知识点统一的写一篇博客吧。主要是今天再看XCTF的re题目,奈何能力有限,实在是摸不出来,想在春秋上找一道题目放松一下,然后我就发现了这道题目。题目很简单,逻辑也很清楚,但是居然把我卡了一下下。这是一道py逆向的题目,也是我re以来做的第三道py逆向。第一道是子洋师傅给的入门py签到题,第二道是比赛上遇见的py字节码的题目(具体题目可以看看子洋师傅写的wp),这道题很新颖,有兴趣的同学可以看看。第三道就是这道,这道题目的算法难度算是入门级的,但是题目并没有告诉我们这是一道py逆向。所以这篇文章主要是记录一下我对py的理解与特点判断。
我们先来看一下这道题目,下载一看,明显不是exe可执行文件,一般遇见这种情况大概率是Linux下的可执行文件。于是我将文件放入虚拟机,结果发现也无法识别。没有办法,我们将文件放入IDA,同样的无法识别。这时候我猜测,这有可能是PE头发生了损坏,导致文件无法识别。于是上winhex,嗯,这哪是文件头损坏,根本就没有文件头。
但是我们发现了一个很奇怪的现象,就是在文件后面几行居然可以看见部分的代码。到这里我才反应过来这很有可能是py的文件(具体关于py的问题放在下一个板块,这里先做题)。于是我们上工具EasyPythonDecompiler,直接对这个文件进行反编译,py有一点好处就是,可以直接看见源码,是直接可以运行的那种源码。下面就是反编译代码,逻辑很简单。
# Embedded file name: findkey
import sys
lookup = [196,
153,
149,
206,
17,
221,
10,
217,
167,
18,
36,
135,
103,
61,
111,
31,
92,
152,
21,
228,
105,
191,
173,
41,
2,
245,
23,
144,
1,
246,
89,
178,
182,
119,
38,
85,
48,
226,
165,
241,
166,
214,
71,
90,
151,
3,
109,
169,
150,
224,
69,
156,
158,
57,
181,
29,
200,
37,
51,
252,
227,
93,
65,
82,
66,
80,
170,
77,
49,
177,
81,
94,
202,
107,
25,
73,
148,
98,
129,
231,
212,
14,
84,
121,
174,
171,
64,
180,
233,
74,
140,
242,
75,
104,
253,
44,
39,
87,
86,
27,
68,
22,
55,
76,
35,
248,
96,
5,
56,
20,
161,
213,
238,
220,
72,
100,
247,
8,
63,
249,
145,
243,
155,
222,
122,
32,
43,
186,
0,
102,
216,
126,
15,
42,
115,
138,
240,
147,
229,
204,
117,
223,
141,
159,
131,
232,
124,
254,
60,
116,
46,
113,
79,
16,
128,
6,
251,
40,
205,
137,
199,
83,
54,
188,
19,
184,
201,
110,
255,
26,
91,
211,
132,
160,
168,
154,
185,
183,
244,
78,
33,
123,
28,
59,
12,
210,
218,
47,
163,
215,
209,
108,
235,
237,
118,
101,
24,
234,
106,
143,
88,
9,
136,
95,
30,
193,
176,
225,
198,
197,
194,
239,
134,
162,
192,
11,
70,
58,
187,
50,
67,
236,
230,
13,
99,
190,
208,
207,
7,
53,
219,
203,
62,
114,
127,
125,
164,
179,
175,
112,
172,
250,
133,
130,
52,
189,
97,
146,
34,
157,
120,
195,
45,
4,
142,
139]
pwda = [188,
155,
11,
58,
251,
208,
204,
202,
150,
120,
206,
237,
114,
92,
126,
6,
42]
pwdb = [53,
222,
230,
35,
67,
248,
226,
216,
17,
209,
32,
2,
181,
200,
171,
60,
108]
flag = raw_input('Input your Key:').strip()
if len(flag) != 17:
print 'Wrong Key!!'
sys.exit(1)
flag = flag[::-1] #取反
for i in range(0, len(flag)):
if ord(flag[i]) + pwda[i] & 255 != lookup[i + pwdb[i]]:
print 'Wrong Key!!'
sys.exit(1)
print 'Congratulations!!'
首先给出了三个数组,然后对输入的flag进行判断,假若满足每次判断,则输出成功,否则失败。由于逻辑很简单,直接采取爆破的手段就可以解决问题。下面就是解题代码。虽然丑但有效!
lookup = [196,
153,
149,
206,
17,
221,
10,
217,
167,
18,
36,
135,
103,
61,
111,
31,
92,
152,
21,
228,
105,
191,
173,
41,
2,
245,
23,
144,
1,
246,
89,
178,
182,
119,
38,
85,
48,
226,
165,
241,
166,
214,
71,
90,
151,
3,
109,
169,
150,
224,
69,
156,
158,
57,
181,
29,
200,
37,
51,
252,
227,
93,
65,
82,
66,
80,
170,
77,
49,
177,
81,
94,
202,
107,
25,
73,
148,
98,
129,
231,
212,
14,
84,
121,
174,
171,
64,
180,
233,
74,
140,
242,
75,
104,
253,
44,
39,
87,
86,
27,
68,
22,
55,
76,
35,
248,
96,
5,
56,
20,
161,
213,
238,
220,
72,
100,
247,
8,
63,
249,
145,
243,
155,
222,
122,
32,
43,
186,
0,
102,
216,
126,
15,
42,
115,
138,
240,
147,
229,
204,
117,
223,
141,
159,
131,
232,
124,
254,
60,
116,
46,
113,
79,
16,
128,
6,
251,
40,
205,
137,
199,
83,
54,
188,
19,
184,
201,
110,
255,
26,
91,
211,
132,
160,
168,
154,
185,
183,
244,
78,
33,
123,
28,
59,
12,
210,
218,
47,
163,
215,
209,
108,
235,
237,
118,
101,
24,
234,
106,
143,
88,
9,
136,
95,
30,
193,
176,
225,
198,
197,
194,
239,
134,
162,
192,
11,
70,
58,
187,
50,
67,
236,
230,
13,
99,
190,
208,
207,
7,
53,
219,
203,
62,
114,
127,
125,
164,
179,
175,
112,
172,
250,
133,
130,
52,
189,
97,
146,
34,
157,
120,
195,
45,
4,
142,
139]
pwda = [188,
155,
11,
58,
251,
208,
204,
202,
150,
120,
206,
237,
114,
92,
126,
6,
42]
pwdb = [53,
222,
230,
35,
67,
248,
226,
216,
17,
209,
32,
2,
181,
200,
171,
60,
108]
flag=""
for j in range(0,17):
for i in range(0,150):
if(i+pwda[j]&255)==lookup[j+pwdb[j]]:
flag+=chr(i)
print(flag[::-1])
#print('ok')
python用过的人都不会对他陌生,这是一种轻量级解释行的语言,主要的有点就是方便。Python 常被称为胶水语言,能把用其他语言编写的各模块 (尤其是 C/C++) 轻松地联结在一起,这就是python为什么会有那么多的库函数。在我学习py的时候,我觉得py的语法很简单,但是各种的库就没有那么容易了。无论是RSA的依赖库还是爬虫的"靓汤"库,一个比一个难记,在我们需要用到的时候,往往还要去看看他们的语法规则。学习c++的时候,我们都知道,一个程序需要经过1.预处理(Preprocessing),2.编译(Compilation),3.汇编(Assemble),4.链接(Linking),四个步骤才可以形成exe程序。但是c++与py是不同的。那么PY到底是怎么运行的呢?Python 在执行时,会先将 .py 文件中的源代码编译成 byte code (字节码),然后再由 Python Virtual Machine 来执行这些编译 byte code。这种方式很像java的虚拟机。这就牵扯到了几个与py有关的文件了,如果你有动手操作这道题目的话,你可能已经发现了,下载的原始文件并不可以被EasyPythonDecompiler识别,我们要将文件后缀改为pyc才可以完成反编译。那么这些文件到底有什么区别呢?
这就是py的几种主要文件格式。这就决定了python编写的程序几乎很难在进行相应的加密(可能有但是我不太清楚,之后碰见的话会再进行补充的)。之后要是发现有些文件不能以正常的方式打开的话可以尝试把它当成py。emmmmmmmmm就在刚才,子洋师傅发现了ghidra神器,成功解决了cipher的反编译问题,不说了,读代码去了。
全部评论 (共 2 条评论)