武汉加油!
Reverse
1. Classic_CrackMe
file查看文件类型
.net的逆向可以用dnSpy
核心代码为
private void button1_Click(object sender, EventArgs e)
{
if (this.status == 1)
{
MessageBox.Show("你已经激活成功啦,快去提交flag吧~~~");
return;
}
string text = this.textBox1.Text;
if (text.Length != 46 || text.IndexOf("hgame{") != 0 || text.IndexOf("}") != 45)
{
MessageBox.Show("Illegal format");
return;
}
string base64iv = text.Substring(6, 24);
string str = text.Substring(30, 15);
try
{
Aes aes = new Aes("SGc0bTNfMm8yMF9XZWVLMg==", base64iv);
Aes aes2 = new Aes("SGc0bTNfMm8yMF9XZWVLMg==", "MFB1T2g5SWxYMDU0SWN0cw==");
string text2 = aes.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I=");
if (text2.Equals("Same_ciphertext_"))
{
byte[] array = new byte[16];
Array.Copy(aes2.EncryptToByte(text2 + str), 16, array, 0, 16);
if (Convert.ToBase64String(array).Equals("dJntSWSPWbWocAq4yjBP5Q=="))
{
MessageBox.Show("注册成功!");
this.Text = "已激活,欢迎使用!";
this.status = 1;
}
else
{
MessageBox.Show("注册失败!\nhint: " + aes2.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I="));
}
}
else
{
MessageBox.Show("注册失败!\nhint: " + aes2.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I="));
}
}
catch
{
MessageBox.Show("注册失败!");
}
}
flag由字符串base64iv和str拼接而成。
AES加密类型可看出为CBC加密,填补方式为PKCS7.
例子中的第一次AES加密明文长度为块大小,填充一个与块大小相同,内容为块大小的数据,因而第二次加密数据的明文和密文均不需要进行分析。根据AES-CBC加密的流程,先将明文P与初始化向量IV进行异或,再进行AES加密置换,解密流程为先将密文C进行AES解密置换,再与初始化向量IV进行异或。密文已知,只取前16字节(块大小)。
from Crypto.Cipher import AES
import base64
def xor(s1, s2):
return bytes(map( (lambda x: x[0]^x[1]), zip(s1, s2) ))
key = base64.b64decode(b"SGc0bTNfMm8yMF9XZWVLMg==")
cipher = base64.b64decode(b"mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I=")
aes = AES.new(key, AES.MODE_ECB)
msg = aes.decrypt(cipher)[:16]
target = b"Same_ciphertext_"
iv = xor(msg, target)
即可获得IV。
第二次加密总共两块,已知第二块的密文,第一块的明文,求第二块的明文。要注意解密后的为填补后的(15填补为16),应去除最后一字节。
aes2 = AES.new(key, AES.MODE_CBC, base64.b64decode(b"MFB1T2g5SWxYMDU0SWN0cw=="))
cipher1 = aes2.encrypt(target)
msg = aes.decrypt(base64.b64decode(b"dJntSWSPWbWocAq4yjBP5Q=="))
综合一下,即可得到对应的flag
print(b"hgame{" + base64.b64encode(iv) + xor(msg, cipher1)[:-1] + b"}")
2. babyPy
https://docs.python.org/zh-cn/3/library/dis.html
根据官方文档,可还原Python字节码。
def encrypt(OOo):
O0O = OOo[::-1]
O0o = list(O0O)
for O0 in range(1, len(O0o)):
Oo = O0o[O0 - 1] ^ O0o[O0]
O0o[O0] = Oo
O = bytes(O0o)
return O.hex()
因此,脚本如下
from binascii import unhexlify
def encrypt(OOo):
O0O = OOo[::-1]
O0o = list(O0O)
for O0 in range(1, len(O0o)):
Oo = O0o[O0 - 1] ^ O0o[O0]
O0o[O0] = Oo
O = bytes(O0o)
return O.hex()
def decrypt(bhstr):
bhstr = unhexlify(bhstr)
bhstr = list(bhstr)
for i in range(len(bhstr)-1, 0, -1):
bhstr[i] = bhstr[i-1] ^ bhstr[i]
return bytes(bhstr[::-1])
print(decrypt('7d037d045717722d62114e6a5b044f2c184c3f44214c2d4a22'))
3. babyPyc
使用uncompyle6反编译代码失败。
# uncompyle6 version 3.6.2
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: task.py
# Size of source mod 2**32: 1056 bytes
# file babyPyc_task_a1f4a8cf21.cpython-37.pyc
# --- This code section failed: ---
3 0 JUMP_ABSOLUTE 2 'to 2'
2 LOAD_CONST 0
4 LOAD_CONST None
6 IMPORT_NAME os
8 STORE_NAME os
10 LOAD_CONST 0
12 LOAD_CONST None
14 IMPORT_NAME sys
4 16 STORE_NAME sys
18 LOAD_CONST 0
20 LOAD_CONST ('b64encode',)
22 IMPORT_NAME base64
24 IMPORT_FROM b64encode
26 STORE_NAME b64encode
6 28 POP_TOP
30 LOAD_CONST b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'
8 32 STORE_GLOBAL O0o
34 LOAD_CODE
36 LOAD_STR 'getFlag'
38 MAKE_FUNCTION_0 ''
16 40 STORE_NAME getFlag
42 LOAD_NAME getFlag
44 CALL_FUNCTION_0 0 ''
18 46 STORE_NAME flag
48 LOAD_NAME flag
50 LOAD_CONST None
52 LOAD_CONST 6
54 BUILD_SLICE_2 2
56 BINARY_SUBSCR
58 LOAD_CONST b'hgame{'
60 COMPARE_OP !=
62 POP_JUMP_IF_TRUE 76 'to 76'
64 LOAD_NAME flag
66 LOAD_CONST -1
68 BINARY_SUBSCR
70 LOAD_CONST 125
72 COMPARE_OP !=
19 74 POP_JUMP_IF_FALSE 94 'to 94'
76_0 COME_FROM 62 '62'
76 LOAD_NAME print
78 LOAD_STR 'Incorrect format!'
80 CALL_FUNCTION_1 1 ''
20 82 POP_TOP
84 LOAD_NAME sys
86 LOAD_METHOD exit
88 LOAD_CONST 1
90 CALL_METHOD_1 1 ''
22 92 POP_TOP
94_0 COME_FROM 74 '74'
94 LOAD_NAME flag
96 LOAD_CONST 6
98 LOAD_CONST -1
100 BUILD_SLICE_2 2
102 BINARY_SUBSCR
23 104 STORE_NAME raw_flag
106 LOAD_NAME len
108 LOAD_NAME flag
110 CALL_FUNCTION_1 1 ''
112 LOAD_CONST 7
114 BINARY_SUBTRACT
116 LOAD_CONST 36
118 COMPARE_OP !=
24 120 POP_JUMP_IF_FALSE 140 'to 140'
122 LOAD_NAME print
124 LOAD_STR 'Wrong length!'
126 CALL_FUNCTION_1 1 ''
25 128 POP_TOP
130 LOAD_NAME sys
132 LOAD_METHOD exit
134 LOAD_CONST 2
136 CALL_METHOD_1 1 ''
27 138 POP_TOP
140_0 COME_FROM 120 '120'
140 LOAD_NAME raw_flag
142 LOAD_CONST None
144 LOAD_CONST None
146 LOAD_CONST -1
148 BUILD_SLICE_3 3
150 BINARY_SUBSCR
28 152 STORE_NAME raw_flag
154 LOAD_LISTCOMP '>'
156 LOAD_STR ''
158 MAKE_FUNCTION_0 ''
160 LOAD_NAME range
162 LOAD_CONST 6
164 CALL_FUNCTION_1 1 ''
166 GET_ITER
168 CALL_FUNCTION_1 1 ''
30 170 STORE_NAME ciphers
172 SETUP_LOOP 260 'to 260'
174 LOAD_NAME range
176 LOAD_CONST 5
178 CALL_FUNCTION_1 1 ''
180 GET_ITER
182 FOR_ITER 258 'to 258'
31 184 STORE_NAME row
186 SETUP_LOOP 256 'to 256'
188 LOAD_NAME range
190 LOAD_CONST 6
192 CALL_FUNCTION_1 1 ''
194 GET_ITER
196 FOR_ITER 254 'to 254'
32 198 STORE_NAME col
200 LOAD_NAME ciphers
202 LOAD_NAME row
204 BINARY_SUBSCR
206 LOAD_NAME col
208 DUP_TOP_TWO
210 BINARY_SUBSCR
212 LOAD_NAME ciphers
214 LOAD_NAME row
216 LOAD_CONST 1
218 BINARY_ADD
220 BINARY_SUBSCR
222 LOAD_NAME col
224 BINARY_SUBSCR
226 INPLACE_ADD
228 ROT_THREE
33 230 STORE_SUBSCR
232 LOAD_NAME ciphers
234 LOAD_NAME row
236 BINARY_SUBSCR
238 LOAD_NAME col
240 DUP_TOP_TWO
242 BINARY_SUBSCR
244 LOAD_CONST 256
246 INPLACE_MODULO
248 ROT_THREE
250 STORE_SUBSCR
252 JUMP_BACK 196 'to 196'
254 POP_BLOCK
256_0 COME_FROM_LOOP 186 '186'
256 JUMP_BACK 182 'to 182'
35 258 POP_BLOCK
260_0 COME_FROM_LOOP 172 '172'
260 LOAD_CONST b''
36 262 STORE_NAME cipher
264 SETUP_LOOP 336 'to 336'
266 LOAD_NAME range
268 LOAD_CONST 6
270 CALL_FUNCTION_1 1 ''
272 GET_ITER
274 FOR_ITER 334 'to 334'
37 276 STORE_NAME row
278 LOAD_CONST 0
38 280 STORE_NAME col
282 SETUP_LOOP 330 'to 330'
284 LOAD_NAME col
286 LOAD_CONST 6
288 COMPARE_OP <
290 POP_JUMP_IF_FALSE 328 'to 328'
294 LOAD_NAME cipher
296 LOAD_NAME bytes
298 LOAD_NAME ciphers
300 LOAD_NAME row
302 BINARY_SUBSCR
304 LOAD_NAME col
306 BINARY_SUBSCR
308 BUILD_LIST_1 1
310 CALL_FUNCTION_1 1 ''
312 INPLACE_ADD
40 314 STORE_NAME cipher
316 LOAD_NAME col
318 LOAD_CONST 1
320 INPLACE_ADD
322 STORE_NAME col
324 JUMP_BACK 284 'to 284'
328_0 COME_FROM 290 '290'
328 POP_BLOCK
330_0 COME_FROM_LOOP 282 '282'
330 JUMP_BACK 274 'to 274'
42 334 POP_BLOCK
336_0 COME_FROM_LOOP 264 '264'
336 LOAD_NAME b64encode
338 LOAD_NAME cipher
340 CALL_FUNCTION_1 1 ''
44 342 STORE_NAME cipher
344 LOAD_NAME cipher
346 LOAD_GLOBAL O0o
348 COMPARE_OP ==
350 POP_JUMP_IF_FALSE 364 'to 364'
354 LOAD_NAME print
356 LOAD_STR 'Great, this is my flag.'
358 CALL_FUNCTION_1 1 ''
360 POP_TOP
47 362 JUMP_FORWARD 372 'to 372'
364_0 COME_FROM 350 '350'
364 LOAD_NAME print
366 LOAD_STR 'Wrong flag.'
368 CALL_FUNCTION_1 1 ''
370 POP_TOP
372_0 COME_FROM 362 '362'
Parse error at or near `None' instruction at offset -1
根据以上,可还原出部分代码。
import os
import sys
from base64 import b64encode
O0o = b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'
flag = getFlag()
if b'hgame{' != flag[:6] or flag[-1] != b'}':
print('Incorrect format!')
sys.exit(1)
raw_flag = flag[6:-1]
if len(flag) - 7 != 36:
print('Wrong length!')
sys.exit(2)
raw_flag = raw_flag[::-1]
# ciphers = 一个列表推导式
for row in range(5):
for col in range(6):
ciphers[row][col] += ciphers[row + 1][col]
ciphers[row][col] %= 256
cipher = b''
for row in range(6):
col = 0
while col < 6:
cipher += bytes([ciphers[row][col]])
col += 1
# assert O0o == b64encode(cipher)
中间的列表推导式部分无法使用uncompyle6查看,但可使用dis和marshal来反编译代码。
结合资料可知,3.7的pyc文件,头部大小为16字节,因此略过16字节,获得的字节码对象如下。
>>> import dis, marshal
>>> f = open("babyPyc_task_a1f4a8cf21.cpython-37.pyc", "rb")
>>> f.read(16)
b'B\r\r\n\x00\x00\x00\x00\xdaR%^ \x04\x00\x00'
>>> code = marshal.load(f)
>>> code
at 0x000001E7C7F45C90, file "task.py", line 3>
>>> dis.dis(code)
3 0 JUMP_ABSOLUTE 2
>> 2 LOAD_CONST 0 (0)
4 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (os)
8 STORE_NAME 0 (os)
10 LOAD_CONST 0 (0)
12 LOAD_CONST 1 (None)
14 IMPORT_NAME 1 (sys)
4 16 STORE_NAME 1 (sys)
18 LOAD_CONST 0 (0)
20 LOAD_CONST 2 (('b64encode',))
22 IMPORT_NAME 2 (base64)
24 IMPORT_FROM 3 (b64encode)
26 STORE_NAME 3 (b64encode)
6 28 POP_TOP
30 LOAD_CONST 3 (b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J')
8 32 STORE_GLOBAL 4 (O0o)
34 LOAD_CONST 4 ()
36 LOAD_CONST 5 ('getFlag')
38 MAKE_FUNCTION 0
16 40 STORE_NAME 5 (getFlag)
42 LOAD_NAME 5 (getFlag)
44 CALL_FUNCTION 0
18 46 STORE_NAME 6 (flag)
48 LOAD_NAME 6 (flag)
50 LOAD_CONST 1 (None)
52 LOAD_CONST 6 (6)
54 BUILD_SLICE 2
56 BINARY_SUBSCR
58 LOAD_CONST 7 (b'hgame{')
60 COMPARE_OP 3 (!=)
62 POP_JUMP_IF_TRUE 76
64 LOAD_NAME 6 (flag)
66 LOAD_CONST 8 (-1)
68 BINARY_SUBSCR
70 LOAD_CONST 9 (125)
72 COMPARE_OP 3 (!=)
19 74 POP_JUMP_IF_FALSE 94
>> 76 LOAD_NAME 7 (print)
78 LOAD_CONST 10 ('Incorrect format!')
80 CALL_FUNCTION 1
20 82 POP_TOP
84 LOAD_NAME 1 (sys)
86 LOAD_METHOD 8 (exit)
88 LOAD_CONST 11 (1)
90 CALL_METHOD 1
22 92 POP_TOP
>> 94 LOAD_NAME 6 (flag)
96 LOAD_CONST 6 (6)
98 LOAD_CONST 8 (-1)
100 BUILD_SLICE 2
102 BINARY_SUBSCR
23 104 STORE_NAME 9 (raw_flag)
106 LOAD_NAME 10 (len)
108 LOAD_NAME 6 (flag)
110 CALL_FUNCTION 1
112 LOAD_CONST 12 (7)
114 BINARY_SUBTRACT
116 LOAD_CONST 13 (36)
118 COMPARE_OP 3 (!=)
24 120 POP_JUMP_IF_FALSE 140
122 LOAD_NAME 7 (print)
124 LOAD_CONST 14 ('Wrong length!')
126 CALL_FUNCTION 1
25 128 POP_TOP
130 LOAD_NAME 1 (sys)
132 LOAD_METHOD 8 (exit)
134 LOAD_CONST 15 (2)
136 CALL_METHOD 1
27 138 POP_TOP
>> 140 LOAD_NAME 9 (raw_flag)
142 LOAD_CONST 1 (None)
144 LOAD_CONST 1 (None)
146 LOAD_CONST 8 (-1)
148 BUILD_SLICE 3
150 BINARY_SUBSCR
28 152 STORE_NAME 9 (raw_flag)
154 LOAD_CONST 16 ( at 0x000001E7C7F280C0, file "task.py", line 28>)
156 LOAD_CONST 17 ('')
158 MAKE_FUNCTION 0
160 LOAD_NAME 11 (range)
162 LOAD_CONST 6 (6)
164 CALL_FUNCTION 1
166 GET_ITER
168 CALL_FUNCTION 1
30 170 STORE_NAME 12 (ciphers)
172 SETUP_LOOP 86 (to 260)
174 LOAD_NAME 11 (range)
176 LOAD_CONST 18 (5)
178 CALL_FUNCTION 1
180 GET_ITER
>> 182 FOR_ITER 74 (to 258)
31 184 STORE_NAME 13 (row)
186 SETUP_LOOP 68 (to 256)
188 LOAD_NAME 11 (range)
190 LOAD_CONST 6 (6)
192 CALL_FUNCTION 1
194 GET_ITER
>> 196 FOR_ITER 56 (to 254)
32 198 STORE_NAME 14 (col)
200 LOAD_NAME 12 (ciphers)
202 LOAD_NAME 13 (row)
204 BINARY_SUBSCR
206 LOAD_NAME 14 (col)
208 DUP_TOP_TWO
210 BINARY_SUBSCR
212 LOAD_NAME 12 (ciphers)
214 LOAD_NAME 13 (row)
216 LOAD_CONST 11 (1)
218 BINARY_ADD
220 BINARY_SUBSCR
222 LOAD_NAME 14 (col)
224 BINARY_SUBSCR
226 INPLACE_ADD
228 ROT_THREE
33 230 STORE_SUBSCR
232 LOAD_NAME 12 (ciphers)
234 LOAD_NAME 13 (row)
236 BINARY_SUBSCR
238 LOAD_NAME 14 (col)
240 DUP_TOP_TWO
242 BINARY_SUBSCR
244 LOAD_CONST 19 (256)
246 INPLACE_MODULO
248 ROT_THREE
250 STORE_SUBSCR
252 JUMP_ABSOLUTE 196
>> 254 POP_BLOCK
>> 256 JUMP_ABSOLUTE 182
35 >> 258 POP_BLOCK
>> 260 LOAD_CONST 20 (b'')
36 262 STORE_NAME 15 (cipher)
264 SETUP_LOOP 70 (to 336)
266 LOAD_NAME 11 (range)
268 LOAD_CONST 6 (6)
270 CALL_FUNCTION 1
272 GET_ITER
>> 274 FOR_ITER 58 (to 334)
37 276 STORE_NAME 13 (row)
278 LOAD_CONST 0 (0)
38 280 STORE_NAME 14 (col)
282 SETUP_LOOP 46 (to 330)
>> 284 LOAD_NAME 14 (col)
286 LOAD_CONST 6 (6)
288 COMPARE_OP 0 (<)
290 EXTENDED_ARG 1
39 292 POP_JUMP_IF_FALSE 328
294 LOAD_NAME 15 (cipher)
296 LOAD_NAME 16 (bytes)
298 LOAD_NAME 12 (ciphers)
300 LOAD_NAME 13 (row)
302 BINARY_SUBSCR
304 LOAD_NAME 14 (col)
306 BINARY_SUBSCR
308 BUILD_LIST 1
310 CALL_FUNCTION 1
312 INPLACE_ADD
40 314 STORE_NAME 15 (cipher)
316 LOAD_NAME 14 (col)
318 LOAD_CONST 11 (1)
320 INPLACE_ADD
322 STORE_NAME 14 (col)
324 EXTENDED_ARG 1
326 JUMP_ABSOLUTE 284
>> 328 POP_BLOCK
>> 330 EXTENDED_ARG 1
332 JUMP_ABSOLUTE 274
42 >> 334 POP_BLOCK
>> 336 LOAD_NAME 3 (b64encode)
338 LOAD_NAME 15 (cipher)
340 CALL_FUNCTION 1
44 342 STORE_NAME 15 (cipher)
344 LOAD_NAME 15 (cipher)
346 LOAD_GLOBAL 4 (O0o)
348 COMPARE_OP 2 (==)
350 EXTENDED_ARG 1
45 352 POP_JUMP_IF_FALSE 364
354 LOAD_NAME 7 (print)
356 LOAD_CONST 21 ('Great, this is my flag.')
358 CALL_FUNCTION 1
360 POP_TOP
47 362 JUMP_FORWARD 8 (to 372)
>> 364 LOAD_NAME 7 (print)
366 LOAD_CONST 22 ('Wrong flag.')
368 CALL_FUNCTION 1
370 POP_TOP
>> 372 LOAD_CONST 1 (None)
374 RETURN_VALUE
Disassembly of :
10 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('Give me the flag')
4 CALL_FUNCTION 1
6 POP_TOP
11 8 LOAD_GLOBAL 1 (input)
10 LOAD_CONST 2 ('> ')
12 CALL_FUNCTION 1
14 STORE_FAST 0 (flag)
12 16 LOAD_FAST 0 (flag)
18 LOAD_METHOD 2 (encode)
20 CALL_METHOD 0
22 STORE_FAST 0 (flag)
13 24 LOAD_CONST 3 (b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q')
26 STORE_GLOBAL 3 (O0o)
14 28 LOAD_FAST 0 (flag)
30 RETURN_VALUE
Disassembly of at 0x000001E7C7F280C0, file "task.py", line 28>:
28 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 26 (to 32)
6 STORE_DEREF 0 (col)
8 LOAD_CLOSURE 0 (col)
10 BUILD_TUPLE 1
12 LOAD_CONST 0 ( at 0x000001E7C7F28B70, file "task.py", line 28>)
14 LOAD_CONST 1 ('.')
16 MAKE_FUNCTION 8
18 LOAD_GLOBAL 0 (range)
20 LOAD_CONST 2 (6)
22 CALL_FUNCTION 1
24 GET_ITER
26 CALL_FUNCTION 1
28 LIST_APPEND 2
30 JUMP_ABSOLUTE 4
>> 32 RETURN_VALUE
Disassembly of at 0x000001E7C7F28B70, file "task.py", line 28>:
28 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 20 (to 26)
6 STORE_FAST 1 (row)
8 LOAD_GLOBAL 0 (raw_flag)
10 LOAD_CONST 0 (6)
12 LOAD_FAST 1 (row)
14 BINARY_MULTIPLY
16 LOAD_DEREF 0 (col)
18 BINARY_ADD
20 BINARY_SUBSCR
22 LIST_APPEND 2
24 JUMP_ABSOLUTE 4
>> 26 RETURN_VALUE
根据以上字节码,可还原源码为
import os
import sys
from base64 import b64encode
O0o = b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'
flag = input()
O0o = b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q'
if b'hgame{' != flag[:6] or flag[-1] != b'}':
print('Incorrect format!')
sys.exit(1)
raw_flag = flag[6:-1]
if len(flag) - 7 != 36:
print('Wrong length!')
sys.exit(2)
raw_flag = raw_flag[::-1]
ciphers = [ [ raw_flag[6*j+i] for j in range(6) ] for i in range(6) ]
for row in range(5):
for col in range(6):
ciphers[row][col] += ciphers[row + 1][col]
ciphers[row][col] %= 256
cipher = b''
for row in range(6):
col = 0
while col < 6:
cipher += bytes([ciphers[row][col]])
col += 1
assert O0o == b64encode(cipher)
因此,脚本如下:
from base64 import b64decode
cipher = b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q'
cipher = b64decode(cipher)
ciphers = [ [ cipher[j + 6*i] for j in range(6)] for i in range(6) ]
for row in range(5):
for col in range(6):
ciphers[4 - row][col] -= ciphers[5 - row][col]
ciphers[4 - row][col] %= 256
cipher = b""
for row in range(6):
col = 0
while col < 6:
cipher += bytes([ciphers[col][row]])
col += 1
cipher = cipher[::-1]
print(b"hgame{" + cipher + b"}")
Crypto
1. Verification_code
爆破就好啦
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import string
import time
from hashlib import sha256
from socket import socket
L = string.ascii_letters+string.digits
sock = socket()
sock.connect(("47.98.192.231", 25678))
s = sock.recv(1024).split(b"\n")[0]
_hexdigest = s[-64:].decode()
sub = s[12:28]
print(sock.recv(1024))
for a in L:
for b in L:
for c in L:
for d in L:
pre = (a+b+c+d).encode()
hexstr = sha256(pre + sub).hexdigest()
if hexstr == _hexdigest:
print(pre)
sock.send(pre)
print(sock.recv(1024))
sock.recv(1024)
sock.send(b"I like playing Hgame")
print(sock.recv(1024))
print(sock.recv(1024))
exit()
- Remainder
中国剩余定理就Vans啦
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from Crypto.Util.number import inverse
p = 94598296305713376652540411631949434301396235111673372738276754654188267010805522542068004453137678598891335408170277601381944584279339362056579262308427544671688614923839794522671378559276784734758727213070403838632286280473450086762286706863922968723202830398266220533885129175502142533600559292388005914561
q = 150088216417404963893679242888992998793257903343994792697939121738029477790454833496600101388493792476973514786401036309378542808470513073408894727406158296404360452232777491992630316999043165374635001806841520490997788796152678742544032835808854339130676283497122770901196468323977265095016407164510827505883
r = 145897736096689096151704740327665176308625097484116713780050311198775607465862066406830851710261868913835866335107146242979359964945125214420821146670919741118254402096944139483988745450480989706524191669371208210272907563936516990473246615375022630708213486725809819360033470468293100926616729742277729705727
e = 65537
cp = 78430786011650521224561924814843614294806974988599591058915520397518526296422791089692107488534157589856611229978068659970976374971658909987299759719533519358232180721480719635602515525942678988896727128884803638257227848176298172896155463813264206982505797613067215182849559356336015634543181806296355552543
cq = 49576356423474222188205187306884167620746479677590121213791093908977295803476203510001060180959190917276817541142411523867555147201992480220531431019627681572335103200586388519695931348304970651875582413052411224818844160945410884130575771617919149619341762325633301313732947264125576866033934018462843559419
cr = 48131077962649497833189292637861442767562147447040134411078884485513840553188185954383330236190253388937785530658279768620213062244053151614962893628946343595642513870766877810534480536737200302699539396810545420021054225204683428522820350356470883574463849146422150244304147618195613796399010492125383322922
m = p*q*r
Mp = q*r
Mq = p*r
Mr = p*q
dp = inverse(Mp, p)
dq = inverse(Mq, q)
dr = inverse(Mr, r)
msg = (dp*Mp*cp+dq*Mq*cq+dr*Mr*cr) % m
phim = (p-1)*(q-1)*(r-1)
de = inverse(e, phim)
msg = pow(msg, de, m)
msg = hex(msg)[2:-1]
if len(msg) % 2 == 1:
msg = "0" + msg
msg = msg.decode("hex")
print(msg)
s = ""
for st in msg.split("\n")[3:-3]:
s += st[:2]
print(s)
3. Inv
求置换群的逆元,之后仿照欧几里得除法。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def Subs(S, X):
return bytes([ S[x] for x in X ])
def Mul(A, B):
assert len(A)==len(B)
return Subs(A, B)
def Pow(X, E):
Y = X
E = bin(E)[3:]
for e in E:
Y = Mul(Y, Y)
if e=='1':
Y = Mul(X, Y)
return Y
def Inv(G : bytes):
ans = [0] * 256
for i in range(256):
ans[G[i]] = i.to_bytes(1, "little")
return b"".join(ans)
A = b'\xc8&\xc1E\xbe*\xc5\x84\xdb1\x05\x9b\xc0\xf2\xac/\x0b0\x8d\'\xc2b\x89\x93\xa6\xcd\xe1\x1b\xf4H\xffa\x90A\xf7,(\xea?\xa8\xa0\x8b\xf1\xf9"X\n\x86fj\x074\x7fBO\xd4F\xbd\xe6\xd9\xa7\xaf\x8a\x8c\xde\xab;!PT\x15)+w\xbc\x00>\xc6g\xc3\x85=9K\xb6<\xb7x\xaeUG\x83vk\xa9\xf6{\x03Y\x87\x14e\xfd\xed@i\xcc.\xd1\xebo\x106\xe2\xe7\xd7\xeeu\x9e\xfe\x95^R\xfb8\x04\xb4S\x16\xe0\xad\xd8\x98n\xca\xe4\xdd\xd2\xc7\x99l\xb3\\2L\xa3\x1d:_\x12\xb87\x17\x01\xb1#~q\x1c\t\xe8\xdar\xef\xcb\x0c\xe5\x80\xdf\xc9y\x0e`\xe9\x94\xd0\xcfW\x1f5\xf5h\xbf\xba\x91\xb9d\xfcM\x81\xec\x88\xb2c\x9f\xa4J|\xd3m\xd6s\xd5\x92\x9d\x9a3\xa2\xb5\xfa\x19N\xa1\x82][\xf8\x06\x13\xdcC\x1e\x1a\xaa\xc4tz\x08\x8f%$D\xbb\x97 \xce\x96V\xe3\x02I\x18\x11\x0f\r\xf3p\x8e\xa5Z-\xf0}\xb0Q\x9c'
B = b'U\x17\x8aE\xa6\x19\xab\x7fd0\xd2)\xc0\xae\xcc/G_\xe3\'\r\xfb\xaf\x00\xb1hgi-\xc1\xffa\x8d\t&\x99k\x95\x93\xa8.\x07\xcd\x87\x01\xe8\x89\x86\xf6f48F\xdc\x96\xd4`P\xd6!\xfe\xc4B:\xd31C\x9f\x1dT{2c9\x0bY5#\xf7\xb8H\xe0Db\xb6wv\xe1\xbbI\x8f\x83l\x80\xa9\x04q\x03\xf0m\xf4\x1bp\x8e\xc6u\xfd\x16$\x06\xf9Z\xec\xa2\xcb\xd7V\xb9\xd1\xbdt^\xe7\xe2\xac\x18\xb4\x15=n\xad\xd8S+\xca\xeb\xdd\xd0;\x84\xe6\x08\x8c3\xb3\x90\x02\xc8}\xee\xea7K\x98\xde\x8b~\xcf\xfa\x11\n\xda\xa4L\xa3\x0cWQ\xdf\xc9yj\x9d\xe9\xfcJO\x1a\x1f\xdb\xf5M\xbf\x9e e\x1c*\x9b\x85\xe5\x88\xb2\xc7\xf2\x91\x10\x0e,\xd9R\x9a\x94\x0fX\xf3\xbe?\xa5\xe4\xa0z\xf16\x81\x9c'
E = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
a = 595
b = 739
enc = b"\\-\xa5{\xb9\x85J @\xfa\x91\x0b\x88\r4I\x7f\xb9\xe5\r\xc0\x84\x8f\xa6\xc0i\xb0\xa4\x1b\x8fIw\x84'\xa2\xa4\x00\x91\x87\x10\r\\\x8c\x12"
a, b = b, a
A, B = B, A
q = a // b
r = a - b*q
R = B
while True:
B_ = Inv(B)
R = Mul(A, Pow(B_, q))
a, b = b, r
A, B = B, R
if b <= 1:
break
q = a // b
r = a - b*q
S = B
print(S)
flag = b""
for c in enc:
index = S.find(c)
flag += index.to_bytes(1, "little")
print(flag)
MISC
2.所见即为假
ZIP伪加密,之后F5-JPG隐写,最后出来base16,之后RAR,之后出FLAG。