有三道题蛮简单的,现代密码那道逆向学到了好多。
login
python写的,pyinstaller打包的。直接解包改魔数反“编译”拿到源码:
# uncompyle6 version 3.7.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: login.py
# Compiled at: 2016-06-14 00:47:18
# Size of source mod 2**32: 7442 bytes
import sys
input1 = input('input something:')
if len(input1) != 14:
print('Wrong length!')
sys.exit()
else:
code = []
for i in range(13):
code.append(ord(input1[i]) ^ ord(input1[(i + 1)]))
code.append(ord(input1[13]))
a1 = code[2]
a2 = code[1]
a3 = code[0]
a4 = code[3]
a5 = code[4]
a6 = code[5]
a7 = code[6]
a8 = code[7]
a9 = code[9]
a10 = code[8]
a11 = code[10]
a12 = code[11]
a13 = code[12]
a14 = code[13]
if (a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748) & (a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258) & (a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190) & (a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136) & (a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915) & (a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298) & (a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875) & (a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784) & (a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710) & (a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376) & (a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065) & (a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687) & (a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250) & (a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317):
print('flag is GWHT{md5(your_input)}')
print('Congratulations and have fun!')
else:
print('Sorry,plz try again...')
# okay decompiling login.pyc
主要是z3解方程组,其他的小逻辑应该不需要我多说。
#s = 'a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748) & (a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258) & (a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190) & (a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136) & (a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915) & (a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298) & (a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875) & (a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784) & (a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710) & (a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376) & (a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065) & (a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687) & (a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250) & (a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317'
#print(s.replace('&', '\n'))
from z3 import *
import struct
def get_md5(b):
import hashlib
return hashlib.md5(b).hexdigest()
s = Solver()
a1 = BitVec('a1', 8)
a2 = BitVec('a2', 8)
a3 = BitVec('a3', 8)
a4 = BitVec('a4', 8)
a5 = BitVec('a5', 8)
a6 = BitVec('a6', 8)
a7 = BitVec('a7', 8)
a8 = BitVec('a8', 8)
a9 = BitVec('a9', 8)
a10 = BitVec('a10', 8)
a11 = BitVec('a11', 8)
a12 = BitVec('a12', 8)
a13 = BitVec('a13', 8)
a14 = BitVec('a14', 8)
s.add(a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748)
s.add(a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258)
s.add(a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190)
s.add(a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136)
s.add(a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915)
s.add(a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298)
s.add(a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875)
s.add(a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784)
s.add(a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710)
s.add(a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376)
s.add(a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065)
s.add(a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687)
s.add(a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250)
s.add(a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317)
print(s.check())
result = s.model()
print(result)
a = [0xffffffff]
for i in range(1, 15):
t = result[eval('a%s' % str(i))].as_long()
a.append(t)
#print(t,end=' ')
print(a)
b = [a[3], a[2], a[1], a[4], a[5], a[6], a[7], a[8], a[10], a[9], a[11], a[12], a[13], a[14]]
print(b)
c = [0] * 14
c[13] = b[13]
for i in range(12, -1, -1):
c[i] = (c[i+1] ^ b[i]) & 0x7f # 不是,python中拿来的char限制??
print(c)
for i in c:
print(hex(i)[2:], end=' ')
print()
d = b''
for i in c:
d += struct.pack('B', i)
print(d)
print(get_md5(d))
Bytecode
老生常谈的python字节码,而且这次的居然保留了变量名,很容易理解。
简单分析:
4 0 LOAD_CONST 0 (3)
3 LOAD_CONST 1 (37)
6 LOAD_CONST 2 (72)
9 LOAD_CONST 3 (9)
12 LOAD_CONST 4 (6)
15 LOAD_CONST 5 (132)
18 BUILD_LIST 6
21 STORE_NAME 0 (en)
5 24 LOAD_CONST 6 (101)
27 LOAD_CONST 7 (96)
30 LOAD_CONST 8 (23)
33 LOAD_CONST 9 (68)
36 LOAD_CONST 10 (112)
39 LOAD_CONST 11 (42)
42 LOAD_CONST 12 (107)
45 LOAD_CONST 13 (62)
48 LOAD_CONST 7 (96)
51 LOAD_CONST 14 (53)
54 LOAD_CONST 15 (176)
57 LOAD_CONST 16 (179)
60 LOAD_CONST 17 (98)
63 LOAD_CONST 14 (53)
66 LOAD_CONST 18 (67)
69 LOAD_CONST 19 (29)
72 LOAD_CONST 20 (41)
75 LOAD_CONST 21 (120)
78 LOAD_CONST 22 (60)
81 LOAD_CONST 23 (106)
84 LOAD_CONST 24 (51)
87 LOAD_CONST 6 (101)
90 LOAD_CONST 25 (178)
93 LOAD_CONST 26 (189)
96 LOAD_CONST 6 (101)
99 LOAD_CONST 27 (48)
102 BUILD_LIST 26
105 STORE_NAME 1 (output) # 输出
7 108 LOAD_CONST 28 ('welcome to GWHT2020')
111 PRINT_ITEM
112 PRINT_NEWLINE
9 113 LOAD_NAME 2 (raw_input)
116 LOAD_CONST 29 ('please input your flag:')
119 CALL_FUNCTION 1
122 STORE_NAME 3 (flag) # 输入
10 125 LOAD_NAME 3 (flag)
128 STORE_NAME 4 (str) # 副本
12 131 LOAD_NAME 5 (len)
134 LOAD_NAME 4 (str)
137 CALL_FUNCTION 1
140 STORE_NAME 6 (a)
13 143 LOAD_NAME 6 (a)
146 LOAD_CONST 30 (38)
149 COMPARE_OP 0 (<) # 长度38
152 POP_JUMP_IF_FALSE 173
14 155 LOAD_CONST 31 ('lenth wrong!')
158 PRINT_ITEM
159 PRINT_NEWLINE
15 160 LOAD_NAME 7 (exit)
163 LOAD_CONST 32 (0)
166 CALL_FUNCTION 1
169 POP_TOP
170 JUMP_FORWARD 0 (to 173)
17 >> 173 LOAD_NAME 8 (ord)
176 LOAD_NAME 4 (str)
179 LOAD_CONST 32 (0)
182 BINARY_SUBSCR # str[0]
183 CALL_FUNCTION 1 # ord(str[0])
186 LOAD_CONST 33 (2020)
189 BINARY_MULTIPLY # ord(str[0]) * 2020
190 LOAD_NAME 8 (ord)
193 LOAD_NAME 4 (str)
196 LOAD_CONST 34 (1)
199 BINARY_SUBSCR
200 CALL_FUNCTION 1
203 BINARY_ADD
204 LOAD_CONST 33 (2020) # ord(str[1]) * 2020
207 BINARY_MULTIPLY
208 LOAD_NAME 8 (ord)
211 LOAD_NAME 4 (str)
214 LOAD_CONST 35 (2)
217 BINARY_SUBSCR
218 CALL_FUNCTION 1
221 BINARY_ADD
222 LOAD_CONST 33 (2020) # ord(str[2]) * 2020
225 BINARY_MULTIPLY
226 LOAD_NAME 8 (ord)
229 LOAD_NAME 4 (str)
232 LOAD_CONST 0 (3)
235 BINARY_SUBSCR
236 CALL_FUNCTION 1
239 BINARY_ADD
240 LOAD_CONST 33 (2020)
243 BINARY_MULTIPLY
244 LOAD_NAME 8 (ord)
247 LOAD_NAME 4 (str)
250 LOAD_CONST 36 (4)
253 BINARY_SUBSCR
254 CALL_FUNCTION 1 # ord(str[3]) * 2020
257 BINARY_ADD
258 LOAD_CONST 37 (1182843538814603) # add4 == C
261 COMPARE_OP 2 (==)
264 POP_JUMP_IF_FALSE 275
18 267 LOAD_CONST 38 ('good!continue\xe2\x80\xa6\xe2\x80\xa6') #'……'
270 PRINT_ITEM
271 PRINT_NEWLINE
272 JUMP_FORWARD 15 (to 290)
20 >> 275 LOAD_CONST 39 ('bye~')
278 PRINT_ITEM
279 PRINT_NEWLINE
21 280 LOAD_NAME 7 (exit)
283 LOAD_CONST 32 (0)
286 CALL_FUNCTION 1
289 POP_TOP
23 >> 290 BUILD_LIST 0
293 STORE_NAME 9 (x)
24 296 LOAD_CONST 40 (5)
299 STORE_NAME 10 (k)
25 302 SETUP_LOOP 128 (to 433)
305 LOAD_NAME 11 (range)
308 LOAD_CONST 41 (13)
311 CALL_FUNCTION 1
314 GET_ITER
>> 315 FOR_ITER 114 (to 432) # range(5, )
318 STORE_NAME 12 (i)
26 321 LOAD_NAME 8 (ord)
324 LOAD_NAME 4 (str)
327 LOAD_NAME 10 (k)
330 BINARY_SUBSCR
331 CALL_FUNCTION 1
334 STORE_NAME 13 (b) # b = str[k]
27 337 LOAD_NAME 8 (ord)
340 LOAD_NAME 4 (str)
343 LOAD_NAME 10 (k)
346 LOAD_CONST 34 (1)
349 BINARY_ADD
350 BINARY_SUBSCR
351 CALL_FUNCTION 1
354 STORE_NAME 14 (c) # c = str[k+1]
28 357 LOAD_NAME 14 (c)
360 LOAD_NAME 0 (en)
363 LOAD_NAME 12 (i)
366 LOAD_CONST 4 (6)
369 BINARY_MODULO # TOS = TOS1 % TOS
370 BINARY_SUBSCR
371 BINARY_XOR # c ^ en[i % 6]
372 STORE_NAME 15 (a11) # a11
29 375 LOAD_NAME 13 (b)
378 LOAD_NAME 0 (en)
381 LOAD_NAME 12 (i)
384 LOAD_CONST 4 (6)
387 BINARY_MODULO
388 BINARY_SUBSCR
389 BINARY_XOR # b ^ en[i % 6]
390 STORE_NAME 16 (a22) # a22
30 393 LOAD_NAME 9 (x)
396 LOAD_ATTR 17 (append)
399 LOAD_NAME 15 (a11)
402 CALL_FUNCTION 1 # x.append(c ^ en[i % 6])
405 POP_TOP
31 406 LOAD_NAME 9 (x)
409 LOAD_ATTR 17 (append)
412 LOAD_NAME 16 (a22)
415 CALL_FUNCTION 1
418 POP_TOP # x.append(b ^ en[i % 6])
32 419 LOAD_NAME 10 (k)
422 LOAD_CONST 35 (2) # k+=2
425 INPLACE_ADD
426 STORE_NAME 10 (k)
429 JUMP_ABSOLUTE 315
>> 432 POP_BLOCK
33 >> 433 LOAD_NAME 9 (x)
436 LOAD_NAME 1 (output)
439 COMPARE_OP 2 (==)
442 POP_JUMP_IF_FALSE 453
34 445 LOAD_CONST 38 ('good!continue\xe2\x80\xa6\xe2\x80\xa6')
448 PRINT_ITEM
449 PRINT_NEWLINE
450 JUMP_FORWARD 15 (to 468)
36 >> 453 LOAD_CONST 42 ('oh,you are wrong!')
456 PRINT_ITEM
457 PRINT_NEWLINE
37 458 LOAD_NAME 7 (exit)
461 LOAD_CONST 32 (0)
464 CALL_FUNCTION 1
467 POP_TOP
39 >> 468 LOAD_NAME 5 (len)
471 LOAD_NAME 4 (str)
474 CALL_FUNCTION 1
477 STORE_NAME 18 (l)
40 480 LOAD_NAME 8 (ord)
483 LOAD_NAME 4 (str)
486 LOAD_NAME 18 (l)
489 LOAD_CONST 43 (7)
492 BINARY_SUBTRACT # l - 7
493 BINARY_SUBSCR
494 CALL_FUNCTION 1
497 STORE_NAME 19 (a1) # a1 = ord(str[l - 7])
41 500 LOAD_NAME 8 (ord)
503 LOAD_NAME 4 (str)
506 LOAD_NAME 18 (l)
509 LOAD_CONST 4 (6)
512 BINARY_SUBTRACT
513 BINARY_SUBSCR
514 CALL_FUNCTION 1
517 STORE_NAME 20 (a2) # a2 = ord(str[l - 6])
42 520 LOAD_NAME 8 (ord)
523 LOAD_NAME 4 (str)
526 LOAD_NAME 18 (l)
529 LOAD_CONST 40 (5)
532 BINARY_SUBTRACT
533 BINARY_SUBSCR
534 CALL_FUNCTION 1
537 STORE_NAME 21 (a3) # a3 = ord(str[l - 5])
43 540 LOAD_NAME 8 (ord)
543 LOAD_NAME 4 (str)
546 LOAD_NAME 18 (l)
549 LOAD_CONST 36 (4)
552 BINARY_SUBTRACT
553 BINARY_SUBSCR
554 CALL_FUNCTION 1
557 STORE_NAME 22 (a4)
44 560 LOAD_NAME 8 (ord)
563 LOAD_NAME 4 (str)
566 LOAD_NAME 18 (l)
569 LOAD_CONST 0 (3)
572 BINARY_SUBTRACT
573 BINARY_SUBSCR
574 CALL_FUNCTION 1
577 STORE_NAME 23 (a5)
45 580 LOAD_NAME 8 (ord)
583 LOAD_NAME 4 (str)
586 LOAD_NAME 18 (l)
589 LOAD_CONST 35 (2)
592 BINARY_SUBTRACT
593 BINARY_SUBSCR
594 CALL_FUNCTION 1
597 STORE_NAME 24 (a6) # a6 = ord(str[l - 2])
46 600 LOAD_NAME 19 (a1)
603 LOAD_CONST 0 (3)
606 BINARY_MULTIPLY
607 LOAD_NAME 20 (a2)
610 LOAD_CONST 35 (2)
613 BINARY_MULTIPLY
614 BINARY_ADD
615 LOAD_NAME 21 (a3)
618 LOAD_CONST 40 (5)
621 BINARY_MULTIPLY
622 BINARY_ADD
623 LOAD_CONST 44 (1003)
626 COMPARE_OP 2 (==)
629 POP_JUMP_IF_FALSE 807
47 632 LOAD_NAME 19 (a1)
635 LOAD_CONST 36 (4)
638 BINARY_MULTIPLY
639 LOAD_NAME 20 (a2)
642 LOAD_CONST 43 (7)
645 BINARY_MULTIPLY
646 BINARY_ADD
647 LOAD_NAME 21 (a3)
650 LOAD_CONST 3 (9)
653 BINARY_MULTIPLY
654 BINARY_ADD
655 LOAD_CONST 45 (2013)
658 COMPARE_OP 2 (==)
661 POP_JUMP_IF_FALSE 807
48 664 LOAD_NAME 19 (a1)
667 LOAD_NAME 20 (a2)
670 LOAD_CONST 46 (8)
673 BINARY_MULTIPLY
674 BINARY_ADD
675 LOAD_NAME 21 (a3)
678 LOAD_CONST 35 (2)
681 BINARY_MULTIPLY
682 BINARY_ADD
683 LOAD_CONST 47 (1109)
686 COMPARE_OP 2 (==)
689 POP_JUMP_IF_FALSE 804
49 692 LOAD_NAME 22 (a4)
695 LOAD_CONST 0 (3)
698 BINARY_MULTIPLY
699 LOAD_NAME 23 (a5)
702 LOAD_CONST 35 (2)
705 BINARY_MULTIPLY
706 BINARY_ADD
707 LOAD_NAME 24 (a6)
710 LOAD_CONST 40 (5)
713 BINARY_MULTIPLY
714 BINARY_ADD
715 LOAD_CONST 48 (671)
718 COMPARE_OP 2 (==)
721 POP_JUMP_IF_FALSE 801
50 724 LOAD_NAME 22 (a4)
727 LOAD_CONST 36 (4)
730 BINARY_MULTIPLY
731 LOAD_NAME 23 (a5)
734 LOAD_CONST 43 (7)
737 BINARY_MULTIPLY
738 BINARY_ADD
739 LOAD_NAME 24 (a6)
742 LOAD_CONST 3 (9)
745 BINARY_MULTIPLY
746 BINARY_ADD
747 LOAD_CONST 49 (1252)
750 COMPARE_OP 2 (==)
753 POP_JUMP_IF_FALSE 798
51 756 LOAD_NAME 22 (a4)
759 LOAD_NAME 23 (a5)
762 LOAD_CONST 46 (8)
765 BINARY_MULTIPLY
766 BINARY_ADD
767 LOAD_NAME 24 (a6)
770 LOAD_CONST 35 (2)
773 BINARY_MULTIPLY
774 BINARY_ADD
775 LOAD_CONST 50 (644)
778 COMPARE_OP 2 (==)
781 POP_JUMP_IF_FALSE 795
52 784 LOAD_CONST 51 ('congraduation!you get the right flag!')
787 PRINT_ITEM
788 PRINT_NEWLINE
789 JUMP_ABSOLUTE 795
792 JUMP_ABSOLUTE 798
>> 795 JUMP_ABSOLUTE 801
>> 798 JUMP_ABSOLUTE 804
>> 801 JUMP_ABSOLUTE 807
>> 804 JUMP_FORWARD 0 (to 807)
>> 807 LOAD_CONST 52 (None)
810 RETURN_VALUE
分为两部分,前面26个字符用下面脚本求:
en = [3, 37, 72, 9, 6, 132]
output = [101, 96, 23, 68, 112, 42, 107, 62, 96, 53, 176, 179, 98, 53, 67, 29, 41, 120, 60, 106, 51, 101, 178, 189, 101, 48]
k = 0
flag_pre = ''
for i in range(13):
a, b = en[i % 6] ^ output[k], en[i % 6] ^ output[k+1]
flag_pre += chr(b) + chr(a)
#print(chr(a), chr(b),end=' ')
k += 2
print(flag_pre)
后面的6个字节要解方程组,数据不多,直接matlab解:
>> A = [3,2,5;
4,7,9;
1,8,2]
A =
3 2 5
4 7 9
1 8 2
>> B = [1003;2013;1109]
B =
1003
2013
1109
>> A\B
ans =
97
101
102
'''
'''
>> C = [3,2,5;
4,7,9;
1,8,2]
C =
3 2 5
4 7 9
1 8 2
>> D = [671;1252;644]
D =
671
1252
644
>> C\D
ans =
102
55
51
babyre
输入两个字符串,第一个是aes_key,第二个是flag.
首先拿到des的key和cipher,解出aes_key.
然后从最终的密文出发,逆两个小逻辑,拿到aes的密文。使用上一步的aes_key,解出flag.
说起来流程很简单,然而我第一次接触在python中使用现代密码,做了整整11小时58分钟。
对了,最后一个小逻辑我逆不出来(或许本身就是不可逆的?),所以直接dfs.
枚举的所有可能的结果中,倒数第六个是flag。md5后提交即可。
from Crypto.Cipher import DES, AES
import struct, copy
def des_cbc_decode(cipher, key, iv): # DES_CBC解密,获取AES密钥
crypto = DES.new(key, DES.MODE_CBC, iv)
plain = crypto.decrypt(cipher)
return plain
def dfs_get_cipher2(k): # 递归枚举所可能的密文
if k == 0:
cipher2_list.append(copy.deepcopy(cipher2))
return
for j in range(0x100):
if final[k-1] == ((2 * (j ^ 0x13) + 7) ^ (j % 9 + cipher2[k] + 2)) & 0xff:
cipher2[k-1] = j
dfs_get_cipher2(k-1)
def get_cipher1(cipher2): # 再次解密
cipher1 = []
for i in range(32):
j = 0
t = cipher2[i]
while (j < i // 4):
t = t ^ cipher2[j]
j += 1
cipher1.append(t)
return cipher1
def list2bytes(cipher1): # 列表转换成字节流,此即AES密文
aes_cipher = b''
for i in range(32):
aes_cipher += struct.pack('B', cipher1[i])
return aes_cipher
def aes_decode(cipher, key): # AES解密flag
aes_crypto = AES.new(key, AES.MODE_ECB)
plain = aes_crypto.decrypt(cipher)
print(plain)
# DES解密得AES密钥
byte_6040C0 = b'\n\xf4\xee\xc8B\x8a\x9b\xdb\xa2&o\xee\xee\xe0\xd8\xa2\x01\x15 \x1f\x0e\x19L%R\x13\n\x15\x16 Mf\x83\x94L\x17U[\x17-\x0cKT\x17,\x0b\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
des_cipher = byte_6040C0[:16]
des_key = b'\xad\x52\xf2\x4c\xe3\x2c\x20\xd6' # 执行DES_string_to_key()后从内存中dump得到
iv = b'\x00'*8
aes_key = des_cbc_decode(des_cipher, des_key, iv)
print('aes_key:', aes_key)
# 最后的AES密文
byte_604100 = b'\xbd\xad\xb4\x84\x10c\xb3\xe1\xc6\x84-o\xba\x88t\xc4\x902\xea.\xc6(ep\xc9ux\xa0\x0b\x9f\xa6\x000\xe4\xd2\xc3\xefu\xed\xa8\xe1\xa1s\x81\xe2\xe9\xab\xc8'
final = byte_604100[:31] + struct.pack('B', 196)
print('final_cipher:', final)
# 递归枚举所有可能的cipher2
final = b'\xbd\xad\xb4\x84\x10c\xb3\xe1\xc6\x84-o\xba\x88t\xc4\x902\xea.\xc6(ep\xc9ux\xa0\x0b\x9f\xa6\xc4'
cipher2 = [-1] * 32
cipher2[31] = final[31]
cipher2_list = []
dfs_get_cipher2(31)
print('cipher2_list: ')
print(cipher2_list)
print()
# 解密得cipher1
cipher1_list = []
for cipher2 in cipher2_list:
cipher1_list.append(get_cipher1(cipher2))
print('cipher1_list: ')
print(cipher1_list)
print()
# AES解密
for i in range(len(cipher1_list)):
aes_cipher = list2bytes(cipher1_list[i])
aes_decode(aes_cipher, aes_key)
easyre
三个加密函数,分别是:
- base64
- 分成4块,然后交换位置
- 凯撒,参数为3
很简单,base64也没换表。就签到题难度。
def decode3(s):
ss = ''
for i in s:
n = ord(i)
if (48 <= n <= 57):
t = (n - 48 - 3 + 10) % 10 + 48
elif (97 <= n <= 122):
t = (n - 97 -3 + 26) % 26 + 97
elif (65 <= n <= 90):
t = (n - 65 -3 + 26) % 26 + 65
else:
t = n
ss += chr(t)
print(ss)
return ss
def decode2(s):
ss = s[13:26] + s[39:52] + s[0:13] + s[26:39]
print(ss)
return ss
def decode1(s):
import base64
ss = base64.b64decode(s)
print(ss)
s = 'EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
print(s)
decode1(decode2(decode3(s)))