Format String Exploitation
A skill for exploiting format string vulnerabilities in C binaries using pwntools.
When to Use This Skill
Use this skill when:
- You're given a binary with a format string vulnerability (e.g.,
printf(user_input)without format specifiers) - You need to leak stack memory or overwrite GOT entries
- You want to redirect function calls (printf → system) for shellcode execution
- You're working on CTF challenges involving format string bugs
Quick Start
Configure the connection in
scripts/format_string_exploit.py:- Set
LOCAL = Truefor local testing - Set
REMOTETTCP = Truefor remote TCP - Set
REMOTESSH = Truefor SSH (e.g., OverTheWire)
- Set
Run the exploit:
python scripts/format_string_exploit.pyReview the output - the script will:
- Automatically find the format string offset
- Overwrite GOT entries
- Spawn an interactive shell
How Format String Exploitation Works
The Vulnerability
Format string vulnerabilities occur when user input is passed directly to format functions like printf(), fprintf(), or sprintf() without a format string argument:
// VULNERABLE
char *input = get_user_input();
printf(input); // User can use %x, %s, %n to read/write memory
// SAFE
printf("%s", input); // Format string is controlled
Attack Phases
- Find the offset: Determine which position in the format string corresponds to your input
- Leak memory: Use
%xor%pto read stack values - Overwrite GOT: Use
%nto write addresses to memory - Redirect execution: Point printf GOT entry to system PLT
- Trigger shell: Find where printf is called with controlled input
Configuration Options
| Variable | Description | Default |
|---|---|---|
LOCAL |
Run binary locally | True |
REMOTETTCP |
Connect via TCP | False |
REMOTESSH |
Connect via SSH | False |
GDB |
Attach GDB for debugging | False |
LOCAL_BIN |
Path to vulnerable binary | "./tyler" |
PREFIX_PAYLOAD |
Bytes to prepend to payload | b"" |
SUFFIX_PAYLOAD |
Bytes to append to payload | b"" |
MAX_LENTGH |
Maximum payload length | 999999 |
Example Usage
Local Binary
LOCAL = True
LOCAL_BIN = "./vulnerable_binary"
Remote TCP
REMOTETTCP = True
# Update in connect_binary():
P = remote('10.10.10.10', 1338)
SSH (OverTheWire)
REMOTESSH = True
REMOTE_BIN = "./tyler"
# SSH credentials configured in connect_binary()
Advanced: Loop Back for Extra Execution
Some binaries require looping back to the vulnerability for a second exploitation. Uncomment in the script:
P_FINI_ARRAY = ELF_LOADED.symbols["__init_array_end"]
INIT_LOOP_ADDR = 0x8048614 # Address to return to
format_string.write(P_FINI_ARRAY, INIT_LOOP_ADDR)
Troubleshooting
Offset not found
- Increase the search range in
get_formatstring_config() - Check if the binary has ASLR enabled (
setarch -R) - Verify the binary actually has a format string vulnerability
GOT overwrite fails
- Check if the binary is PIE (Position Independent Executable)
- Verify GOT entry is writable
- Ensure you're writing the correct address
Shell doesn't spawn
- Find where printf is called with user-controlled input
- The input should contain
/bin/shor similar - Check if the binary has a second call to printf after GOT overwrite
References
Script Files
scripts/format_string_exploit.py- Main exploitation script
Run the script after configuring your connection settings. The script will automatically:
- Find the format string offset
- Overwrite printf GOT with system PLT
- Spawn an interactive shell