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 |
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.
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.
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.
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.
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{***************************}
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.
The flag is deliberately hidden — follow the method, you've earned it. 💪
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.
curl + grep saves precious time on challenges with multiple filesBypassing an overly naive anti-SQL-injection filter to get past a login form.
Enumerating an insecure session cookie value with DevTools and Python to find the flag.
Discuss this writeup with the community on the CTFdojo Discord.
Join the Discord →