Jump to content
Nytro

Optimized Blind MySQL Injection Data Retrieval

Recommended Posts

Posted

Optimized Blind MySQL Injection Data Retrieval

Posted on March 31, 2011 by Roberto Salgado

I recently came across a paper titled Faster Blind MySQL Injection Using Bit Shifting by Jelmer de Hen describing a technique that allows the retrieval of data from a MySQL database in only 8 requests per character using bit shifting; this is a slight improvement from the traditional Bisection method. This got me thinking on how information could be extracted from the database in even less amount of requests and after a few hours of fooling around, this is what I came up with.

AND (SELECT @a:=MID(BIN(FIND_IN_SET(MID(table_name,1,1), 'a,b,c,d,e,f

,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,_,!,@,#,

$,%,^,&,*,(,),-,+,=,\,,.,",\',~,`,\\,|,{,},[,],:,;, ,')),1,1) FROM in

formation_schema.tables LIMIT 1)=@a AND IF(@a!='',@a,SLEEP(5));

A quick explanation of how this query works and what it does:

It starts off with your basic blind injection, selecting only 1 character at a time from the table

SELECT MID(table_name,1,1) FROM information_schema.tables LIMIT 1

It then uses FIND_IN_SET(), to look for the position of the extracted character in the list. So for example, say the table is CHARACTER_SET, MID("CHARACTER_SET",1,1) = 'C', therefore the returned value for FIND_IN_SET('C', 'a,b,c') would be 3 (case insensitive). We then proceed to use BIN() to convert it to binary, BIN(3) = 11. Now that we've reduced the character to two possibilities, 1 or 0, we only have to check if the result is 1, if not we can assume it's 0. So BIN(3) = 11 would take 3 requests: Is the first digit 1? Yes. Is the second digit 1? Yes. Is the third digit 1? No, there is no third digit, so it triggers the SLEEP() function.

mysql_extraction.en.png

Now we know that CAST(b'11' AS DEC) is 3 and that's the equivalent of 'c' on the list, all in 3 requests! Say your list contained 45 elements, BIN(45) = 101101, still only making the total amount of requests 7 for characters in later position on the list. I'm sure this could be optimized and greatly improved, possibly by removing the need for FIND_IN_SET() and using a more effective function. One idea would be to split the list in two requests, this way you can ensure the length of the binary doesn't grow too big.

mysql_extraction.graph.png

Downside:

Query can be a bit longer than normal.

Requires SLEEP() to know when you've reached the end of the binary.

Another possible solution that doesn't require SLEEP(), but would require two different pages (test.php?id=0, test.php?id=1) could be done with something like this:

IF((@a:=MID(BIN(FIND_IN_SET(MID((SELECT table_name FROM info
rmation_schema.tables LIMIT 1),1,1),'a,b,c,d,e,f,g,h,i,j,k,l,
m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,_,!,@,#,$,%,^,&,
*,(,),-,+,=,\,,.,",\',~,`,\\,|,{,},[,],:,;, ')),1,1))!='',@a,0/0);

UPDATE:

Two things I just thought I should point out: This technique doesn't necessarily require FIND_IN_SET(). There are plenty of other similar functions that could be substituted in its place (locate, position, instr, field) just to name a few. Secondly, the use of quotations can be avoided. For example, FIND_IN_SET(0x33, CONCAT_WS(0x2C,0x31,0x32,0x33));

Sursa: Optimized Blind MySQL Injection Data Retrieval

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...