BabyUPX
使用UPX脱壳工具之后打开,从encode函数发现加密逻辑是交换字节的高四位和第四位,可以写出exp
def decode(encoded_bytes): decoded_bytes = encoded_bytes for i in range(len(decoded_bytes)): high = decoded_bytes[i] & 0xF0 low = decoded_bytes[i] & 0x0F decoded_bytes[i] = (low << 4) | (high >> 4) return decoded_bytes encoded_data = [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_data = decode(encoded_data) flag = '' for i in range(len(decoded_data)): flag += chr(decoded_data[i]) print(flag)
|
FirstSight-Jar
使用Jadx打开jar文件,在main函数中能看到uuid,拼接上0xGame即可得到flag
FirstSight-Pyc
使用pydumpck反编译pyc文件得到py文件逻辑
import hashlib user_input = input('请输入神秘代号:') if user_input != 'Ciallo~': print('代号不是这个哦') exit() input_hash = hashlib.md5(user_input.encode()).hexdigest() input_hash = list(input_hash) for i in range(len(input_hash)): if ord(input_hash[i]) in range(48, 58): original_num = int(input_hash[i]) new_num = (original_num + 5) % 10 input_hash[i] = str(new_num) else: input_hash = ''.join(input_hash) print('0xGame{{{}}}'.format(input_hash)) return None
|
修改为正确的逻辑输入Ciallo~即可得到flag
0xGame{2f0ef0217bf3a7c598d381b077672e09}
ZzZ
使用IDA打开后看到flag具体格式以及中间部分的加密逻辑,使用Z3求解方程得到flag
from z3 import *
def solve_for_flag():
v10 = BitVec('v10', 64) v11 = BitVec('v11', 64) v12 = BitVec('v12', 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() v10_value = model[v10].as_long() v11_value = model[v11].as_long() v12_value = model[v12].as_long()
print(f"v10: {v10_value}, v11: {v11_value}, v12: {v12_value}")
v5 = v10_value.to_bytes(4, byteorder='little').decode('utf-8') v6 = v11_value.to_bytes(4, byteorder='little').decode('utf-8') v7 = v12_value.to_bytes(4, byteorder='little').decode('utf-8')
v13 = 0xe544267d v14 = 0xd085a85201a4
flag = "0xGame{{{:08x}-{}-{}-{}-{:012x}}}".format(v13, v5, v6, v7, v14) print(flag)
solve_for_flag()
|
Xor::Ramdom
有关伪随机数的异或
理清代码逻辑后可以在init_random函数中发现随机数的种子
int init_random(void) { srand(0x77u); return rand(); }
|
同时我们可以在main函数中看到v21 = rand( ),所以一共调用了两次rand函数,接下来是一个简单的逻辑,根据索引的奇偶性来判断实际的异或值
if ( (v23 & 1) != 0 ) v8 = v21; else v8 = v21 + 3; *v7 ^= v8;
|
根据以上分析可以写出exp
#include<stdio.h> #include<stdlib.h>
int main() { srand(0x77u); int cipher[]{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; int random_number2 = rand()%256; printf("0xGame{"); for(int i = 0; i < sizeof(cipher)/sizeof(cipher[0]);i++) { if ((i&1)!=0) cipher[i] ^= random_number2; else cipher[i] ^= (random_number2+3); printf("%c",cipher[i]); } printf("}"); return 0; }
|