format-string-exploitation

Format string exploitation playbook. Use when printf-family functions receive user-controlled format strings, enabling arbitrary stack reads (%p/%s), arbitrary memory writes (%n/%hn/%hhn), GOT/hook overwrites, and canary/libc/PIE leaks.

By yaklang · 3,025 installs

npx skills add yaklang/hack-skills --skill format-string-exploitation

Source repository · Upstream listing

SKILL: Format String Exploitation — Expert Attack Playbook AI LOAD INSTRUCTION : Expert format string techniques. Covers stack reading, arbitrary write via %n, GOT overwrite, malloc hook overwrite, pointer chain exploitation, blind format string, FORTIFY SOURCE bypass, 64 bit null byte handling, and pwntools automation. Distilled from ctf wiki fmtstr, CTF patterns, and real world scenarios. Base models often miscalculate positional parameter offsets or forget 64 bit address placement after format string. 0. RELATED ROUTING [stack overflow and rop](../stack overflow and rop/SKILL.md) — combine format string leak with stack overflow for full exploit [binary protection bypass](../binary protection bypass/SKILL.md) — format string is the primary canary/PIE/ASLR leak method [arbitrary write to rce](../arbitrary write to rce/SKILL.md) — convert format string write primitive to code execution targets [heap exploitation](../heap exploitation/SKILL.md) — heap address leak via format string for heap exploitation 1. VULNERABILITY IDENTIFICATION Vulnerable Pattern Quick Test 2. READING MEMORY Stack Leak (%p) Format Action Use %p Print next stack value as pointer Sequential stack dump %N$p Print N th parameter as pointer Direct positional access %N$lx Same as %p but explicit hex (64 bit) Portable %N$s Dereference N th parameter as string pointer Read memory at pointer value Finding Your Input Offset Leaking Specific Values Target Method Stack Position Canary %N$p where N = canary offset from format string Typically at offset buf size/8 + few Saved RBP %N$p (just above return address) Leaks stack address → stack base Return address %N$p Leaks .text address (PIE base = leak & ~0xfff offset) Libc address %N$p where N points to libc start main+XX return on stack libc base = leak offset Reading Arbitrary Address (%s) 3. WRITING MEMORY (%n) Write Specifiers Specifier Bytes Written Width %n 4 bytes (int) Characters printed so far %hn 2 bytes (short) Characters printed so far (mod 0x10000) %hhn 1 byte (char) Characters printed so far (mod 0x100) %ln 8 bytes (long) Characters printed so far Arbitrary Write Technique Goal : Write value V to address A . 32 bit (address on stack directly): 64 bit (address AFTER format string): Byte by Byte Write with %hhn Write one byte at a time for precision (6 writes for full 48 bit address on 64 bit): 4. PWNTOOLS fmtstr payload() FmtStr Class (Interactive Exploitation) 5. GOT OVERWRITE VIA FORMAT STRING Common Targets Overwrite With Trigger printf@GOT system Next printf(user input) → system(user input) , send /bin/sh strlen@GOT system If strlen(user input) called puts@GOT system If puts(user input) called atoi@GOT system If atoi(user input) called (send sh as "number") stack chk fail@GOT Controlled addr Bypass canary check entirely exit@GOT main Create infinite loop for multi shot exploit Hook Targets (glibc < 2.34) Target One gadget Trigger malloc hook one gadget addr Any printf with large format → internal malloc free hook system Trigger free("/bin/sh") 6. STACK POINTER CHAIN EXPLOITATION When format string is not directly on the stack (e.g., stored in a heap buffer referenced by stack pointer), use pointer chains on the stack to achieve arbitrary write. Two Stage Write This requires finding existing pointer chains on the stack (e.g., saved frame pointers forming a chain: rbp → prev rbp → prev prev rbp). Finding Pointer Chains 7. BLIND FORMAT STRING Remote service, no binary, no source — exploit format string blind. Methodology Step Action Purpose 1 Send %p × 50 Dump stack, identify address patterns 2 Identify offsets Find libc addrs (0x7f...), stack addrs (0x7ff...), code addrs 3 Find input offset Send AAAA%N$p for N=1..50, find 0x41414141 4 Identify binary base Code addresses reveal PIE base (or fixed base if no PIE) 5 Leak GOT entries If binary base known, read GOT via %N$s with GOT address 6 Calculate libc base GOT value libc symbol offset 7 Overwrite GOT %n to rewrite GOT entry with system address 8. FORTIFY SOURCE BYPASS FORTIFY SOURCE (gcc D FORTIFY SOURCE=2 ) replaces printf with printf chk which forbids %N$n (positional writes). Bypass Techniques Method Detail Use %hn sequentially (no positional) Print exact byte count, %hn , adjust, %hn — fragile but works Stack based exploit If format string is on stack, use non positional %n with stack position control Heap overflow instead FORTIFY doesn't protect heap — combine with heap bug Return to printf ROP to call unfortified printf (if available in binary or libc) 9. 64 BIT CONSIDERATIONS Challenge Solution Addresses contain \x00 (null byte terminates format string) Place addresses AFTER format specifiers, pad to alignment Address width: 6 significant bytes Write 3 × %hn (2 bytes each) or 6 × %hhn Larger stack offset range Input may be at offset 6+ due to 6 register args saved 48 bit address space Only bottom 48 bits of 64 bit used Layout Template (64 bit) 10. DECISION TREE