4

I'm trying to analyse the test results for blind SQL injection using Acunetrix Vulnerability Scanner.

URL encoded POST input address was set to 
if(now()=sysdate(),sleep(0),0)/*'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"*/

Tests performed: 
if(now()=sysdate(),sleep(6),0)/*'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"*/ => 12.062 s

HTTP headers sent to POST were:
address=if(now()%3dsysdate()%2csleep(0)%2c0)/*'XOR(if(now()%3dsysdate()%2csleep(0)%2c0))OR'%22XOR(if(now()%3dsysdate()%2csleep(0)%2c0))OR%22*/&

If we supply any value to address variable data is getting inserted to tables. Is there any way to modify the header data for the address variable so that instead of storing data, we can retrieve the data and perform select operations and get to know about the internal schema?

It would also be really helpful if someone could help me in understanding the internals behind this statement:

if(now()=sysdate(),sleep(0),0)/*'XOR(if(now()=sysdate(),sleep(0),0))OR'"XOR(if(now()=sysdate(),sleep(0),0))OR"*/
2

The statement

if(now()=sysdate(),sleep(6),0)/*'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"*/

basically tries three different injection points at once.

1. The direct one

    if(now()=sysdate(),sleep(6),0)/*...*/

If the input would be directly interpreted (without any escape characters) this sql would be triggered. The rest of the input string would be commented out.

2. Single quotation marks '..'

    ..'XOR(if(now()=sysdate(),sleep(6),0))OR'..

If the input is encapsulated in the statement with single quotation marks, the characters at the beginning and the end will break out of the context and the sql between them will be interpreted.

3. Double quotation marks ".."

    .."XOR(if(now()=sysdate(),sleep(6),0))OR"*/

Same as with the single quotation marks but works for inputs that are encapsulated in double quotation marks.

What the query might look like

If it is PHP that builds this MySQL statement, it might look like one of the following ones (depending on the case that triggers it):

sql = "INSERT INTO tbl_addresses (address,user) VALUES("+$_POST["address"]+",..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES('"+$_POST["address"]+"',..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES(\""+$_POST["address"]+"\",..)"

How it works

The statements are the same for each injection case.
It first compares if the return value of the "now" function matches that of the "sysdate" function. If that is the case (and it should be), the "sleep" function will be called with a time of either 6 or 0 seconds, resulting in the delay that you observed.

It is possible to exploit this as a purely blind SQL injection. A tool like sqlmap will help you with that, as it would take quite a lot of time if you do it by hand.
What it will basically do (in simplified form), is issue statements like:

if ( nth_character_of(password) == "a" , sleep(6), 0)

Where "nth_character_of" will be a database specific function that picks a character from a string and "password" will be a query that returns whatever value you want to retrieve from the database. It will also use an optimized method to find the correct characters.
If sqlmap experiences a delay it will know that the compare was correct and iterate further.

Narrowing it down

You can try to supply each of the three injection cases separately and have a look which one results in the delay. This way your injection string becomes much shorter and easier to modify and understand.

What you could try

If the value is indeed returned in the frontend, as you said in a comment under another answer, that SQL injection is not purely blind.
You might be successfull trying to insert your value directly like that:

version()/*'+version()+'"+version()+"*/

to retrieve the version in the frontend or with your query in all three places like:

(select password from users LIMIT 1)/*'+(select password from users LIMIT 1)+'"+(select password from users LIMIT 1)+"*/

The one with the custom query might not work depending on the encoding that in needed in this specific application but it is worth a try.

0

[NOTE: see comment thread - there is actually sql injection here, as demonstrated by the 12 second round trip time]

If that statement is actually being inserted into the address column, then you likely do not have a sql injection there - at least not one exploitable by that particular string.

It looks like it is trying to cause a pause in execution that is detectable by the exploit framework - because it is blind (not data returned back), it is difficult to tell from the outside if it is working. That's why the sleep.

However, an injection happens not when data is put in the right place (if someone puts this in the address field, you'd expect it to end up in the address column), but when the data is instead interpreted as code. From what you are saying, that isn't happening. Please clarify if I misunderstood.

  • That particular code was injected by tool to check for injection. When that code was inserted it evaluated to 0 and displayed as 0 from the front end. – Gurunatha Reddy G Sep 21 '16 at 2:53
  • What do you mean by 'injected' here? Injected means put into a command string and parsed as a command, typically - if it wasn't actually run as a command, then it wasn't sql injection. If it was, it was. – crovers Sep 21 '16 at 13:29
  • When I refer the word "injected" , I mean POST parameter value for address variable is sent as above mentioned query in HTTP headers and submitted the request, previous value of address variable got overridden and the above string got evaluated and is getting displayed as 0. – Gurunatha Reddy G Sep 21 '16 at 14:43
  • Did it get evaluated by the sql engine, though or is 0 just a failed parse of it in the display code? A POST making changes to the DB is generally what is supposed to happen - that's what posting to that url is for. Easy way to check - if you do a POST with an address like 'THISISJUSTABUNCHOF$@%@%@RANDOMGARBAGE' - does it behave the same way? If so, this is not a sql injection vulnerability. It may indicate you want data validation at the server level (just so you don't store rubbish, but rather spit it back at the user), rather than just at the client level, but that's a different thing – crovers Sep 21 '16 at 14:53
  • A POST making changes to the DB is generally what is supposed to happen-- Yes it is, but the form i'm testing now is in user panel where will not have access to modify these values. When I tested using Acuentrix scanner, it showed that while navigating to user profile panel if we send post data, then the values are getting modified. If I modify the header to POST "THISISJUSTABUNCHOF$@%@%@RANDOMGARBAGE" then the same value will get inserted. My question here is , if the above poseted string got evaluated and resulted to 0 , then can we modify the request sent, to do select operations. – Gurunatha Reddy G Sep 21 '16 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.