由于我懒得分哪一周了,所以我就全部直接写了。 # BabyBase 打开一看,经典Base64,一点没变

base解密

BabyUPX

查壳,看到upx,一点没改,直接upx -d 脱壳

脱壳

简单的加密逻辑

加密

直接脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def decode(encoded_data):
decoded_data = []
for value in encoded_data:
for original_value in range(256):
if ((16 * original_value | (original_value >> 4)) % 256) == value:
decoded_data.append(original_value)
break
return bytes(decoded_data).decode('utf-8', errors='ignore')
enc = [ 0x03, 0x87, 0x74, 0x16, 0xD6, 0x56, 0xB7, 0x63, 0x83, 0x46,
0x66, 0x66, 0x43, 0x53, 0x83, 0xD2, 0x23, 0x93, 0x56, 0x53,
0xD2, 0x43, 0x36, 0x36, 0x03, 0xD2, 0x16, 0x93, 0x36, 0x26,
0xD2, 0x93, 0x73, 0x13, 0x66, 0x56, 0x36, 0x33, 0x33, 0x83,
0x56, 0x23, 0x66, 0xD7]
decoded_string = decode(enc)
print("Decoded string:", decoded_string)
# Decoded string: 0xGame{68dff458-29e5-4cc0-a9cb-971fec338e2f}
# BinaryMaster 额。。。。,不写了,直接就能看见 # EzJar 打开看到一个加密逻辑;

加密

不多说,直接看脚本吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package re;
public class Encryptor {
static String Alphabat = "0123456789abcdef";

private static String decrypt(String encryptedInput) {
StringBuilder decrypted = new StringBuilder();
for (int i = 0; i < encryptedInput.length(); i++) {
char currentChar = encryptedInput.charAt(i);
int newIndex = Alphabat.indexOf(currentChar);

if (newIndex < 0) {
decrypted.append(currentChar);
} else {
boolean found = false;
for (int originalIndex = 0; originalIndex < 16; originalIndex++) {
if ((originalIndex * 5 + 3) % 16 == newIndex) {
decrypted.append(Alphabat.charAt(originalIndex));
found = true;
break;
}
}

if (!found) {
decrypted.append(currentChar);
}
}
}
return decrypted.toString();
}

public static void main(String[] args) {
String encryptedInput = "ab50e920-4a97-70d1-b646-cdac5c873376";
String decryptedString = decrypt(encryptedInput);
System.out.println("0xGame{" + decryptedString + "}");
}
}
//0xGame{b8a9fe39-dbe4-4926-87d7-52b5a5140047}
# EzPyc 我使用uncompyle6进行反编译

加密

然后微改一下加密代码即可解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hashlib
# Get user input
user_input = input("请输入神秘代号:") # "Please enter the mysterious code:"
if user_input != "Ciallo~":
print("代号不是这个哦") # "The code is not this."
exit()
# Generate MD5 hash of the user input
input_hash = hashlib.md5(user_input.encode()).hexdigest()
input_hash_list = list(input_hash) # Convert to a list for mutability
# Modify the hash
for i in range(len(input_hash_list)):
if ord(input_hash_list[i]) in range(48, 58): # Check if the character is a digit (ASCII 48-57)
original_num = int(input_hash_list[i])
new_num = (original_num + 5) % 10 # Add 5 and take modulo 10
input_hash_list[i] = str(new_num) # Assign modified value back to the list
# Join the modified hash and print the output
modified_hash = "".join(input_hash_list) # Convert back to string
print("0xGame{{{}}}".format(modified_hash))
GPT还是很好用的~ # justsoso.apk(4) 打开文件就可以清晰看到加密逻辑,长度为44,原文经过ReversC4这个函数加密之后,接着经过base64加密,和encryptedFLAG:“nB9RCjwReif5P1H1MYO6m/hucCGjI6EE9wWEx/E4N+bO5k5ior6MnqAGQfc=”进行对比

justsoso

