Two objectives: log into the admin panel, and find the hidden text file in the flags folder. That's the whole mission statement. What followed was considerably less simple, especially given my well-documented distaste for databases.
Enumeration
nmap -T4 -n -sC -sV -Pn -p- 10.146.148.157
Port 22 and Port 80. Started with a site visit, and also ran the full vuln scan in parallel:
nmap -sS -Pn -sC -sV --script=vuln -T4 -A 10.146.148.157
The output of the above Nmap is a bit lengthy to post here. Why is it my favorite Nmap syntax? It lists all of the CVEs and CNVDs, their severity, and available exploits. In this case: possible HTTP access points, enumerated subdomains that felt like key evidence, discoverable credentials, and more known vulnerabilities than necessary. Filed away for later.
Site Reconnaissance
Most nav menu items were dead links. Two that weren't: /login and /adminLogin007.php — that second one surfaced during the vuln scan.
Restricted area. Any time I see a restricted area, it's like a button labeled "Don't Touch." I have honed the art of self-control.
View Source on /login.php showed a client-side filter living at /script.js. That's the first real lead.
script.js blocked a specific keyword list — or, and, union, select, ", ' — before any POST request reached functions.php. Client-side only. The filter didn't exist server-side. That's the opening.
Ran Gobuster while planning the bypass:
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-x html,js,txt,php,db,json,log \
-u http://10.146.148.157
SQLi — Login Bypass
Intercepted the login POST in Burp Suite and sent it to Repeater:
The client-side filter blocked OR — but the filter was JavaScript, not server-side. Burp bypasses it entirely. The payload that worked:
username=a' || 1=1; -- -&password=a&function=login
|| instead of OR. The original attempt with OR failed. That distinction matters — the server was doing some filtering of its own, just not catching the pipe operator.
In. Gobuster hadn't finished yet, but mail.log was already visible in the results. Filed away.
Database Manipulation — Recursive Filter Bypass
The dashboard had an editable leaderboard. Each edit generated a POST to /edit_leaderboards.php. The input was reaching the database — confirmed by updating medal counts and watching the changes propagate, including one that changed China's data instead of USA's, which was clarifying in its own way.
The real discovery came from testing what the server would actually accept. Strings worked — confirmed by updating a country name to "ME" and watching it stick. Look at me. I won all of these medals by myself. Very impressive, me.
The server was filtering SQL keywords server-side as well. Standard payloads came back blank. The breakthrough was realizing the filter was doing a simple string match — so nesting the keyword inside itself bypassed it:
seSELECTlect
When SELECT was stripped by the filter, seSELECTlect collapsed into select. Plain sight obfuscation.
mail.log — Credential Recovery and Table Drop
mail.log contained the instruction to DROP the table — and the admin credentials. The recursive bypass made the final payload possible:
rank=1&country=&gold=22; DROP TABLE users -- -&silver=21&bronze=12345
Database corrupted. Logged into the admin panel with the credentials from mail.log:
Flag 1. And my database alterations were still visible, which made it that much sweeter.
Gobuster had also confirmed a /flags directory:
SSTI — Twig CVE-2024-45411
The admin account had an additional nav item: Profile. A photo upload field — the kind that deserves immediate scrutiny.
Tested for server-side template injection:
{{7x7}}
{{7x7}} was not treated as a string. It returned 49. That's SSTI confirmed.
Remember that massive vuln Nmap from the beginning? That's coming in handy right now. The web app runs Twig v2.14.0 — exploitable via CVE-2024-45411, a sandbox bypass vulnerability. The math really maths.
RCE achieved. From here the path to /flags is yours to find.
Full Attack Chain
nmap → ports 22 + 80, vuln scan surfaces CVEs and Twig version
→ /login.php client-side filter in script.js → Burp bypass
→ SQLi login: a' || 1=1; -- - → dashboard access
→ edit_leaderboards.php → string injection confirmed
→ recursive keyword bypass: seSELECTlect
→ mail.log → DROP TABLE users → admin credentials
→ admin login → Flag 1
→ Profile upload → {{7x7}} → SSTI confirmed
→ Twig CVE-2024-45411 sandbox bypass → RCE → /flags