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.