Efficient but slow blind sql injection data extraction

So here is a quick midnight thought to retrieve data when facing a blind sql injection. It’s nothing ground breaking on the horizon I just wanted the technique to get some more attention, since I don’t see it used that often. I’m using MySQL as an example, but this can be used on any database which has somewhat of a reliable way to force it to do time related actions. The downside is that it’s pretty unstable if your connection to the target is not reliable and it’s a slow method like all time based methods. The upside however is that you only need one request for one character instead of eight requests and it can be further improved. If you are a whitehat then the amount of requests usually aren’t that important, if you are a blackhat you might prefer a small footprint in the logs.


sleep(ascii(substr(user(),1,1)))

The above is the quick and dirty way. You can probably guess it we use sleep() as the transport medium for the character value. The only reference I found to this technique is in this paper [PDF] on page 4. Maybe I haven’t searched long enough and there are better papers out there exploring this method of data extraction.

You do want to speed the above up, since the character ‘r’ (if we assume ‘root’ as an example username) gives you a waiting time of 114 seconds (1min 54sec). The easiest way is to just substract a constant from it and add the constant up when you have retrieved the value. You can use the following ascii chart to see what a save constant values could be. An example could be:


sleep(ascii(substr(user(),1,1))-32)

We can further improve this however by involving the human factor. As often said humans are the weakest links in the security field, yet they are the strongest link when it comes down to thinking (artificial intelligence is still trying to catch up). For example the following text has circulated a REALLY long time on the internet (original):

Aoccdrnig to a rscheearch at Cmabrigde Uinervtisy, it deosn’t mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe.

So…this actually means that to be able to extract data we don’t really need all the data do we? YES there are exceptions to the rule like hashes and the like. So all we need is to get the first and last letter and then just get random letters in between. You can use letter frequency analysis to make sure your request for a letter has a high probability of being in there, for example using the following wikipedia page:

http://en.wikipedia.org/wiki/Letter_frequency

So after getting the first and last letter of the data you are after, you can use the following query to get the intermediate letters:


sleep(instr(user(),"o"))

If that’s too fast because of the positions being returned are in the range of 0-10, you can always add a constant or wrap it with ascii(). I won’t be coding a tool or POC for this, since I think this is just a technique that should be included in already available tools like sqlmap, sqlninja and the like.

Hope someone finds this useful.