SQL注入(5):extractValue、updateXml报错注入
报错注入
首先报错注入需要一个基础
报错注入就是:
构造语句,让错误信息中夹杂可以显示数据库内容的查询语句。
该注入方式常见于没有回显结果的,但是注入点输错结果会报错的的情况。例如Less-5
但是我们通过这个报错又可以获取到数据库库名叫security
。通过这个逻辑注入的方式就被称之为报错注入。
报错注入分为12种
常见的报错注入为前三种:
- floor()报错注入
- extractValue()报错注入
- updataXml()报错注入
其中第二和第三种原理基本一致,只是函数的内容不太一样。
extractValue()报错注入
extractValue()函数
函数extractValue()包含两个参数
- 第一个参数为XML文档对象名称
- 第二个参数为路径
该函数用于查询数据库内XML文档对象的内容。而updateXml()则是用于更新XML文档内容。
使用例:
创建表的命令的含义是,在创建一个xml表,表内有一列名字叫doc
,为varchar类型,长度150。
现在我们想查询作者是谁,我们可以用extractValue()进行查询
1 | select extractvalue(doc, '/book/author/surname') from xml; |
报错信息
单纯的写错路径或者对象的名称,是不会返回任何报错信息的
而把查询参数的格式符号写错,才会显示出报错信息
而我们发现,此查询在报错信息这里可以把我们的信息回显回来。因此我们可以寻找一个机会,在报错之前,执行我们的查询语句,并且将报错信息回显回来。
利用concat()
拼接的效果,我们将会引起报错的字符~
(0x7e)和我们要执行的语句拼接在一起,从而使得引起报错,且得到查询结果
1 | select extractvalue(1, concat(0x7e,(select database()))) from xml; |
这样我们就查询到我们所需的信息。
靶机实例
对于我们的靶机实例less-5,我们使用上面的方法进行注入。
构造注入语句
1 | http://127.0.0.1:8081/Less-5/?id=1' union select 1,2,extractvalue(1, concat(0x7e,(select database())))--+ |
我们成功利用报错信息查询出当前页面数据库的名字。实际上后面不使用union也是可以的,只要是能够执行语句的方法都是可以的,例如
1 | http://127.0.0.1:8081/Less-5/?id=1' and 1=extractvalue(1, concat(0x7e,(select database())))--+ |
接下来查询表名列名仅需要替换掉select database()
的内容即可,与前面的过程差异不大。不再作出演示。
**值得注意的是:**报错信息一次只能返回32个字符,因此我们可以用到substring()
函数解决这个问问题。substring()函数包含三个参数
- 第一个参数是要控制输出的字符串,也就是我们的返回值
- 第二个参数是从哪个字符开始显示
- 第三个参数是一次性显示多少个字符
因此我们用这个函数每次显示指定数量的字符,这样就不会触及到报错信息的上限了。
updateXml()报错注入
updateXml()报错注入的逻辑与extractValue()报错注入的逻辑类似。
updataXml()函数
该函数具有三个参数
- 第一个参数是XML文档对象的名称
- 第二个参数是路径
- 第三个参数是要替换成的新字符串
报错信息
与extractValue()触发报错信息的方式类似,都是通过错误的路径触发错误信息。
1 | select updateXml(1, concat(0x7e,(select database())), 1) from xml; |
具体注入过程参考上面已经写过的注入即可,不再重复展示。