我们一直都知道updatexml等一众函数可以用来报错注入,但是究竟为什么他可以报错?又为什么可以帮助我们起到注入的效果呢?如果这是一道面试题,问你updatexml 报错注入的原理,你又知道多少呢?
updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
实际上是因为,他会把校验失败的数据
给回显出来,方便开发人员调试用的,但到了咱们这里,就变成了一个利器。我们只需要将第二个参数变成非XPATH格式的,就会引发报错,进而MYSQL会把错误信息回显出来,让我们看到我们的注入结果。
那我们来看看这个最最最常见的payload:
xxxxxxxxxx
updatexml(1,concat(0x7e,version()),1)
我想向你继续提出两个问题:为什么要0x7e又为什么有concat
如果说不上来,没事,我们继续往下看,毕竟文章就是为你答疑解惑的。
我们看这个payload,会发现一些好玩的事情,就是所有的payload,高低都在这个报错注入的payload中加入concat(符号,注入语句)
为什么需要concat?又为什么需要这个0x7e?
我们来做做实验:
会发现一个好玩的事情,那就是,没有这个0x7e(或者说特殊符号),注入的结果并不完全。
那这是什么引起的呢?
还记得我们最早说的那句话吗,为什么updatexml会把我们需要的信息爆出来,我们回顾一下:
实际上是因为,他会把
校验失败的数据
给回显出来,方便开发人员调试用的
没错!就是这句话中被标注的那几个字在捣鬼"校验失败的数据",例如在这个案例当中,当出现第二个.
的时候就会无情错误了,即校验失败的数据为.28
,看下图:
所以我们需要在第一位就让他报错,然后把报错信息和后面的结果联合起来,就类似于这样:
我提前加入两个.
,这样的话他后面的所有信息全部都是校验失败的信息。
那这个将引发校验失败符号
和有用信息
连接起来的函数是什么呢?就是我们的concat()
。
只不过在我们日常的payload当中使用的是0x7e
罢了。
似乎文章写到这就可以结束了。但事实真的如此吗?全部问题都解决了吗?当然不是。
我最近遇上的有关updatexml
的,还存在一个大问题,那就是updatexml回显字数限制问题。
我们来看,现在我们想要查询出的数据是一个三十二位的数据:
我们来查询一下:
肉眼可见的少了一位E
这是怎么回事呢?按前面所说的,丢失信息的问题早被我们一个0x7e
再加上一个concat
给干掉了啊
这是因为updatexml
这个函数自身最多就能回显32位,因为0x7e
占了一位,所以无法回显完全。
那有没有什么方法呢?当然有,我们可以借助截取字符串的函数substring(要截取的字符串,起始位(从第一位开始),结束位)
来做到
其实写本文最开始是因为之前从公众号上看到了一个面试题,里面问到了updatexml
报错注入的原理。当时我就一愣,用的多,但是原理什么的还真是不清楚。于是,我就从最简单最常见的payload updatexml(1,concat(0x7e,version()),1)
分析,讲述了报错注入的原理。