Description
Final boss! Log in as admin using the SQLite-backed login form. More keywords are filtered this time.
Visit /filter to see the full blocklist before attempting your bypass.
Setup
Open the challenge URL and check /filter to see blocked keywords.
curl http://mercury.picoctf.net:<PORT_FROM_INSTANCE>/filterSolution
Walk me through it- Step 1Enumerate the expanded blocklistGET /filter to see every blocked term. Compared to Web Gauntlet 2, this version typically also blocks LIKE, GLOB, additional comment styles (#, /**/), and possibly || itself.bash
curl http://mercury.picoctf.net:<PORT_FROM_INSTANCE>/filterLearn more
Strategy. With most named operators blocked, the goal is to manipulate the query without spelling out any blocked term. SQLite has two escape hatches that rarely show up in blocklists:
CHAR()for code-point strings, and hex blob literals for raw byte strings. - Step 2Build 'admin' from CHAR() or a hex blob literalIf you can output literal characters but not the word 'admin', generate the string with CHAR(97,100,109,105,110) or X'61646d696e'. Both evaluate to 'admin' inside the query without any letter appearing in your input.bash
# Generate CHAR() expression for any string: python3 -c "s='admin'; print(','.join(str(ord(c)) for c in s))" # 97,100,109,105,110 # Hex literal: python3 -c "print('admin'.encode().hex())" # 61646d696e -> X'61646d696e'Learn more
CHAR()function. SQLite'sCHAR(n1, n2, ...)returns the string formed by the given Unicode code points.CHAR(97,100,109,105,110)isadmin. No quote, no letter, no recognizable keyword.Hex blob literal.
X'hexstring'is a SQLite literal that decodes the hex into raw bytes.X'61646d696e'is the byte sequence61 64 6D 69 6Ewhich is ASCIIadmin. SQLite implicitly converts BLOB to TEXT for string comparisons, so it works as a username. Useful when you can output hex but not quotes around your payload.See SQL injection for CTF for the broader CHAR/hex/UNHEX trick library.
- Step 3Submit the bypass and retrieve the flagPOST a username crafted with CHAR() or a hex literal that ends up evaluating to admin in the query, plus any password. A successful login reveals the flag.bash
# Example bypass (assumes /* and */ are allowed): curl -X POST http://mercury.picoctf.net:<PORT_FROM_INSTANCE>/login \ -d "username=admin'/*&password=x"Learn more
Multiline comment bypass. If
/*and*/are unblocked,admin'/*closes the username string and starts a multiline comment that swallows the password check until the next*/the server appends. Shape of the resulting query:WHERE username='admin'/* AND password='x'. The comment kills the password condition.Defense in depth doesn't help here. Each filter version closes one escape hatch and SQLite offers another. Parameterized queries are the only fix.
Flag
picoCTF{...}
SQLite's CHAR() function and hex blob literals bypass even aggressive keyword filters. The only real fix is parameterized queries, not blocklists.