How to shoot in the dark: Improved Blind SQLi

I really like this method, i feel that it should replace the method you are currently used for blind injection if you aren't using this one!


Blind SQL injection is all about knowing how to ask the right questions. The problem is you have to ask alot of questions before finding out something useful! And we also know most of the time we are trying to find out things like passwords/password hashes, usernames or emails and these things are just simply saved as a bunch of characters in a table somewhere.

The conventional Blind injection will have you probing every character of a given, guessing every possible character in the ascii table until you manage to get the right one. Worst case this will take 127 requests per character!

But there is a a faster way, which uses the way characters are represented to guess them faster.

Before we begin (lols the infamous words) I need to discuss the old Blind injection, after which I'll talk you through how the improvement was developed.

Conventional Blind injection
We all know how the story goes, you have a script that you know is injectable but:
  • No error messages are displayed
  • No direct result of your injection is visible after the query
So you result to playing 20 questions with the web app --- or O(n*127) questions, where n is the character length of the information. Usually you might do in the way  demonstrated in the screen shot below.

Blind brtuteforce
This method is tried and true, and still costs a lot of companies millions of dollars, and its because of its popularity that it needs improvement and other variants!

Or you could be a little more intelligent with your attack and not completely brute force it, by using something we computer scientists call divide and conquer.

Because what you are actually doing is just guessing a number you could just simply use a Binary Search. Which is pretty effective because it will take you a worst case of log_2(127) *2 guesses because you also need to inspect the mid point of every interval











Blind bit shift
h.ackers.net's method
Another method that I quite enjoyed reading about uses bit shifting to guess the number based on its binary value.

This method will guarantee a maximum of 8 probes per character in the information string. This is because every ASCII character is represented using 8 bits, and we can find out these 8 bits by using a clever step by step right ---or if you prefer a left shift of the binary value of the character. At each step shifting it by on position less than the previous step, this will either uncover a 1 or 0 after every shift. We can then easily predict what number we can expect since it will only differ by one bit. --- http://h.ackack.net/faster-blind-mysql-injection-using-bit-shifting.html

Masked bit shift
my variant, of their method

Now what the bit shift guessing method does is move a certain amount of numbers out (by shifting) leaving some behind, allowing you to guess whether a 1 or 0 has become a new member to the party. Using this I've added another operation, the XOR.

lets say the number we are trying to guess is : 01101101
????????
to be able to check out what the left most digit is, we can shift it to the right 7 times making the number,
0000000?
What we can do to guess that bit very simply is XOR it with 1:
0000000? ^ 00000001 
or in MySQL terms we would ask the question like this
(ascii(substring(info,1,1)) >> 7) ^1
---all we are doing is checking whether the new unknown bit is 1 or not!

this will either give us a TRUE or FALSE return to our query, knowing our number it will return a TRUE, meaning the two numbers are different and the new first bit is NOT a 1, thus it is a 0.
So far what we have for our mystery number is:
0???????
Performing this operation again, we then shift the number one less times, so we shift it 6 times to the right, leaving us with:
our known number is in green here
0000000
 we would then XOR our bit mask with the freshly shifted number:
our guessing bit is in blue
0000000? ^ 00000001  (we guess a 1 as the new bit)
This will return a 0 or a FALSE because the two numbers are the same, so then so far our mystery number is:
01??????
(ill do it once more)
We shift the mystery number 5 times, giving us: 00000001?
We then then update our mask, including the bits we know, and a 1 as the guessing bit, and then XOR'ing them:
0000001? ^ 00000011
which will return a FALSE since both numbers will be the same, we know then that the 1 we added as a guess is correct! Our number is then unravelled a little more:
011?????
you perform this over and over until you've done it 8 times, after the 8th time you will have unravelled the entire number!

Guessing the 'k' char

Why the addition of the XOR?
  • WAF's may filter out the '=' operator in the arguments to scripts, knowing that it is an integral part of blind injection
  • The XOR makes the method easier to understand, no need to constantly convert numbers in and out of binary to determine your next move
Possible improvements I'll be working on

The two pronged attack:
The Masked bit shifting method I developed only determines numbers from one end, the left. It may be possible to determine numbers from the right simultaneously. This is why
  • Masked bit shifting will always return either a one or a zero after every injection, 0 being a success and 1 being false
  • 1 and 0 returned are just numbers, and they can be added, i propose adding the two results, and XOR'ing them again with 0
    • Since if they are both successful guesses adding the two results together will again return a zero, and you will have guessed two numbers correctly at once!
    • I still hafto figure out what the algorithm must do when both results are not 0 lols, but I'm getting there!
It would probably look something like:
((ascii(substring(hash,1,1)) >> 7)^1 + (ascii(substring(hash,1,1)) << 7)^256 )^0 

I might not manage to combined them, but because of the limited set of chars that are in hashes (especially MySQL hashes) there are almost certainly ways to bound the amount of guessing necessary to determine a logical character. Or one could look at improving guessing of the whole hash using some top down method.

Anyway, thats it for now. Hope you enjoyed it!

Comments

  1. All you need to do really is write the 1s and 0s you get from the Masked bit shift, invert them and you'll have your char!!

    ReplyDelete

Post a Comment