[极客大挑战 2019]HardSQL updatexml报错注入小结
报错注入
链接:
https://www.cnblogs.com/richardlee97/p/10617115.html
报错原因:
其原因主要是因为虚拟表的主键重复。按照MySQL的官方说法,group by要进行两次运算,第一次是拿group by后面的字段值到虚拟表中去对比前,首先获取group by后面的值;第二次是假设group by后面的字段的值在虚拟表中不存在,那就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。
0|10x01 解题
简单测试一下:
发现union被直接过滤掉了,不能使用双写绕过等方式,不过我们可以使用报错注入进行注入可以使用extractvalue和updatexml进行报错注入
先贴上payload:
整个过程的注入语句:
看网上的wp他们出来也没看到有没有出。。
有一个思路是
substr过滤了不能
用另外一个骚操作{left(),right()}
进行拼接
playload
用left和right进行拼接就出来flag了
链接:
https://blog.csdn.net/SopRomeo/article/details/104041233/
extractvalue()
extractvalue() :对XML文档进行查询的函数
其实就是相当于我们熟悉的HTML文件中用 <div><p><a>标签查找元素一样
语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。
正常查询 第二个参数的位置格式 为 /xxx/xx/xx/xx ,即使查询不到也不会报错
select username from security.user where id=1 and (extractvalue(‘anything’,’/x/xx’))
使用concat()拼接 ‘ / ‘ 效果相同,
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘/’,(select database()))))
这里在’anything’中查询不到 位置是 /database()的内容,
但也没有语法错误,不会报错,下面故意写入语法错误:
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘~’,(select database()))))
可以看出,以~开头的内容不是xml格式的语法,报错,但是会显示无法识别的内容是什么,这样就达到了目的。
有一点需要注意,extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位
这里查询前5位示意:
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘#’,substring(hex((select database())),1,5))))
updatexml()
updatexml()函数与extractvalue()类似,是更新xml文档的函数。
语法updatexml(目标xml文档,xml路径,更新的内容)
select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))
报错方式相同:
select username from security.user where id=1 and (updatexml(‘anything’,concat(‘~’,(select database())),’anything’))
同样是32位查询。
转载指明出处