Description
A sprawling static site hides the flag somewhere in its source tree. Mirror the entire site and grep for picoCTF.
Setup
Use wget -r -np -k <url> to recursively download the entire site without traversing upward.
Run grep -R picoCTF inside the mirrored directory to locate the flag.
wget -r -np -k http://saturn.picoctf.net:<PORT_FROM_INSTANCE>/cd saturn.picoctf.net:<PORT_FROM_INSTANCE> && grep -R picoCTFgrep -RhoE 'picoCTF\{[^}]+\}' .Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Mirror everything
ObservationThe challenge is a sprawling static site with no obvious place for the flag. Mirroring the whole thing with wget and searching locally beats clicking through page by page.wget -r -np -krecursively pulls down every linked file (-r), refuses to climb above the starting directory (-np= no-parent), and rewrites links inside the local copy so the mirror is browsable offline (-k). The result is the full /problem directory ready for offline grep.What didn't work first
Tried: Clicking through the site manually in a browser and using View Source on each page.
The site runs to many pages and the flag sits in a non-obvious asset such as a CSS file. Checking by hand takes too long, and View Source shows one page at a time. Mirroring locally lets one grep search the entire tree.
Tried: Running wget without the -np flag, which causes it to crawl upward through the server directory tree.
Without -np, wget follows links above the starting path and can pull down huge amounts of unrelated content, or get stuck in a redirect loop. The flag confines the download to the target directory and below, which keeps the mirror manageable.
Learn more
wget is a command-line tool for downloading files and mirroring websites. The flags used here:
-r(recursive download),-np(no-parent, don't traverse above the starting URL), and-k(convert links for local browsing). Together they create a complete local copy of the site's directory tree.This technique is useful when a site has many pages or files - rather than clicking through each one manually, you download everything at once and analyze offline. In real-world web recon, httrack and Scrapy provide similar offline mirroring with more configuration options.
Static sites (no server-side rendering) are particularly amenable to this approach because every file is directly accessible via HTTP. Dynamic sites (React, Next.js, PHP) may not expose source files directly, but their JavaScript bundles, CSS, and API responses can still contain sensitive data worth examining.
Step 2Search recursively
ObservationWeb challenges often hide the flag in a CSS or JS comment rather than in visible HTML. A recursive grep across the whole mirrored directory covers every file type in one pass.grep -R picoCTFrecursively searches the mirrored tree and surfaces the file containing the flag. A second pass withgrep -hoE 'picoCTF\{[^}]+\}'strips everything except the flag itself.A typical run looks like this:
$ cd saturn.picoctf.net:<PORT_FROM_INSTANCE> $ grep -R picoCTF css/style.css:/* picoCTF{1nsp3ti0n_0f_w3bpag3s_8de9...} */ $ grep -RhoE 'picoCTF\{[^}]+\}' . picoCTF{1nsp3ti0n_0f_w3bpag3s_8de9...}-hsuppresses the file name,-oprints only the match,-Eenables the extended regex.What didn't work first
Tried: Searching only the HTML files by running grep on the downloaded index page, and missing the flag in a CSS or JS asset.
Flags in web challenges usually hide in comments inside CSS or JavaScript rather than in the HTML. Grep a single file, or only the .html files, and you miss them. Recursing over the mirrored directory covers every file type at once.
Tried: Using browser DevTools to search page source instead of grepping the mirrored files.
The Sources panel lists only files loaded during the current visit, so assets linked from pages you have not opened never appear. Grepping the full mirror is the only reliable way to cover every file without visiting each page by hand.
Learn more
grep -R pattern directoryperforms a recursive content search through all files in a directory tree. It's one of the most powerful everyday tools for developers and security researchers alike. The-lflag shows only filenames;-nadds line numbers;-imakes the match case-insensitive.In CTF competitions, flags often appear in comments, JavaScript files, CSS, configuration files, or metadata - places that aren't rendered visibly in a browser. A broad recursive grep covers all of these simultaneously and is far faster than manually checking each page's view-source.
For larger codebases or binary files, ripgrep (
rg) is a faster modern alternative to grep. It respects.gitignorepatterns, handles binary files gracefully, and produces colorized output by default. Both tools are essential for source code review and CTF challenges involving large file sets.
Interactive tools
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
Flag
Reveal flag
picoCTF{1nsp3ti0n_0f_w3bpag3s_8de9...}
When in doubt, mirror and grep-many web challenges boil down to hidden strings in source files.