1. Overview
Event: CODEX CTF 2025
Date: 15 November 2025
Author: Fa’iza Alfagading Sofwan (FAZer0)
2. Crypto: The Tiny Exponent Incident (Hastad’s Broadcast Attack)
Vulnerability Analysis
The challenge supplies 3 RSA ciphertexts (c1, c2, c3) corresponding to 3 distinct moduli (n1, n2, n3) with the same public exponent e = 3.
According to Hastad’s Broadcast Theorem, by applying the Chinese Remainder Theorem (CRT) across pairwise coprime moduli n1, n2, n3, we can solve for:
C = m^3 mod (n1 * n2 * n3)
Since m < n_i for all i, m^3 < n1 * n2 * n3, allowing us to extract the integer cube root of C directly over integers Z without modular reduction.
Python Solver with gmpy2
import gmpy2
from Crypto.Util.number import long_to_bytes
from functools import reduce
e = 3
c_list = [c1, c2, c3]
n_list = [n1, n2, n3]
def chinese_remainder_theorem(c, n):
prod = reduce(lambda a, b: a * b, n)
total = 0
for c_i, n_i in zip(c, n):
p = prod // n_i
total += c_i * int(gmpy2.invert(p, n_i)) * p
return total % prod
crt_val = chinese_remainder_theorem(c_list, n_list)
m, exact = gmpy2.iroot(crt_val, e)
if exact:
flag = long_to_bytes(int(m)).decode()
print(f"[+] Recovered Flag: {flag}")
3. Reverse: The Packed Grimoire
The binary was packed to obscure the static flag comparison logic. By launching the process dynamically under Linux and dumping memory structures via GDB core dump utilities:
# 1. Start process in background
./chall &
PID=$!
# 2. Inspect memory mapping and dump memory core
sudo gcore -o core_dump $PID
# 3. Extract flag strings from memory
strings core_dump.$PID | grep -E "CODEX\{.*\}|flag\{.*\}"