$ cat writeup.md…
$ cat writeup.md…
broncoctf2026
Task: Flask web page hides a flag inside a CSS-blurred image, gated behind solving 500 calculus problems tracked only in client-side JavaScript. Solution: read the page source to find the unauthenticated /api/v1/internal/fetch-config-blob endpoint that serves the original unblurred PNG on page load, then curl it directly to read the flag from the image.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
My friend tried to motivate me to review my derivatives by telling that me that I can unlock a top-secret image after I solve 500 challenges on this website. Unfortunately for her, I'm a firm believer in work smarter not harder, so I wonder if there's a way I can get the flag without actually doing any math?
A Flask web app ("Calculus Review") shows a blurred flag image and asks you to solve 500 derivative problems to "unblur" it. The goal is to read the flag without solving 500 math problems. The description's "work smarter not harder" is a direct hint that the gate is fake.
Recon of https://broncoctf-unblur-me.chals.io/:
Server: Werkzeug/3.1.8 Python/3.14.6 (Flask)
The single HTML page contains all the logic inline. Three things stand out:
The blur is pure CSS, not a server-side render:
#flag-image { filter: blur(20px); ... }
Removing this one CSS property reveals the original image.
The 500-problem gate lives entirely in client-side JavaScript — checkAnswer() increments a local correctCount and only calls flag.style.filter = "none" when correctCount >= 500. There is no server-side verification of progress.
The secret image is fetched immediately on page load, before any question is answered, from an internal API endpoint:
function loadSecretImage() { fetch('/api/v1/internal/fetch-config-blob') .then(r => r.blob()) .then(blob => { img.src = URL.createObjectURL(blob); }); } loadSecretImage(); // runs at load time
...
$ grep --similar