0

Efficient Time Based Blind SQL Injection using MySQL Bit Functions and Operators

 

I was performing some penetration tests in 2011 – 2012 against various PHP applications integrated with MySQL databases which were vulnerable to Time Based Blind SQL Injection.  Due to various constraints and limitations, exploitation was a little tricky and I was forced to investigate a method which allowed me to retrieve data with as little requests as possible.

I stumbled across this paper demonstrating SQL injection using Bit shifting techniques: https://www.exploit-db.com/papers/17073/

During a recent CTF exercise on Hack the Box (https://www.hackthebox.eu/) I found myself revisiting this method to exploit some tricky SQL injection.

This blog post will demonstrate how the ‘right shift’ Operator ( >> ) can be used to enumerate the Binary bits of a value returned from a SQL query.

Note: A full description of Bit Functions and Operators can be found at the following URL: https://dev.mysql.com/doc/refman/5.7/en/bit-functions.html

 

The right shift operator will shift the number of bits of a binary value 1 location to the right, as illustrated in the example below:

 

This can be utilised to enumerate a character of a string when exploiting Blind SQL injection.  This guarantees that the data can be enumerated by a maximum of 8 requests per character if it appears within the full ASCII table.

The data we wish to extract via this method is the first character returned for the query: select user()

First Bit:

We start by finding the value of the first bit:

????????

Two possibilities for this:

0 (Decimal value: 0) // TRUE condition

OR

1 (Decimal value: 1) // FALSE condition

 

The SQL query resulted in a time delay, therefore the condition is TRUE, resulting in the first bit being 0

0???????


Second Bit:

Now we need find the value of the second bit. As before, there are two possibilities for this:

00 (Decimal value: 0) // TRUE condition

OR

01 (Decimal value: 1) // FALSE condition

 

 

The SQL query resulted in no time delay, therefore the condition is FALSE, resulting in the second bit being 1

01?????

 

Third Bit:

Now we need find the value of the third bit. As before, there are two possibilities for this:

010 (Decimal value: 2) // TRUE

OR

011 (Decimal value: 3) // FALSE

 

The SQL query resulted in no time delay, therefore the condition is FALSE, resulting in the third bit being 1

011?????


 

Fourth Bit:

Now we need find the value of the fourth bit. As before, there are two possibilities for this:

0110 (Decimal: 6) // TRUE

OR

0111 (Decimal: 7) // FALSE

 

 

The SQL query resulted in no time delay, therefore the condition is FALSE, resulting in the fourth bit being 1

0111????

 

Fifth Bit:

Now we need find the value of the fifth bit. As before, there are two possibilities for this:

01110 (Decimal: 14) /// TRUE

OR

01111 (Decimal: 15) // FALSE

 

The SQL query resulted in a time delay, therefore the condition is TRUE, resulting in the fifth bit being 0

01110???

 

Sixth Bit:

Now we need find the value of the sixth bit. As before, there are two possibilities for this:

011100 (Decimal: 28) // TRUE

OR

011101 (Decimal: 29) // FALSE

 

 

The SQL query resulted in a time delay, therefore the condition is TRUE, resulting in the sixth bit being 0

011100??

 

Seventh Bit:

Now we need find the value of the seventh bit. As before, there are two possibilities for this:

0111000 (Decimal: 56) // TRUE

OR

0111001 (Decimal: 57) // FALSE

 

The SQL query resulted in no time delay, therefore the condition is FALSE, resulting in the seventh bit being 1

The fourth bit must be 1

0111001?

 

 

Eighth Bit:

Now we need find the value of the eighth and final bit. As before, there are two possibilities for this:

01110010 (Decimal: 114) // TRUE

OR

01110011 (Decimal: 115) // FALSE

 

The SQL query resulted in a time delay, therefore the condition is TRUE, resulting in the eight bit being 0

01110010

 

Now we can conclude that the binary value for the first character returned by the query: select user() is 01110010 resulting in a decimal value of 114.  114 being the ‘r’ character of the ASCII table.

 

 

In order to demonstrate this type of Blind SQL injection attack, I have demenstrated how to enumerate the first and last binary bit of the first character returned by ‘select user()’ on the bWAPP vulnerable application: (https://www.vulnhub.com/entry/bwapp-bee-box-v16,53/)

 

  1. SQLi string returning a TRUE condition for the first bit:
 

 

  1. SQLi string returning a FALSE condition for the first bit:
 

 

  1. SQLi string returning a TRUE condition for the eight bit:
 

Kai Stimpson

Proud Parent, Senior Security Consultant, Weightlifter and Gardener.

Leave a Reply