LitCTF 2025 Reverse WP
LitCTF 2025 Reverse WriteUp
前言:难崩,Unity题有CE解法,他妈的局限在dll里分析了 呜呜
1.easy_rc4
没壳
显然v4是key,s2-v18是密文
发现rc4_crypt函数里面多异或了个0x20
上赛博厨子
2.Robbie Wanna Revenge
来说说这个sb题,先说说我自己的思路,上次在XYCTF已经遇到过iwanna的游戏,这次这破游戏是一点玩不了,根本就出不去。。。。。。
思路:通常Unity游戏的主要数据算法在Assembly-CSharp.dll里,要想获取这个Dll,需要两个前置文件
1.GameAssembly.dll
2.global-metadata.dat
并且还需要专门的Unity工具去dump它,这里用的工具是Il2CppDumper
dump完寻找Assembly-CSharp.dll,然后找到里面关键函数,再用ida去加载GameAssembly.dll,加载完发现是没有符号表的,这时候就用到了dumper里的py可以恢复符号表,最后找到解密函数分析即可
正常来说他是dump不下来的,因为GameAssembly.dll他加UPX壳了
用DIE查看是看不出来的,需要用010editor去看
发现对这4个地方进行了魔改,我们只需将这四个地方进行还原即可,4C 49 54 改为 55 50 58 即LIT->UPX保存即可正常脱壳
dump完就会出来些东西
对于dll文件使用ILSPY工具查看
我当时发现了这个函数
还有这么个玩意儿,完了我就用IDA打开dll,恢复符号表,找了半天,啥他吗也没有......找了两个小时红温了,完了后来才发现这玩意儿是个障眼法......
新学的大招:
在高版本CE里,加载Mono游戏时会自动出现
先激活Mono功能,然后打开.net info
这个GetFlag我点了1分钟,游戏里也没弹出来任何东西,完了我就发现还有这么个东西
右键invoke调用
总结:似乎CE的Mono只有在高版本才有用。我用的CE 7.5
哎,绷不住了.....
3.pickle
首先做题时候遇到这么个问题
好家伙这是什么情况? 无奈让AI再写一份
5 0 RESUME 0
6 2 LOAD_GLOBAL 1 (NULL + input)
14 LOAD_CONST 1 ('input your flag > ')
16 PRECALL 1
20 CALL 1
30 LOAD_METHOD 1 (encode)
52 PRECALL 0
56 CALL 0
66 STORE_FAST 0 (user_input)
8 68 BUILD_LIST 0
70 STORE_FAST 1 (decrypted)
9 72 LOAD_GLOBAL 5 (NULL + range)
84 LOAD_GLOBAL 7 (NULL + len)
96 LOAD_FAST 0 (user_input)
98 PRECALL 1
102 CALL 1
112 PRECALL 1
116 CALL 1
126 GET_ITER
>> 128 FOR_ITER 34 (to 198)
130 STORE_FAST 2 (i)
10 132 LOAD_FAST 0 (user_input)
134 LOAD_FAST 2 (i)
136 BINARY_SUBSCR
146 LOAD_CONST 2 (6)
148 BINARY_OP 10 (-)
152 STORE_FAST 3 (b)
11 154 LOAD_FAST 1 (decrypted)
156 LOAD_METHOD 4 (append)
178 LOAD_FAST 3 (b)
180 PRECALL 1
184 CALL 1
194 POP_TOP
196 JUMP_BACKWARD 35 (to 128)
13 >> 198 BUILD_LIST 0
200 LOAD_CONST 3 ((85, 84, 174, 227, 132, 190, 207, 142, 77, 24, 235, 236, 231, 213, 138, 153, 60, 29, 241, 241, 237, 208, 144, 222, 115, 16, 242, 239, 231, 165, 157, 224, 56, 104, 242, 128, 250, 211, 150, 225, 63, 29, 242, 169))
202 LIST_EXTEND 1
204 STORE_FAST 4 (fflag)
14 206 BUILD_LIST 0
208 LOAD_CONST 4 ((19, 55, 192, 222, 202, 254, 186, 190))
210 LIST_EXTEND 1
212 STORE_FAST 5 (key_ints)
16 214 LOAD_CONST 5 (<code object encrypt at 0x000001DFB4B16B50, file "d:\code\PYTHON\IPParser1.py", line 16>)
216 MAKE_FUNCTION 0
218 STORE_FAST 6 (encrypt)
23 220 PUSH_NULL
222 LOAD_FAST 6 (encrypt)
224 LOAD_FAST 4 (fflag)
226 LOAD_FAST 5 (key_ints)
228 PRECALL 2
232 CALL 2
242 STORE_FAST 7 (encrypted_flag)
25 244 LOAD_FAST 1 (decrypted)
246 LOAD_FAST 7 (encrypted_flag)
248 COMPARE_OP 2 (==)
254 POP_JUMP_FORWARD_IF_FALSE 17 (to 290)
26 256 LOAD_GLOBAL 11 (NULL + print)
268 LOAD_CONST 6 ('Good job! You made it!')
270 PRECALL 1
274 CALL 1
284 POP_TOP
286 LOAD_CONST 0 (None)
288 RETURN_VALUE
28 >> 290 LOAD_GLOBAL 11 (NULL + print)
302 LOAD_CONST 7 ("Nah, don't give up!")
304 PRECALL 1
308 CALL 1
318 POP_TOP
320 LOAD_CONST 0 (None)
322 RETURN_VALUE
Disassembly of <code object encrypt at 0x000001DFB4B16B50, file "d:\code\PYTHON\IPParser1.py", line 16>:
16 0 RESUME 0
17 2 BUILD_LIST 0
4 STORE_FAST 2 (result)
18 6 LOAD_GLOBAL 1 (NULL + range)
18 LOAD_GLOBAL 3 (NULL + len)
30 LOAD_FAST 0 (flag_bytes)
32 PRECALL 1
36 CALL 1
46 PRECALL 1
50 CALL 1
60 GET_ITER
>> 62 FOR_ITER 56 (to 176)
64 STORE_FAST 3 (i)
19 66 LOAD_FAST 0 (flag_bytes)
68 LOAD_FAST 3 (i)
70 BINARY_SUBSCR
80 LOAD_FAST 1 (key)
82 LOAD_FAST 3 (i)
84 LOAD_GLOBAL 3 (NULL + len)
96 LOAD_FAST 1 (key)
98 PRECALL 1
102 CALL 1
112 BINARY_OP 6 (%)
116 BINARY_SUBSCR
126 BINARY_OP 12 (^)
130 STORE_FAST 4 (b)
20 132 LOAD_FAST 2 (result)
134 LOAD_METHOD 2 (append)
156 LOAD_FAST 4 (b)
158 PRECALL 1
162 CALL 1
172 POP_TOP
174 JUMP_BACKWARD 57 (to 62)
21 >> 176 LOAD_FAST 2 (result)
178 RETURN_VALUE
交给AI
# 从字节码中提取的常量值
fflag = [85, 84, 174, 227, 132, 190, 207, 142, 77, 24, 235, 236, 231, 213, 138, 153, 60, 29, 241, 241, 237, 208, 144, 222, 115, 16, 242, 239, 231, 165, 157, 224, 56, 104, 242, 128, 250, 211, 150, 225, 63, 29, 242, 169]
key_ints = [19, 55, 192, 222, 202, 254, 186, 190]
# 逆向加密过程
def decrypt(encrypted, key):
result = []
for i in range(len(encrypted)):
b = encrypted[i] ^ key[i % len(key)]
result.append(b)
return result
# 逆向用户输入处理过程
def reverse_decryption(decrypted):
original_input = []
for b in decrypted:
original_input.append(b + 6) # 逆向减去6的操作
try:
# 尝试将字节转换为字符串
return bytes(original_input).decode('utf-8')
except UnicodeDecodeError:
return original_input # 如果无法解码为字符串,返回原始字节
# 执行解密
decrypted_flag = decrypt(fflag, key_ints)
original_input = reverse_decryption(decrypted_flag)
print("解密后的flag:", original_input)
4.FeatureExtraction
没做出来,待复现
5.easy_tea
没做出来,待复现