Files
ctf/2025/glacier/rev/wisdom/decrypt.py
2025-11-22 21:21:24 +01:00

44 lines
1.5 KiB
Python

def solve():
# Constants
MAGIC = 0x0D15EA5E
# Data extracted from .rodata
# KEY array (46 bytes)
KEY = [
0x36, 0xD1, 0xD9, 0xDB, 0x89, 0xA5, 0xBE, 0xDE, 0x5E, 0xE6,
0x0F, 0x12, 0x02, 0x1A, 0xE1, 0xC0, 0x0B, 0x4C, 0xA3, 0xB0,
0x08, 0xE9, 0xA0, 0xD0, 0xD1, 0xEA, 0x88, 0x71, 0x23, 0x87,
0xD0, 0x41, 0xD8, 0x04, 0x09, 0xA2, 0xFD, 0x20, 0x02, 0x28,
0x0D, 0x75, 0x8D, 0x66, 0xA8, 0x5C
]
# FLAG array (Target bytes from memcmp, 46 bytes)
# Note: These are the bytes labeled 'FLAG' in the assembly dump
TARGET = [
0xAF, 0x0F, 0x09, 0x18, 0x4C, 0x47, 0x33, 0x44, 0x64, 0x0E, 0xBC,
0x75, 0xBD, 0xA5, 0xD6, 0xEE, 0xA0, 0xC9, 0x22, 0x3A, 0xB9,
0xCF, 0x3C, 0xD6, 0xEB, 0xE7, 0xFD, 0x45, 0xBE, 0xF8,
0x20, 0xB0, 0x2B, 0x6E, 0xA7, 0xFE, 0x02, 0x49, 0x73, 0x84, 0xA2,
0x78, 0xF0, 0x88, 0xC2, 0x52
]
flag_chars = []
# Iterate 46 times matching the loop in the C code
for i in range(46):
# 1. Reverse the arithmetic: Target - MAGIC + i
# We use & 0xFF to ensure we stay within byte boundaries
# and handle the negative results of subtraction correctly.
intermediate = (TARGET[i] - MAGIC + i) & 0xFF
# 2. Reverse the XOR: intermediate ^ KEY
decrypted_char = intermediate ^ KEY[i]
flag_chars.append(chr(decrypted_char))
print("Flag found:")
print("".join(flag_chars))
if __name__ == "__main__":
solve()