The flag is split into 3 pieces hidden in comments: one in the page's HTML, one in the linked .js file, one in the linked .css file. Just inspect each one to reconstruct the full flag.
- Platform: picoGym
- Category: Web Exploitation
- Points: 100 pts
- Difficulty: Beginner
- Technique: Reading source code / DevTools
Challenge description
The challenge simply gives a URL to a website with no other hint:
"There is a flag in this html, but the button doesn't work? http://mercury.picoctf.net:PORT/"
Arriving on the page, we find a minimalist site: a title, a bit of text, and a button that doesn't seem to do anything when clicked. Nothing displayed on screen looks like a flag. The challenge's name — Insp3ct0r — is a fairly clear hint: we're going to need to inspect what's hiding behind the page rather than what it displays.
Step 1 — Read the HTML source code
First reflex on any web challenge: look at the page's source code with Ctrl+U (or right-click → "View page source"). We deliberately avoid opening DevTools directly here, because the element inspector shows the DOM after JS modifications, whereas "View source" shows the raw HTML as sent by the server — exactly what we want to look for forgotten comments.
Scanning through the file, we come across an HTML comment in the middle of the document:
<!-- part 1: picoCTF{*********** -->
<button onclick="myFunction()">Click Me</button>
First piece of the flag found, tucked away in a comment nobody was supposed to leave in production.
Step 2 — Explore the linked JavaScript file
Still in the HTML source code, we spot the tag that loads an external script, either in the <head> or just before the closing <body> tag:
<script src="js/main.js"></script>
Many beginners stop at the HTML and completely miss the referenced files. Yet all it takes is opening this URL directly in the browser (or via curl) to read the JS file in plain text:
$ curl -s http://mercury.picoctf.net:PORT/js/main.js
function myFunction() {
// part 2: ***********
alert("This button doesn't do anything");
}
Second piece found, this time in a JavaScript comment — and along the way, we understand why the button "doesn't do anything": it just triggers a useless alert, a decoy to distract attention.
Step 3 — Explore the CSS stylesheet
Same logic for the stylesheet, also referenced in the <head>:
<link rel="stylesheet" href="css/style.css">
We open it directly:
$ curl -s http://mercury.picoctf.net:PORT/css/style.css
body {
font-family: sans-serif;
background-color: #fdfdfd;
}
/* part 3: ***********} */
button {
padding: 10px 20px;
}
Third and final piece, hidden in a CSS comment.
Step 4 — Reconstruct the flag
All that's left is to string the three pieces together in the order they were found (HTML → JS → CSS):
part 1 (HTML): picoCTF{***********
part 2 (JS) : ***********
part 3 (CSS) : ***********}
picoCTF{***************************}
Step 5 — Bonus: automate with curl + grep
On a challenge with more files to explore, we can save time by scanning several resources at once to spot all the suspicious comments:
$ for f in index.html js/main.js css/style.css; do
echo "=== $f ==="
curl -s "http://mercury.picoctf.net:PORT/$f" | grep -E "<!--|//|/\*"
done
=== index.html ===
<!-- part 1: picoCTF{*********** -->
=== js/main.js ===
// part 2: ***********
=== css/style.css ===
/* part 3: ***********} */
A single command, and the three pieces come right out — handy as soon as the number of files to check grows.
🚩 picoCTF{ flag intentionally hidden }
The flag is deliberately hidden — follow the method, you've earned it. 💪
Key takeaways
This challenge is a perfect introduction to an essential web security reflex: everything sent to the browser is readable by the user, whether it's HTML, JavaScript, or CSS. A development comment left in production can leak sensitive information — credentials, internal paths, business logic, or even an entire flag.
- Always inspect ALL resources loaded by a page (JS, CSS, images), not just the HTML — development comments often end up in production
- "View source" (
Ctrl+U) shows the raw HTML from the server, while the DOM inspector shows the state after JS execution — the two are complementary - Automating the search for comments with
curl+grepsaves precious time on challenges with multiple files
Originally published on CTFdojo — join the CTFdojo Discord to discuss writeups and get notified about new ones.
Top comments (0)