看到getKey的方法调用,我们知道可以用frida来Hookkey的值(其实就是懒得分析so文件~)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Java.perform(function() {

var MainActivity = Java.use("com.ctf.justsoso.MainActivity");

// Hook getKey 方法
MainActivity.getKey.implementation = function() {

var key = this.getKey();

var hexKey = Array.prototype.map.call(key, function(byte) {
return '0x' + ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join(', ');

console.log("Key obtained from getKey (hex): " + hexKey);

return key;
};
});

// [ASUS I005DA::PID::1769 ]-> Key obtained from getKey (hex): 0xab, 0x95, 0x99, 0x97, 0xc1, 0x1f, 0x8f, 0xf1, 0xbd, 0xa5, 0xb5, 0xc1, 0x99, 0xa1
然后我们对这个密文,先base64解一下,然后进行rc4解密即可

base64解密

得到了密文,rc4解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class ReversC4:
@staticmethod
def initial(key):
length = len(key)
iArr2 = [256 - i for i in range(256)]
iArr3 = [key[i % length] for i in range(256)]

i2 = 0
for i3 in range(256):
i4 = iArr2[i3]
i2 = (i2 + i4 + iArr3[i3]) % 256
i5 = iArr2[i2]
iArr2[i2] = i4
iArr2[i3] = i5

return iArr2

@staticmethod
def encrypt(data, key):
length = len(data)
initial = ReversC4.initial(key)
i = 0
i2 = 0

for i3 in range(length):
i = (i + 1) % 256
i4 = initial[i]
i2 = (i2 + i4) % 256
i5 = initial[i2]
initial[i] = i5
initial[i2] = i4

data[i3] = data[i3] ^ initial[(i4 + i5) % 256]

return data



enc = [0x9c, 0x1f, 0x51, 0x0a, 0x3c, 0x11, 0x7a, 0x27, 0xf9, 0x3f, 0x51, 0xf5, 0x31, 0x83, 0xba, 0x9b, 0xf8, 0x6e, 0x70,
0x21, 0xa3, 0x23, 0xa1, 0x04, 0xf7, 0x05, 0x84, 0xc7, 0xf1, 0x38, 0x37, 0xe6, 0xce, 0xe6, 0x4e, 0x62, 0xa2, 0xbe,
0x8c, 0x9e, 0xa0, 0x06, 0x41, 0xf7]
key = [0xab, 0x95, 0x99, 0x97, 0xc1, 0x1f, 0x8f, 0xf1, 0xbd, 0xa5, 0xb5, 0xc1, 0x99, 0xa1]

decrypted_data = ReversC4.encrypt(enc.copy(), key)

print("解密后的数据:", decrypted_data)
print("解密后的字符串:", bytes(decrypted_data).decode('utf-8', errors='ignore'))

# 解密后的字符串: 0xGame{fd51ce4b-4556-4cf9-9430-67480614e43b}
# MadMatrix 感觉这个题是整个逆向里面最难的一个,先看一下加密逻辑

矩阵1
矩阵2

先用密钥初始化了四个数组,然后将输入进行了一些初始化处理。 验证阶段,其实就是矩阵乘法,ByeBye函数就是在检测乘法的结果与预定的结果一不一致。 (具体函数细节直接去看吧,其实交给GPT很快就出了) 用我们小学二年级的矩阵求逆知识,可以得到解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import numpy as np

k1 = [1, 3, 1, 0, 2, 1, 1, 2, 0]
k2 = [1, 2, 2, 3, 5, 6, 0, 2, 1]
k3 = [0, 4, 3, 1, 2, 1, 2, 3, 1]
k4 = [1, 2, 3, 3, 5, 6, 1, 4, 10]

data = [
0x1e8, 0x1c0, 0x181, 0x557, 0x4d3, 0x41e, 0x13d, 0x111, 0x102,
0x26c, 0x140, 0x145, 0x5b7, 0x2ec, 0x2f3, 0x5e9, 0x31d, 0x336,
0x14d, 0x10a, 0x192, 0xbd, 0x9f, 0xf5, 0xbd, 0xa1, 0x101,
0x162, 0x147, 0x223, 0xfb, 0xc0, 0x126, 0x191, 0x123, 0x1b7,
0xf0, 0xfd, 0x10d, 0x29e, 0x2c0, 0x2f1, 0x91, 0x9f, 0xa4,
0x229, 0x13b, 0x12e, 0x4e4, 0x2d8, 0x2c7, 0x5bd, 0x325, 0x2e4,
0x1c7, 0x151, 0xd5, 0xfe, 0xe5, 0x6e, 0x12c, 0xa0, 0x9e
]

# 创建密钥矩阵
keyMat = [np.array(var).reshape(3, 3) for var in (k2, k4, k1, k3)]
# 创建数据矩阵
dataMat = [np.array(data[i * 9:(i + 1) * 9]).reshape(3, 3) for i in range(len(data) // 9)]

flag = []
for i in range(7):
# 选择当前使用的密钥矩阵,并计算其逆矩阵
inv = np.linalg.inv(keyMat[i % 4])

# 执行矩阵相乘
decrypted_matrix = np.matmul(inv, dataMat[i])

# 将矩阵展平成一维数组,并对每个元素进行四舍五入
arr = decrypted_matrix.flatten()

# 解决相邻矩阵元素重叠问题,只取前6个元素(前6次迭代)
if i < 6:
arr = arr[:6]

# 将四舍五入的元素加入到flag中
flag.extend([round(num) for num in arr])

try:
print(bytes(flag).decode())
except UnicodeDecodeError as e:
print("解码错误:", e)
print("字节数组:", flag)

# 0xGame{78d51c59-6dc3-30d2-1276-18e13f80c478}
# MineSweeper(4) 用DnSpy打开,仔细寻找就可以看见加密函数

扫雷

然后在asset文件中的resources.assets获得44位的加密数据即可

扫雷

然后可以写解密函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def decrypt(key_str, enc_data, game_key_str):
# 将 key 和 game_key 转换为字节数组
key = bytearray(key_str.encode('ascii'))
game_key = bytearray(game_key_str.encode('ascii'))

# 确保 key 长度为 44
if len(key) < 44:
raise ValueError("Key length must be at least 44 characters.")

# 按照加密逻辑调整 key 的内容
num = 0
for i in range(44):
num = (num + game_key[i % len(game_key)]) % 44
# 交换 key[num] 和 key[i]
key[num], key[i] = key[i], key[num]

# 复制加密数据
decrypted_data = bytearray(enc_data)

# 解密过程,从数组的尾部开始,逐个与 key 进行异或操作
for j in range(43, -1, -1):
decrypted_data[j] ^= key[j]

# 将解密后的字节数组转换为字符串
return decrypted_data.decode('ascii')


# 初始化所需的数据
haha = "This is: True_KEY!for #0xgAmE_Unity~Cryption"
game_key = "0xoX0XOxOXoxGAME"
hex_data = [
0x45, 0x21, 0x3E, 0x08, 0x57, 0x31, 0x09, 0x4D, 0x42, 0x45, 0x42, 0x44, 0x5D, 0x5A, 0x4B, 0x4B,
0x52, 0x56, 0x16, 0x44, 0x66, 0x45, 0x6C, 0x40, 0x57, 0x44, 0x33, 0x35, 0x51, 0x75, 0x0D, 0x58,
0x15, 0x71, 0x11, 0x1B, 0x0B, 0x08, 0x76, 0x04, 0x4F, 0x5C, 0x68, 0x3C
]

# 调用解密函数
result = decrypt(haha, hex_data, game_key)
print("Decrypted data:", result)

# Decrypted data: 0xGame{36ecd059-b3e7-73c8-fa80-0a2abef3c757}
# Puzzle 数独游戏,解法很多

Pypro(4)

用pyinstxtractor.py分解exe文件,将得到的文件里面和exe文件同名的文件后缀改成.pyc,然后将此文件的对应的MagicNumber补上

py

之后pycdc.exe反编译,你会发现,版本不容, 只能用pycdas.exe反汇编,,,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
PyPro.pyc (Python 3.12)
[Code]
File Name: PyPro.py
Object Name: <module>
Qualified Name: <module>
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Stack Size: 2
Flags: 0x00000000
[Names]
'base64'
'Crypto.Cipher'
'AES'
'Crypto.Util.number'
'long_to_bytes'
'key'
'PKCS5_pad'
'main'
'__name__'
[Locals+Names]
[Constants]
0
None
(
'AES'
)
(
'long_to_bytes'
)
0x554B134A029DE539438BD18604BF114L
[Code]
File Name: PyPro.py
Object Name: PKCS5_pad
Qualified Name: PKCS5_pad
Arg Count: 1
Pos Only Arg Count: 0
KW Only Arg Count: 0
Stack Size: 5
Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
[Names]
'len'
'ljust'
'to_bytes'
[Locals+Names]
'data'
'length'
[Constants]
None
48
[Disassembly]
0 RESUME 0
2 LOAD_GLOBAL 1: NULL + len
12 LOAD_FAST 0: data
14 CALL 1
22 LOAD_CONST 1: 48
24 COMPARE_OP 2 (<)
28 POP_JUMP_IF_FALSE 46 (to 122)
30 LOAD_CONST 1: 48
32 LOAD_GLOBAL 1: NULL + len
42 LOAD_FAST 0: data
44 CALL 1
52 BINARY_OP 10 (-)
56 STORE_FAST 1: length
58 LOAD_FAST 0: data
60 LOAD_ATTR 3: ljust
80 LOAD_CONST 1: 48
82 LOAD_FAST 1: length
84 LOAD_ATTR 5: to_bytes
104 CALL 0
112 CALL 2
120 RETURN_VALUE
122 RETURN_CONST 0: None
[Code]
File Name: PyPro.py
Object Name: main
Qualified Name: main
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Stack Size: 5
Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
[Names]
'input'
'encode'
'len'
'print'
'range'
'exit'
'ord'
'AES'
'new'
'long_to_bytes'
'key'
'MODE_ECB'
'encrypt'
'PKCS5_pad'
'base64'
'b64encode'
'decode'
[Locals+Names]
'enc'
'i'
'chiper'
'result'
'data'
[Constants]
None
'在这里输入你的flag:\n'
'utf-8'
44
'length error!'
123
6
'{'
-1
'}'
'format error'
1
'2e8Ugcv8lKVhL3gkv3grJGNE3UqkjlvKqCgJSGRNHHEk98Kd0wv6s60GpAUsU+8Q'
'flag正确'
'错误'
[Disassembly]
0 RESUME 0
2 LOAD_GLOBAL 1: NULL + input
12 LOAD_CONST 1: '在这里输入你的flag:\n'
14 CALL 1
22 LOAD_ATTR 3: encode
42 LOAD_CONST 2: 'utf-8'
44 CALL 1
52 STORE_FAST 0: enc
54 LOAD_GLOBAL 5: NULL + len
64 LOAD_FAST 0: enc
66 CALL 1
74 LOAD_CONST 3: 44
76 COMPARE_OP 55 (!=)
80 POP_JUMP_IF_FALSE 48 (to 178)
82 LOAD_GLOBAL 7: NULL + print
92 LOAD_CONST 4: 'length error!'
94 CALL 1
102 POP_TOP
104 LOAD_GLOBAL 9: NULL + range
114 LOAD_GLOBAL 5: NULL + len
124 LOAD_FAST 0: enc
126 CALL 1
134 CALL 1
142 GET_ITER
144 FOR_ITER 2 (to 150)
148 STORE_FAST 1: i
150 JUMP_BACKWARD 4 (to 144)
152 END_FOR
154 LOAD_GLOBAL 11: NULL + exit
164 LOAD_CONST 5: 123
166 CALL 1
174 POP_TOP
176 JUMP_FORWARD 57 (to 292)
178 LOAD_FAST 0: enc
180 LOAD_CONST 6: 6
182 BINARY_SUBSCR
186 LOAD_GLOBAL 13: NULL + ord
196 LOAD_CONST 7: '{'
198 CALL 1
206 COMPARE_OP 55 (!=)
210 POP_JUMP_IF_TRUE 17 (to 246)
212 LOAD_FAST 0: enc
214 LOAD_CONST 8: -1
216 BINARY_SUBSCR
220 LOAD_GLOBAL 13: NULL + ord
230 LOAD_CONST 9: '}'
232 CALL 1
240 COMPARE_OP 55 (!=)
244 POP_JUMP_IF_FALSE 23 (to 292)
246 LOAD_GLOBAL 7: NULL + print
256 LOAD_CONST 10: 'format error'
258 CALL 1
266 POP_TOP
268 LOAD_GLOBAL 11: NULL + exit
278 LOAD_CONST 11: 1
280 CALL 1
288 POP_TOP
290 NOP
292 LOAD_GLOBAL 15: NULL + AES
302 LOAD_ATTR 16: new
322 LOAD_GLOBAL 19: NULL + long_to_bytes
332 LOAD_GLOBAL 20: key
342 CALL 1
350 LOAD_GLOBAL 14: AES
360 LOAD_ATTR 22: MODE_ECB
380 CALL 2
388 STORE_FAST 2: chiper
390 LOAD_FAST 2: chiper
392 LOAD_ATTR 25: encrypt
412 LOAD_GLOBAL 27: NULL + PKCS5_pad
422 LOAD_FAST 0: enc
424 CALL 1
432 CALL 1
440 STORE_FAST 0: enc
442 LOAD_GLOBAL 29: NULL + base64
452 LOAD_ATTR 30: b64encode
472 LOAD_FAST 0: enc
474 CALL 1
482 STORE_FAST 3: result
484 LOAD_CONST 12: '2e8Ugcv8lKVhL3gkv3grJGNE3UqkjlvKqCgJSGRNHHEk98Kd0wv6s60GpAUsU+8Q'
486 STORE_FAST 4: data
488 LOAD_FAST 3: result
490 LOAD_ATTR 33: decode
510 CALL 0
518 LOAD_FAST 4: data
520 COMPARE_OP 40 (==)
524 POP_JUMP_IF_FALSE 12 (to 550)
526 LOAD_GLOBAL 7: NULL + print
536 LOAD_CONST 13: 'flag正确'
538 CALL 1
546 POP_TOP
548 RETURN_CONST 0: None
550 LOAD_GLOBAL 7: NULL + print
560 LOAD_CONST 14: '错误'
562 CALL 1
570 POP_TOP
572 RETURN_CONST 0: None
'__main__'
[Disassembly]
0 RESUME 0
2 LOAD_CONST 0: 0
4 LOAD_CONST 1: None
6 IMPORT_NAME 0: base64
8 STORE_NAME 0: base64
10 LOAD_CONST 0: 0
12 LOAD_CONST 2: ('AES',)
14 IMPORT_NAME 1: Crypto.Cipher
16 IMPORT_FROM 2: AES
18 STORE_NAME 2: AES
20 POP_TOP
22 LOAD_CONST 0: 0
24 LOAD_CONST 3: ('long_to_bytes',)
26 IMPORT_NAME 3: Crypto.Util.number
28 IMPORT_FROM 4: long_to_bytes
30 STORE_NAME 4: long_to_bytes
32 POP_TOP
34 LOAD_CONST 4: 0x554B134A029DE539438BD18604BF114L
36 STORE_NAME 5: key
38 LOAD_CONST 5: <CODE> PKCS5_pad
40 MAKE_FUNCTION 0
42 STORE_NAME 6: PKCS5_pad
44 LOAD_CONST 6: <CODE> main
46 MAKE_FUNCTION 0
48 STORE_NAME 7: main
50 LOAD_NAME 8: __name__
52 LOAD_CONST 7: '__main__'
54 COMPARE_OP 40 (==)
58 POP_JUMP_IF_FALSE 8 (to 76)
60 PUSH_NULL
62 LOAD_NAME 7: main
64 CALL 0
72 POP_TOP
74 RETURN_CONST 1: None
76 RETURN_CONST 1: None
自己看或者交给GPT了解加密逻辑之后,进行解密即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import base64
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
key = 0x554B134A029DE539438BD18604BF114


def PKCS5_unpad(data):
padding_length = data[-1]
if padding_length > 48 or data[-padding_length:] != bytes([padding_length]) * padding_length:
raise ValueError("Invalid padding.")
return data[:-padding_length]


def decrypt(data):
chiper = AES.new(long_to_bytes(key), AES.MODE_ECB)
decoded_data = base64.b64decode(data)
decrypted_data = chiper.decrypt(decoded_data)
return PKCS5_unpad(decrypted_data)


def main():
encrypted_data = '2e8Ugcv8lKVhL3gkv3grJGNE3UqkjlvKqCgJSGRNHHEk98Kd0wv6s60GpAUsU+8Q'
try:
decrypted_flag = decrypt(encrypted_data).decode('utf-8')
print("解密成功,解密后的 flag 是:", decrypted_flag)
except Exception as e:
print("解密失败:", str(e))


if __name__ == "__main__":
main()

# 0xGame{1cb76d38-4900-476f-bf1b-9d59f74d7b2e}
# Register(4) 用ida打开查找字符串,可以找到主要加密函数

register

然后两次交叉引用,可以看到用户名的判断

register

简单分析加密函数(其实动调就可以),可以知道答案就是用户名的SHA1加密,(动调就可以出) 不想分析了,大家自己去搞吧~(动调很简单的) # SignIn 直接shift+F12查询即可

加密

Tea

TEA

注意到,在进行反向的过程中,Buf1变成的int64型,所以传入TEA加密时,是以int64类型传入的,所以只加密了最前面以及最后面的数据

TEA

很经典的TEA,我就不贴脚本了(我是不可能说我找不到了~)

Tea2.0(4)

这个就是一个很简单的tea,但是你直接上脚本就会发现,得到了一串乱码,当你不死心的交上去,果然。错了 其实这个题就是有TLS回调函数,对密文进行了一些操作,直接动调然后提取正确的数据就可(当然,如果你想自己写出来正确数据,我也不反对-,只要你不怕麻烦doge) # Xor_Beginning 不截图了,直接附上脚本

1
2
3
4
5
6
7
8
enc = [ 0x7E, 0x35, 0x0B, 0x2A, 0x27, 0x2C, 0x33, 0x1F, 0x76, 0x37,
0x1B, 0x72, 0x31, 0x1E, 0x36, 0x0C, 0x4C, 0x44, 0x63, 0x72,
0x57, 0x49, 0x08, 0x45, 0x42, 0x01, 0x5A, 0x04, 0x13, 0x4C]

flag = ''
for i in range(len(enc)):
flag += chr(enc[i] ^ (78 - i))
print(flag)
# Xor_Endian 多了一个密钥,也不多说
1
2
3
4
5
6
7
8
9
10
11
12
enc = [ 0x7B, 0x1D, 0x3E, 0x51, 0x15, 0x22, 0x1A, 0x0F, 0x56, 0x0A,
0x51, 0x56, 0x00, 0x28, 0x5D, 0x54, 0x07, 0x4B, 0x74, 0x05,
0x40, 0x51, 0x54, 0x08, 0x54, 0x19, 0x72, 0x56, 0x1D, 0x04,
0x55, 0x76, 0x56, 0x0B, 0x54, 0x57, 0x07, 0x0B, 0x55, 0x73,
0x01, 0x4F, 0x08, 0x05]

key = "Key0xGame2024"
flag = ''
for i in range(len(enc)):
enc[i] ^= ord(key[i % len(key)])
flag += chr(enc[i])
print(flag)
# Xor_Random 这个题的代码真丑

加密
加密

通过分析可以知道,随机数种子为0x77,v21是第二次赋值, 并且这个随机数是c++生成,所以我们可以得到如下c++代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>

int main() {
// 设置固定的随机数种子
srand(0x77u);

int v13[] = { 0x0c,0x4f,0x10,0x1f,0x4e,0x16,0x21,0x12,
0x4b,0x24,0x10,0x4b,0x0a,0x24,0x1f,0x17,
0x09,0x4f,0x07,0x08,0x21,0x5c,0x2c,0x1a,
0x10,0x1f,0x11,0x16,0x59,0x5a,
};
//生成并输出一些随机数
int random_number1 = rand() % 256; // 生成随机数
printf("Random Number1: %d\n", random_number1);
int random_number2 = rand() % 256; // 生成随机数
printf("Random Number2: %d\n", random_number2);

for (int i = 0; i < sizeof(v13) / sizeof(v13[0]); i++) {
if ((i & 1) != 0)
v13[i] ^= 123;
else
v13[i] ^= 126;
printf_s("%c", v13[i]);
}
//0xGame{r4nd0m_i5_n0t_alw4ys_'Random'!}
}
# ZzZ

加密

可以看到,一个经典Z3,没有一点坑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from z3 import *

# 定义变量,使用 BitVec 类型
v10 = BitVec('v10', 64) # 64位变量
v11 = BitVec('v11', 64) # 64位变量
v12 = BitVec('v12', 64) # 64位变量

solver = Solver()

solver.add(11 * v11 + 14 * v10 - v12 == 0x48FB41DDD)
solver.add(9 * v10 - 3 * v11 + 4 * v12 == 0x2BA692AD7)
solver.add(((v12 - v11) >> 1) + (v10 ^ 0x87654321) == 3451779756)

if solver.check() == sat:
model = solver.model()
print("v10 =", model[v10].as_long())
print("v11 =", model[v11].as_long())
print("v12 =", model[v12].as_long())
else:
print("No solution found")

# v10 = 842086455 //0x32313837
# v11 = 862073908 //0x33623434
# v12 = 1681208161 //0x64353361


enc = [0x37, 0x38, 0x31, 0x32, 0x34, 0x34, 0x62, 0x33, 0x61, 0x33, 0x35, 0x64]
flag = ''
for i in enc:
flag += chr(i)
print(flag)

# 0xGame{e544267d-7812-44b3-a35d-d085a85201a4}

babyASM

给了一个txt文件,里面很短的一个汇编,硬读也是不难的,但是我们完全可以甩给GPT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 初始加密后的 data 数组
data = [
20, 92, 43, 69, 81, 73, 95, 23, 72, 22, 24, 69, 25, 27, 22, 17,
23, 29, 24, 73, 17, 24, 85, 27, 112, 76, 15, 92, 24, 1, 73, 84,
13, 81, 12, 0, 84, 73, 82, 8, 82, 81, 76, 125
]

# 第一轮操作:data[0] 到 data[21] 增加 28
for i in range(22):
data[i] = (data[i] + 28) & 0xFF # 确保结果在 0-255 范围内

# 第二轮操作:data[22] 到 data[42] 与 data[0] 到 data[20] 的字节异或
for i in range(22, 43):
data[i] ^= data[i - 22]

# 打印结果
print("加密后的数据:", data)
# 尝试将加密后的数据转换为字符串
print("加密后的字符串:", "".join(chr(b) for b in data))
# 0xGame{3d24a572-394e-4ec7-b9c2-f9097fda1f4a}

EzAndroid.apk

在资源文件里面找到加密数据串,然后bsae62解密即可

这个难度才叫新生赛嘛woc,符合预期,也是第一个我ak的新生赛hhhhhhhhhhhhhh