在mysql⾼版本(⼤于5.1版本(5.1.5))中添加了对XML⽂档进⾏查询和修改的函数:
利⽤前提:页⾯上没有显⽰位,但是需要输出 SQL语句 执⾏错误信息。⽐如
mysql_error()
优点:不需要显⽰位
缺点:需要输出mysql_error()的报错信息
⼀、报错注⼊的定义
报错注⼊就是利⽤了数据库的某些机制,⼈为地制造错误条件,使得查询结果能够出现
在错误信息中。
⼆、利⽤报错注⼊的前提
1.页⾯上没有显⽰位,但是必须有SQL语句执⾏错误的信息
三、报错注⼊的优缺点
1.优点:不需要显⽰位,如果有显⽰位建议使⽤union联合查询。
2.缺点:需要有SQL语句的报错信息。
四、构造报错注⼊的基本步骤
1.构造⽬标查询语句
2.选择报错注⼊函数
3.构造报错注⼊语句
4.拼接报错注⼊语句
五、常见的报错注⼊函数
1.updatexml();
2.extractvalue();
3.floor();
4.geometrycollection();
5.multipoint();
6.polygon();
7.multipolygon();
8.linestring();
9.multilinestring();
10.exp();
六、报错函数
SQL注⼊之updatexml()函数报错注⼊
updatexml()函数是MYSQL对XML⽂档数据进⾏查询和修改的XPATH函数。
语法:UPDATEXML (xml_document, XPathstring, new_value)。
第⼀个参数:xml_document,⽂档名称。
第⼆个参数:XPathstring (Xpath格式的字符串),做内容定位。
第三个参数:new_value,String格式,替换查找到的符合条件的值。
注意:⼀次返回值最⼤为32位,当数据库名⼤于32,需要结合其他⽅式使⽤(可以使⽤substr());
UpdateXML(xml_target, xpath_expr, new_xml)
xml_target:: 需要操作的xml⽚段
xpath_expr: 需要更新的xml路径(Xpath格式)
new_xml: 更新后的内容 此函数⽤来更新选定XML⽚段的内容,将XML标记的给定⽚
段的单个部分替换为 xml_target 新的XML⽚段 new_xml ,然后返回更改的XML。
xml_target替换的部分 与xpath_expr ⽤户提供的XPath表达式匹配。 如果未xpath_expr找
到表达式匹配 ,或者找到多个匹配项,则该函数返回原始 xml_targetXML⽚段。所有三
个参数都应该是字符串。使⽤⽅式如下:
/表⽰指定路径下的所有符合条件的节点,//表⽰指定路径下匹配模式的所有节点。这样
说很难区分,举例:
(1) ./parameter:表⽰本节点下(不包括⼦节点)下所有的parameter节点集
(2) .//parameter: 表⽰本节点及其所有⼦节点下的parameter节点集(包括⼦节点、孙节
点、⼦⼦孙孙都包括)
这⾥和上⾯的extractvalue函数⼀样,当Xpath路径语法错误时,就会报错,报错内容含有
错误的路径内容:
例如: SELECT ExtractValue('', '/a/b'); 就是寻找前⼀段xml⽂
档内容中的a节点下的b节点,这⾥如果Xpath格式语法书写错误的话,就会报错。这⾥
就是利⽤这个特性来获得我们想要知道的内容。
能够使⽤union注⼊的地⽅就可以使⽤报错注⼊
SQL注⼊之extractvalue()函数报错注⼊
名称 描述
ExtractValue() 使⽤XPath表⽰法从XML字符串中提取值
UpdateXML() 返回替换的XML⽚段
通过这两个函数可以完成报错注⼊
⼀、extractvalue函数
语法:extractvalue(⽬标xml 文档,xml路径)
ExtractValue(xml_frag, xpath_expr) ExtractValue() 接受两个字符串参数,
⼀个XML标记⽚段 xml_frag和⼀个XPath表达式 xpath_expr(也称为 定位器); 它返回
CDATA 第⼀个⽂本节点的text(),该节点是XPath表达式匹配的元素的⼦元素。
第⼀个参数可以传⼊⽬标xml⽂档,第⼆个参数是⽤Xpath路径法表⽰的查找路径
例如: SELECT ExtractValue('', '/a/b'); 就是寻找前⼀段xml⽂
档内容中的a节点下的b节点,这⾥如果Xpath格式语法书写错误的话,就会报错。这⾥
就是利⽤这个特性来获得我们想要知道的内容。
报错原理,同extractValue,构造错误的Xpath,以达到报错注⼊
payload: updatexml(1,concat(0x23,payload,0x23),1)
默认只能返回32字符串
Forexample: Lesson1
判断数据类型
构造Payload and 1=1
构造Payload and 1=2
Payload and ‘1’=‘1
Payload and ‘1’=‘2
特意写错字母发现报错
默认只能返回32字符串
使⽤函数substring()函数解决只能返回32个字符串的问题(功能和substr函数⼀样)
substring((字符串),从第⼏个字符开始,⼀次输出⼏个)因为有32的局限所以每次开始的字
符都要不⼀样才能拼成完整的答案
concat_ws 实现
mid函数截取
SQL注⼊之floor()函数报错注⼊
原理
通过使⽤ count() 、 floor() 、 rand() 、 group by 四个条件形成主键重复的错误
count() :计算满⾜某⼀条件下的⾏数
floor() :向下取整的函数
rand() :⽣成0~1之间的浮点数
count() :group by:针对表中的字段来分组
⼀、count()函数、group by
在分组的情况下记录并输⼊每个分组的数量,不过在记录的过程中会先⽣成⼀个虚拟
表,然后往虚拟表中插⼊数据
⼆、floor()函数
向下取整
三、rand()函数
如果配合上floor()函数结果就⽐较明确了
这⾥我乘2的⽬的是⽣成0~2之间的浮点数(不包括2),然后经过floor()函数,最后得到结
果要么是0,要么是1
可以看出,结果是:0 1 1 0 1 1 0 0 1
四、报错初体验
这条语句⽆论执⾏多少次都会报出这条错误,且内容不会改变
这⾥在floor()函数后⾯的x起到了⼀个起别名的作⽤,换句话说,x就等价于
floor(rand()*2),前⾯有说到count()函数会⽣成⼀个虚拟表,就我这条SQL语句来说,虚
拟表中会有两个字段,⼀个是字段是count()的结果,⼀个是字段存放x
五、报错注⼊
1、获取当前数据库
2、获取当前数据库中表
使⽤floor()函数获取当前数据库名 接下来将database()替换为查询语句即可
改变limit 0,1参数依次获取所有表名
报错注⼊FUZZ(报错注⼊检测)
select 1/0
select 1 from (select count(*),concat(version(),floor(rand(0)*2))x
from information_schema.tables group by x)a
extractvalue(1, concat(0x5c,(select user())))
updatexml(0x3a,concat(1,(select user())),1)
每个⼀个报错语句都有它的原理:
exp() 报错的原理:exp 是⼀个数学函数,取e的x次⽅,当我们输⼊的值⼤于709就会报
错,然后 ~ 取反它的值总会⼤于709,所以报错。
updatexml() 报错的原理:由于 updatexml 的第⼆个参数需要 Xpath 格式的字符串,以 ~
开头的内容不是 xml 格式的语法,concat() 函数为字符串连接函数显然不符合规则,但
是会将括号内的执⾏结果以错误的形式报出,这样就可以实现报错注⼊了。