$ cat writeup.md…
$ cat writeup.md…
broncoctf2026
Task: a single 3395-char Unicode line (flag.txt) whose riddle hints at a terminal size. Solution: factor the length (3395 = 5*7*97), wrap at 97 columns to reveal FIGlet 'ticks' block letters around a Braille oyster, render to pixels for OCR, then read the glyphs in a clockwise spiral dictated by edge arrows.
I used to be too big picture, never focusing on the details (keeping track of like 90 things at once). Then, I starting looking into things a little bit too much (this phase only lasted like 7 days). Nowadays though, I am primed to look at things with just the right width (and height too). Anyways, here's the flag! You should be able to read it just fine, as long as you align with my mindset.
The only artifact is flag.txt from the CTFd instance: one very long single line of Unicode text. The riddle is a disguised hint about the correct terminal width (and height) at which the line should be wrapped so that the ASCII art becomes readable.
file flag.txt reports "Unicode text, UTF-8, with very long lines". The file is a single line of 3395 characters (4140 bytes). The character set is small:
/ \ _ < > ^ v — ASCII art strokes and directional markersThe riddle encodes a terminal size through numeric decoys:
The clean way to find the width is to factor the character count:
3395 = 5 × 7 × 97
Wrapping the line every 97 characters yields exactly 35 rows (5 × 7). The intended terminal is 97 columns × 35 rows.
import sympy s = open('flag.txt').read().rstrip('\n') print(len(s), sympy.factorint(len(s))) # 3395 {5:1, 7:1, 97:1} w = 97 print('\n'.join(s[i:i+w] for i in range(0, len(s), w)))
Wrapped at 97 columns, the / and \ characters form large block letters — a narrow FIGlet "ticks"-style font (the standard figlet -f ticks uses /\/\ per stroke; this puzzle uses a half-width /\ variant). The _ characters are the font's background padding. The Braille block (U+2800) in the middle draws an oyster — a thematic nod to the idiom "the world is your oyster".
Treat / and \ as filled pixels and everything else as background, then rasterize to a scaled PNG so the letters become legible:
from PIL import Image rows = [s[i:i+97] for i in range(0, len(s), 97)] scale = 9 img = Image.new('1', (97*scale, 35*scale), 1) px = img.load() for r in range(35): line = rows[r] if r < len(rows) else '' for c in range(97): if c < len(line) and line[c] in '/\\': for dy in range(scale): for dx in range(scale): px[c*scale+dx, r*scale+dy] = 0 img.save('clean.png')
The glyphs are laid out in a 6×8 grid of FIGlet letters wrapping around the central oyster:
bronco{r
le_world
o as <- oyster image occupies the middle of these three lines
h ti
w z
_say_...
Non-letter markers appear at the edges of the grid:
>> at the left of band le_world → read rightwardvvvv down the right side → read downward<< at the bottom-right → read leftward^^^^ up the left side → read upwardThese trace a clockwise spiral around the oyster. Reading the grid naively in row-major order produces gibberish (bronco{rle_worldoashtiwz_say_...); the arrows are mandatory.
Verified glyph-by-glyph from the render:
resizing (r-e-s-i-z-i-n-g)le_world = whole_world (who + le + _world)say (appears reversed as _yas_ because the spiral crosses the bottom right-to-left)Assembling the spiral in natural reading order yields the sentence matching the riddle's theme — fitting "the whole world" into the terminal by resizing it:
bronco{REDACTED}
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar