Description
Can you conjure the right bytes? Download `app.py` and the compiled `spellbook` binary, then reconstruct the required payload.
Setup
Download app.py and the compiled spellbook binary.
Read app.py and analyse the binary -- both are needed to understand the full validation.
cat app.py
file spellbook
chmod +x spellbook
Solution
- Step 1Read the source code and understand the challengeDownload app.py and the spellbook binary. app.py asks you to send the raw 4-byte little-endian address of a named function inside the spellbook binary, for 3 randomly selected rounds. The functions are: ember_sigil, glyph_conflux, astral_spark, binding_word.cat app.pyfile spellbook
- Step 2Read all four function addresses from the binaryUse pwntools ELF to read the symbol table and get the address of each function. The binary is not PIE (addresses are fixed), so you can precompute all four addresses.python3 - <<'EOF' from pwn import ELF, p32 elf = ELF("./spellbook", checksec=False) funcs = ["ember_sigil", "glyph_conflux", "astral_spark", "binding_word"] addrs = {name: elf.symbols[name] for name in funcs} for name, addr in addrs.items(): print(f"{name}: {hex(addr)} -> {p32(addr).hex()}") EOF
- Step 3Write the solve scriptConnect to the server, read each round's prompt to get the requested function name, then send its 4-byte little-endian address. Repeat for 3 rounds.python3 - <<'EOF' from pwn import * HOST, PORT = "<HOST>", <PORT_FROM_INSTANCE> elf = ELF("./spellbook", checksec=False) funcs = ["ember_sigil", "glyph_conflux", "astral_spark", "binding_word"] addrs = {name: elf.symbols[name] for name in funcs} r = remote(HOST, PORT) r.recvuntil(b"unlock the flag.") # banner for _ in range(3): line = r.recvuntil(b"==> ", timeout=5).decode() # Find the function name requested for name in funcs: if f"'{name}'" in line: payload = p32(addrs[name]) r.send(payload) break print(r.recvall(timeout=3).decode()) EOF
Flag
picoCTF{byt3m4ncy_3_...}
app.py randomly selects 3 of 4 functions (ember_sigil, glyph_conflux, astral_spark, binding_word) from the spellbook binary and asks for their raw 4-byte little-endian addresses. Use pwntools ELF to read symbol addresses and send them per round.