28.10.2014 Views

SQL Injection Attacks and Defense - 2009

SQL Injection Attacks and Defense - 2009

SQL Injection Attacks and Defense - 2009

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Exploiting <strong>SQL</strong> <strong>Injection</strong> • Chapter 4 159<br />

Regarding Oracle, you can achieve the same effect (although less reliably) by generating<br />

an HTTP request to a “dead” Internet Protocol (IP) address, using UTL_HTTP or<br />

HTTPURITYPE. If you specify an IP address where no one is listening, the following<br />

queries will wait for the connection attempt to time out:<br />

select utl_http.request ('http://10.0.0.1/') from dual;<br />

select HTTPURITYPE( 'http://10.0.0.1/').getclob() from dual;<br />

An alternative to using the network timing approach is to use a simple Cartesian product.<br />

A count(∗) on four tables takes much more time than returning a number. The following<br />

query returns a number after counting all rows in a Cartesian product (which could become<br />

really big <strong>and</strong> time-intensive) if the first character of the username is A:<br />

SELECT decode(substr(user,1,1),'A',(select count(*) from<br />

all_objects,all_objects,all_objects,all_objects),0)<br />

Easy, isn’t it? Well, keep reading, because things are going to get even more interesting.<br />

Approach 2: Error-based<br />

The time-based approach is extremely flexible, <strong>and</strong> it is guaranteed to work in very<br />

difficult scenarios because it uniquely relies on timing <strong>and</strong> not on the application output.<br />

For this reason, it is very useful in pure-blind scenarios, which we will analyze in depth in<br />

Chapter 5.<br />

However, it is not suited to extracting more than a few bits of information. Assuming<br />

that each bit has the same probability of being 1 or 0, <strong>and</strong> assuming that we used five<br />

seconds as the parameter to WAITFOR, each query would take an average of 2.5 seconds<br />

(plus any additional network delay) to return, making the process painstakingly slow. You could<br />

reduce the parameter passed to WAITFOR, but that would likely introduce errors. Luckily,<br />

we have in our bag other techniques that will trigger different responses depending on the<br />

value of the bit that we are looking for. Take a look at the following query:<br />

http://www.victim.com/products.asp?id=12/is_srvrolemember('sysadmin')<br />

is_srvrolemember( ) is an <strong>SQL</strong> Server T-<strong>SQL</strong> function that returns the following values:<br />

■■<br />

■■<br />

■■<br />

1 if the user is part of the specified group<br />

0 if it is not part of the group<br />

NULL if the specified group does not exist<br />

If our user belongs to the sysadmin group, the id parameter will be equal to 12/1, which<br />

is equal to 12, <strong>and</strong> the application will therefore return the old page describing the Syngress<br />

book. However, if the current user is not a member of sysadmin, the id parameter will have<br />

the value 12/0, which is obviously not a number. This will make the query fail, <strong>and</strong> the<br />

application will return an error. The exact error message can obviously vary a lot: It could be

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!