WCU / Cybersecurity
~/CSC 472/Lab 3
CSC 472 · Lab 3

Format String Vulnerabilities

printf(buf)buf = user inputRSIRDXRCXR8R9then values pulled from the stack →stack: %p %p %p ... %n
%p leaks these slots; %n writes to them — an arbitrary read/write primitive.

The goals of this lab:

  • Understand how an attacker-controlled format string becomes an arbitrary memory read and write primitive.
  • Use format specifiers to leak stack memory and to overwrite a chosen target.
  • Redirect control flow to a win() function using a %n-family write.

Background

The bug is a single misuse: the program calls printf(buf) where buf is user input, instead of the safe printf("%s", buf). Because printf interprets buf as a format string, an attacker who types conversion specifiers makes printf read (and even write) memory:

  • %p/%x print values pulled from argument registers and then the stack — a stack leak.
  • Positional %7$p selects the 7th argument directly.
  • %s treats an argument as a pointer and prints the string it points to — an arbitrary read.
  • %n writes the number of characters printed so far into a pointed-to integer — an arbitrary write. Width specifiers control the value; %hn/%hhn write 2/1 bytes.

On x86-64, after the format string, further conversions consume RSI, RDX, RCX, R8, R9, then values from the stack.

Experiment Setup

  • Log in to Badger CTF and copy the source: cp /workdir/ss2026/lab3/lab3_fmt.c .
  • Compile (GOT left writable for the exercise): gcc lab3_fmt.c -o lab3_fmt -fno-stack-protector -no-pie -z norelro
  • The program prints the address of win() as a hint and reads three lines, so you can build a multi-step payload.

Lab Exercise (10 points)

Task 1: Find your offset

Send a probe such as AAAA.%p.%p.%p.%p.%p.%p and locate where your AAAA (0x41414141) appears in the output. That index is your format-argument offset.

Q1: What is your argument offset, and how did you determine it? (2 pts)

Task 2: Leak with format specifiers

Q2: Use %p specifiers to leak several stack values. Identify one leaked value that looks like a code or libc address and explain how you can tell. (2 pts)

Task 3: Arbitrary write to redirect control flow

Overwrite a target so that control flow reaches win() (which spawns a shell). Good targets: the GOT entry of a function called after your input (e.g., printf), or a saved return address. pwntools fmtstr_payload builds the %n chain for you once you know your offset, target, and value. A skeleton (lab3_fmt_exploit.py) is provided.

Q3: Which target address did you overwrite, and with what value? Show your payload construction. (3 pts)
Q4: Provide your exploit.py and a screenshot of the resulting shell. Run id in the shell. (3 pts)

Hint

Review Class 06: Format String Vulnerabilities. %n writes can be finicky — start by writing a small known value and confirm it lands before attempting the full address.

Deliverables

A PDF report with Q1—Q4, your exploit script, and screenshots.

Submission

  • The lab due date is available on our course website. Late submission will not be accepted.
  • Submit your assignment to D2L directly.
  • No copy or cheating is tolerated. If your work is based on others' or AI, please give clear attribution. Otherwise, you WILL FAIL this course.