Wednesday, October 19, 2011

Time delay SQL injections


 The following excerpt, courtesy of Wiley Publishing, is from Chapter 22 of the book "The Database Hacker's Handbook: Defending Database Servers" written by David Litchfield, Chris Anley, John Heasman and Bill Grindlay. Click for the complete book excerpt series or purchase the book.




Time delays
The previous examples of SQL injection techniques assumed that the client can view the error messages returned by the backend database server; however, often the Web server is set up so that error messages are not returned. In this case an attacker may suspect that the Web application is vulnerable to SQL injection but be unable to view any useful information because of its configuration. A method used here to extract the data is known as time delay SQL injection, and works on the basis that true or false queries can be answered by the amount of time a request takes to complete. The statement waitfor used with the delay argument causes

SQL Server to pause for the specified period of time:
 
waitfor delay '0:0:5'

This will pause the query for five seconds.

This feature can be leveraged to reveal information, such as whether the Web application's connection to the database is made as a system administrator:
 
if (is_srvrolemember('sysadmin') > 0) waitfor delay '0:0:5'

This will cause the query to pause if true, or return immediately if false. At the very lowest level, all data stored in the database is just a binary series of ones and zeros. This means that any data in the database can be extracted using a sequence of true/false questions. For example, the query
 
if (ascii(substring(@string, @byte, 1)) & (power(2, @bit))) > 0 waitfor
delay '0:0:5'
 
will trigger a delay only if the bit (@bit) of byte (@byte) in the string (@string) is set to 1. To retrieve the current database name from the server, execute

declare @string varchar(8192) select @string = db_name() if
(ascii(substring(@string, 1, 1)) & (power(2, 0))) > 0 waitfor delay
'0:0:5'
This will delay if the first bit of the first byte of the current  database name is set to 1. The second bit of the first byte can then be  queried:

declare @string varchar(8192) select @string = db_name() if
(ascii(substring(@string, 1, 1)) & (power(2, 1))) > 0 waitfor delay
'0:0:5'

and so on, building up the entire string. Obviously using this method, this would be a time-consuming process, mainly because of the five-second delay per set bit. It is not necessary, however, to run these queries sequentially or in any particular order. A small program, known as a harness, can be used to form the URLs to request with the necessary injected SQL to build the required string. Multiple requests can then be made to the server in multiple threads, and the harness program can then wait for the requests to return and build the string as they do.

No comments:

Post a Comment