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
| from z3 import *
a = [ 0x0B1B0, 0x5678, 0x7FF2, 0x0A332, 0x0A0E8, 0x364C, 0x2BD4, 0x0C8FE, 0x4A7C, 0x18, 0x2BE4, 0x4144, 0x3BA6, 0x0BE8C, 0x8F7E, 0x35F8, 0x61AA, 0x2B4A, 0x6828, 0x0B39E, 0x0B542, 0x33EC, 0x0C7D8, 0x448C, 0x9310, 0x8808, 0x0ADD4, 0x3CC2, 0x796, 0x0C940, 0x4E32, 0x4E2E, 0x924A, 0x5B5C, ] assert len(a) == 34
PRINTABLE_ASCII_ONLY = True MAX_SOLUTIONS = 10
def build_solver(): N = 34 s = [BitVec(f"s_{i}", 8) for i in range(N)]
sol = Solver()
if PRINTABLE_ASCII_ONLY: for i in range(N): sol.add(UGE(s[i], BitVecVal(32, 8))) sol.add(ULE(s[i], BitVecVal(126, 8)))
MOD = BitVecVal(51966, 64) MUL = BitVecVal(47806, 64) MAGIC = BitVecVal(0x114514, 64)
for i in range(N): term = MUL * (ZeroExt(56, s[i]) + BitVecVal(i, 64)) if i == 0: x = term else: x = term ^ (BitVecVal(a[i-1], 64) ^ MAGIC)
rem = URem(x, MOD) sol.add(rem == BitVecVal(a[i], 64))
return sol, s
def model_to_inner(m, s_vars): bs = [m[v].as_long() for v in s_vars] try: return bytes(bs).decode("latin1") except Exception: return "".join(chr(b) for b in bs)
def main(): sol, s_vars = build_solver() solutions = []
while len(solutions) < MAX_SOLUTIONS and sol.check() == sat: m = sol.model() inner = model_to_inner(m, s_vars) flag = f"moectf{{{inner}}}" solutions.append(flag)
sol.add(Or([s_vars[i] != m[s_vars[i]] for i in range(len(s_vars))]))
print(f"[域] {'ASCII(32..126)' if PRINTABLE_ASCII_ONLY else 'BYTE(0..255)'}") print(f"[找到] {len(solutions)} 个解(最多枚举 {MAX_SOLUTIONS} 个)\n") for idx, f in enumerate(solutions, 1): print(f"[{idx}] {f} (len={len(f)})") if not solutions and PRINTABLE_ASCII_ONLY: print("\n提示:把 PRINTABLE_ASCII_ONLY=False 可放宽域,可能出现更多解。")
if __name__ == "__main__": main()
|