What if we don't get any output?
The fourth challenge server is completely different. The flag on the website is no longer protected by a password login, it is the password login. Therefore, bypassing the login won't help you.
Even if you can trick the query to return true, you can't see the password. What you need to do is to steal (or
exfiltrate) the password. But in this challenge, the there is no way to output the password because the values
returned by the query are not displayed. So what can you do? You can steal the password out character by character
using a special query add-on: password = 'a' OR (1=1 AND 1=randomblob(1000000000));--
What this does
is in two steps. After deciding that password
is not equal to 'a'
, the SQL parser tests
(1=1 AND 1=randomblob(1000000000)
Because 1=1
is TRUE
, it goes on to test the
second half of the statement connected by AND
. To test if 1=randomblob(1000000000)
, it needs
to create a blob of 1000000000 RANDOM bytes, which takes a lot of time. However, if the parser tests (1=0 AND 1=randomblob(1000000000)
,
because 1
is NOT equal to 0
, the parser does not need to test 1=randomblob(1000000000)
because it already knows the statement is False
. The means the server will not pause for a long time to
find the result of the operation and will return near instantly. Therefore, the results of {SOME CONDITION}
can be extracted by the delay after OR ( {SOME CONDITION} AND 1=randomblob(1000000000));--
is run. If there is
a long delay, it is true, otherwise it is false.
What should the condition be?
But what should you use as {SOME CONDITION}
? This is when the functions hex()
and
substr()
come in handy. hex('a')
will convert the character a
into its hexadecimal
representation. substr()
will get the sub-string of a certain input. For example, substr(password,3,1)
will get 1
character starting from the 3rd
character of password
. If
password
were a string like 'password'
, it would have returned s
. But because
password
is a COLUMN NAME, it would return the substring of EVERY string in the password
column.
This will allow use to use a hex value to compare the character to a guess, like in
(hex(substr(password,3,1))=hex('a')
, where we compare the 3rd
character of the (only) row
entry in the password
column to a
.
Isn't this slow?
Yes, this is both slow and extremely sensitive to timing. Therefore, it is recommended to automate the guessing of
every character with a script or use a tool like SQLMap, because every character of the password has to be guessed one
by one until each character is found. Because of common network fluctuations, it is recommended to try each character twice.
Examples
password='' OR (hex(substr(password,4,1))=hex('a') AND 1=randomblob(1000000000));--
will delay if the
4th
character of password is a
and will not delay if it is not a
.
password='a' OR (hex(substr(password,3,1))=hex('e') AND 1=randomblob(1000000000));--
will delay if the
3rd
character of password is e
and will not delay if it is not e
.
password='a' OR (hex(substr(username,3,1))=hex('e') AND 1=randomblob(1000000000));--
will delay if the
3rd
character of username is e
and will not delay if it is not e
.