from Crypto.Cipher import AES import os from pwn import p32, u32, p64, u64, log from dataclasses import dataclass from typing import Optional from zlib import crc32 import struct from functools import cache from tqdm import tqdm @dataclass class Message: mode: int = 0 size_mode0: Optional[int] = None id: int = 0 data: bytes = b"" crc: Optional[int] = None size_mode1: Optional[int] = None def to_bytes(self): if self.crc is None: self.crc = crc32(self.data) & 0xffffffff if self.size_mode0 is None: self.size_mode0 = len(self.data) if self.size_mode1 is None: self.size_mode1 = len(self.data) return struct.pack("= n: break base = 0x48 + i * 0x114 m = Message.from_bytes(MEMORY[base: base + 0x114]) iv = MEMORY[0xc28 + i * 0x10: 0xc28 + (i+1) * 0x10] sz = m.size_mode0 print("...encrypt %d/%d [%d bytes]" % (i, n, sz)) assert base + 0xc + sz <= 0x1000 MEMORY[base + 0xc:base + 0xc + sz] = AES.new(SECRET_AES_KEY, mode=AES.MODE_CBC, iv=iv).encrypt(MEMORY[base + 0xc:base + 0xc + sz]) MEMORY[base + 0x110:base + 0x114] = p32(sz) MEMORY[base] = 1 i += 1 results.append(Message.from_bytes(MEMORY[base:base+0x114])) clear() return results def decrypt(n): i = 0 results = [] while 1: n = u32(MEMORY[0xb10:0xb14]) if i >= n: break base = 0x48 + i * 0x114 m = Message.from_bytes(MEMORY[base: base + 0x114]) iv = MEMORY[0xc28 + i * 0x10: 0xc28 + (i+1) * 0x10] sz = m.size_mode1 print("...decrypt %d/%d [%d bytes]" % (i, n, sz)) assert base + 0xc + sz <= 0x1000 MEMORY[base] = 0 MEMORY[base + 0xc:base + 0xc + sz] = AES.new(SECRET_AES_KEY, mode=AES.MODE_CBC, iv=iv).decrypt(MEMORY[base + 0xc:base + 0xc + sz]) MEMORY[base + 4:base + 8] = p32(sz) i += 1 results.append(Message.from_bytes(MEMORY[base:base+0x114])) clear() return results @cache def decrypt_block(block): add(Message(mode=1, data=b"\0" * 16 + block)) data = decrypt(1) return data[-1].data.ljust(32, b"\0")[16:32] # attack CRC = crc32(b"A" * 16) def decrypt_msg9(size): """ Overflowing decryption from message 9. Uses (CRC, size, 10, 0) as the IV for overflowed blocks. """ block_old = struct.pack("