1. 项目概述当SQL注入遇上WAF这道墙在Web安全测试或渗透测试的日常工作中我们常常会遇到一个令人头疼的“守门员”——Web应用防火墙也就是大家常说的WAF。它的职责就是识别并拦截那些恶意的、不怀好意的请求比如我们最熟悉的SQL注入攻击。但安全攻防从来不是一堵墙就能终结的游戏而是一场持续不断的“猫鼠游戏”。当你的一个精心构造的注入语句被WAF无情地拦截返回一个刺眼的“403 Forbidden”或者“Blocked by WAF”时那种感觉就像被一盆冷水从头浇到脚。今天要聊的就是这场游戏中的“鼠”方技巧SQL注入的WAF绕过方法。这绝不是鼓励大家去做坏事恰恰相反对于安全从业者、开发者甚至是运维人员来说理解攻击者是如何思考、如何绕过防御的是构建更坚固防线的前提。只有知道矛有多锋利才能打造出更坚固的盾。无论是进行授权渗透测试、代码审计还是单纯想深入理解WAF的工作原理掌握一些常见的绕过技巧都至关重要。这篇文章我们就从一个实战者的角度拆解那些让WAF“失明”的经典与新兴技巧并分享在实际操作中积累下来的心得与避坑指南。2. WAF工作原理与SQL注入检测逻辑拆解要绕过它必须先理解它。WAF不是魔法它是一套基于规则有时也结合机器学习的过滤系统。我们可以把它想象成一个站在应用程序前面的、眼神犀利的安检员。这个安检员手里拿着一本厚厚的《可疑行为特征手册》对每一个进来的HTTP请求包括URL参数、Headers、Body进行逐项检查。2.1 WAF的常规检测手段WAF的检测逻辑通常分为几个层次理解这些层次就等于拿到了绕过地图的钥匙。1. 基于正则表达式的模式匹配这是最基础、也最广泛使用的手段。WAF内置了大量正则表达式规则用于匹配已知的攻击模式。比如看到union select、or 11、sleep(、information_schema这些关键字组合警报就会立刻拉响。这些规则库往往来源于公开的漏洞库如OWASP ModSecurity核心规则集和厂商自身的积累。2. 语法/词法分析更高级的WAF会尝试解析输入判断其是否符合合法的SQL语法结构或者是否在看似正常的语法中嵌入了恶意片段。例如它会检查括号是否匹配、字符串引号是否闭合试图识别出超出正常业务逻辑的查询结构。3. 统计学分析与异常检测这类WAF会建立请求的“正常行为基线”。比如一个登录接口正常的用户名参数长度可能在20个字符以内。如果你突然提交了一个长达5000个字符、包含各种特殊符号的用户名即使没有匹配到具体的攻击规则也会因为严重偏离基线而被判定为异常并拦截。4. 语义分析这是目前比较前沿的方向。WAF会尝试理解参数的“意图”。例如在一个商品ID的参数位置输入应该是数字如果你输入了包含SQL关键字的文本即使被编码或分割系统也可能通过上下文分析出其恶意意图。2.2 WAF的软肋与绕过思路起源没有完美的防御。WAF的软肋往往源于其设计目标与真实世界复杂性的矛盾性能与安全的平衡WAF必须快速处理海量请求因此深度分析如完整的SQL语法树解析往往成本高昂多数时候依赖于快速但可能粗糙的规则匹配。误报的容忍度过于严格的规则会导致大量正常业务请求被误拦误报这是业务方无法接受的。因此规则通常会在安全性和可用性之间妥协。规则更新滞后性新的攻击手法层出不穷规则库的更新总有延迟。对应用程序上下文的理解有限WAF站在应用之外它很难百分百理解每一个参数在具体业务代码中的真实用途和处理逻辑。基于这些软肋我们的绕过思路也就清晰了想方设法让你的恶意负载在WAF看来是“正常”或“无法识别”的同时又能被后端的数据库成功解析并执行。核心就是制造“差异”WAF解析的结果 vs. 数据库引擎解析的结果。3. 经典字符绕过技巧实战解析让我们从最基础、也最有效的字符层面技巧开始。这些方法主要利用的是WAF规则编写不够严谨或对数据标准化处理不一致的漏洞。3.1 大小写变奏曲这是最简单的一招。很多基于简单正则匹配的WAF其规则可能是大小写敏感的。例如规则可能只匹配union select但对UnIoN SeLeCt或UNION SELECT视而不见。?id1‘ UnIoN SeLeCt 1,2,3--实操心得在手工测试时可以准备一个大小写混合的常用关键字字典进行模糊测试。但要注意现代成熟的WAF如Cloudflare、AWS WAF大多已经做了大小写归一化处理这一招可能失效但它永远是值得尝试的第一步成本极低。3.2 双写与冗余字符干扰在关键字中间插入一些WAF可能忽略但数据库SQL引擎会自动忽略的字符。最常见的是注释符/**/MySQL中。?id1‘ uni/**/on sel/**/ect 1,2,3 from users--WAF的规则可能直接匹配连续的union select但被/**/隔开后匹配失败。而MySQL数据库在执行SQL前会移除这些注释因此实际执行的语句依然是union select 1,2,3 from users。除了注释还可以使用其他会被数据库忽略的字符如在MySQL中某些版本的某些场景下%0a换行符、%0d回车符、%09制表符也可能被利用。?id1‘ uni%0aon%0dselect 1,2,3--注意事项这种方法高度依赖于具体的WAF实现和数据库类型。需要针对目标环境进行测试。/**/在MySQL中通用性较好但在其他数据库如SQL Server的/**/可能不被支持中需调整。3.3 编码与多重编码的艺术这是绕过中高级WAF的利器。其核心思想是WAF可能只对输入进行一层解码检查而应用程序或数据库可能会进行多层解码。URL编码将关键字符进行URL编码百分号编码。?id1‘ union%20select%201,2,3--这里的%20是空格。如果WAF直接匹配“union select”中的空格而忽略了解码则可能绕过。双重URL编码更保险的做法是进行两次编码。空格-%20-%2520。?id1‘ union%2520select%25201,2,3--假设WAF只做一次URL解码它看到的是union%20select依然包含%20可能不认为这是关键字。但应用服务器如Apache/Nginx或后端代码通常会进行完整的URL解码最终数据库收到的还是union select。十六进制编码将整个或部分关键字转换为十六进制表示。这在绕过对特定字符串的过滤时非常有效。?id1‘ and 1(select 1 from users where user0x61646d696e)--这里0x61646d696e是字符串admin的十六进制。WAF规则可能匹配user‘admin‘但很难去匹配所有可能的十六进制串。Unicode编码/HTML实体编码在Web上下文中有奇效。例如单引号‘可以编码为#x27;或#39;。如果WAF没有规范化这些实体而后端代码在渲染或处理时又将其解码就会产生漏洞。?id1#x27; union select 1,2,3--核心技巧编码绕过的关键在于找到WAF解码层和应用程序解码层之间的“断层”。你需要通过测试判断WAF在哪个环节进行检查而 payload 又在哪个环节被还原。常用的测试方法是先提交一个无害的编码 payload如%41代表 ‘A‘观察返回结果中 ‘A‘ 是否正常显示以此判断解码流程。4. 语句结构与逻辑绕过进阶当字符层面的把戏被识破后我们就需要更深入地玩弄SQL语句本身的逻辑和结构。4.1 内联注释的妙用MySQL特有的内联注释/*!...*/是一个宝藏。其中的代码只有在MySQL特定版本或更高版本下才会被执行。我们可以利用它来包裹整个恶意语句有时能起到混淆作用。?id1‘ /*!union*/ /*!select*/ 1,2,3--更高级的用法是利用/*!50000...*/这种版本号注释但我们的主要目的不是版本控制而是将其作为一个特殊的“标记符”可能干扰WAF的简单分词。4.2 等价函数与操作符替换不要死磕被拦截的关键字寻找它们的“替身”。or 11被拦截试试or 21、or 99100、or true在某些数据库、or ‘a‘‘a‘。and被拦截试试MySQL中。‘admin‘被拦截试试like ‘admin‘、in (‘admin‘)。substring()被拦截试试mid()、substr()、left()。sleep(5)被拦截试试benchmark(10000000, md5(‘test‘))通过执行大量计算来制造延迟。union select被拦截是否可以尝试基于错误的注入或时间盲注完全避开union实战案例在一次测试中information_schema.tables被严格过滤。我们转而使用mysql.innodb_table_statsMySQL特定来获取表名信息成功绕过了基于常见表名的过滤规则。4.3 分块传输编码Chunked Transfer Encoding干扰这是一种协议层的绕过技巧主要针对那些依赖于解析完整HTTP请求体的WAF。通过将请求体分块发送可以扰乱WAF的解析器使其无法正确识别出完整的恶意参数。通常你需要借助工具来构造这种请求比如Burp Suite的 “Chunked Transfer Encoding” 插件。原理是将union select这样的关键词拆散到不同的传输块中WAF可能因为看不到完整的连续数据流而放行但后端Web服务器会正确重组这些块形成完整的攻击语句。注意事项这种方法对WAF的实现要求较高且不一定所有服务器都支持或启用分块传输。它更偏向于一种“奇技淫巧”在常规方法无效时可以尝试。4.4 参数污染与参数拆分利用应用程序处理多个同名参数的逻辑差异。有些WAF只检查第一个或最后一个参数而应用程序可能以不同方式拼接它们。?id1id2‘ union select 1,2,3--或者将 payload 拆分到不同的参数中后端代码错误地将其拼接。?field‘ union selfield2ect 1,2,3--这需要你对目标应用的参数处理逻辑有猜测或了解通过模糊测试来发现。5. 基于时间与布尔盲注的绕过策略当直接的错误回显和联合查询都被封死时盲注就成了唯一的出路。而针对盲注的WAF规则往往侧重于检测明显的延迟函数如sleep,benchmark和布尔判断模式。5.1 时间盲注的隐蔽延迟sleep(5)太明显了我们可以制造更“自然”的延迟。重型查询延迟执行一个查询巨大表或复杂连接的语句来消耗时间。‘ and (select count(*) from information_schema.columns A, information_schema.columns B, information_schema.columns C) 1 and ‘1‘‘1这种笛卡尔积查询在数据量大时会显著耗时。网络延迟诱导在某些情况下可以利用like ‘%a%‘对长文本字段进行模糊查询或者使用regexp进行复杂的正则匹配来消耗数据库CPU时间间接产生延迟。但这需要目标字段存在且数据量足够大。绕过sleep检测的技巧如果将sleep编码成分散的形式如sl/**/eep(5)或者将其放在一个复杂的表达式里有时可以绕过简单的正则匹配。但更高级的WAF会进行语法分析识别出函数调用结构。5.2 布尔盲注的隐式判断避免使用and 11和and 12这种经典模式。可以改用更隐晦的比较。使用位运算‘ and ascii(substr(database(),1,1))164--。将比较转化为移位运算可能绕过对等号和比较符、的简单检测。使用in或between ... and ...‘ and substr(database(),1,1) in (‘a‘,‘b‘,‘c‘)--。利用数学函数‘ and pow(2, ascii(substr(database(),1,1))-96) 0--。构造一个依赖于目标字符的数学表达式。核心思路是让你的布尔判断看起来不像一个典型的盲注判断逻辑更像一个复杂的业务查询条件。6. 工具使用技巧与手工结合sqlmap 是自动化注入的神器但它默认的 payload 很容易被WAF识别。高手都是将手工技巧与工具结合。6.1 定制化sqlmap Tamper脚本sqlmap 的--tamper参数是其灵魂所在。Tamper脚本用于在发送 payload 前对其进行混淆、编码等操作。常用内置Tamperspace2comment.py: 用/**/替换空格。between.py: 用between ... and ...替换大于号和小于号。charencode.py: 对 payload 进行URL编码。randomcase.py: 随机大小写。equaltolike.py: 用like替换。apostrophemask.py: 用UTF-8全角字符伪装单引号。组合使用可以同时使用多个tamper形成组合拳。sqlmap -u “http://target.com/page?id1“ --tamperspace2comment,randomcase,charencode --level3 --risk2自定义Tamper当内置脚本无效时需要根据目标WAF的行为编写自己的Tamper脚本。例如你可以写一个脚本将union select转换成uni%0aon%0dsel%09ect。这需要你具备基本的Python编程能力并理解sqlmap的Tamper接口。6.2 低慢速攻击模式有些WAF针对单个请求进行检测很强但对长时间、低频率的请求流缺乏关联分析能力。sqlmap 的--delay和--time-sec参数可以用于调节请求速度模拟正常用户行为避免触发基于请求速率的异常检测。sqlmap -u “http://target.com/page?id1“ --delay2 --time-sec5这会让sqlmap在每个请求间等待2秒并将时间盲注的延迟基准设为5秒使得攻击流量更“平滑”。6.3 代理与流量分发如果目标IP因为大量攻击请求被临时封禁可以考虑使用--proxy或--proxy-file通过代理池发送请求分散流量来源。同时配合--random-agent随机化User-Agent让请求看起来更像来自不同的浏览器。7. 实战场景与综合绕过思路在实际环境中很少有一种方法能通吃。你需要像侦探一样收集信息逐步试探组合拳出击。7.1 信息收集与指纹识别WAF指纹识别使用工具如WAFW00F或手工方法判断目标使用的WAF类型Cloudflare, Akamai, ModSecurity, 长亭雷池等。不同WAF的规则强度和侧重点不同了解对手是第一步。错误信息分析故意触发一个错误如输入一个单引号观察返回的错误页面。有时错误信息会直接暴露后端数据库类型MySQL, PostgreSQL, SQL Server等甚至WAF的名称和版本。数据库类型直接决定了你可用的绕过函数和语法。参数可接受格式测试测试参数对数据类型、长度、特殊字符的容忍度。例如一个数字型参数是否接受引号是否接受科学计数法这能帮你判断注入点类型和可能的过滤强度。7.2 分层渐进测试法不要一上来就扔最复杂的 payload。建立一个系统的测试流程基础探测测试‘、“、\等字符看是否被过滤或转义是否有错误回显。简单绕过尝试使用大小写、内联注释/**/、简单编码如空格变或%20测试and 11这类简单逻辑。关键字拆分测试如果简单拦截尝试用uni/**/on sel/**/ect。编码测试尝试URL编码、双重URL编码、十六进制编码关键部分。等价替换测试如果union被拦尝试基于错误的注入‘ and updatexml(1,concat(0x7e,database()),1)--或者时间盲注‘ and if(11,sleep(5),0)--。协议/参数层测试在前端方法都无效时考虑分块传输、参数污染、HTTP方法转换GET变POST等。7.3 一个综合案例模拟假设目标URL为http://target.com/news.php?id123存在数字型注入但部署了某品牌WAF。第一步id123‘返回被WAF拦截页面。第二步id123 and 11被拦截。第三步id123 anandd 11双写绕过成功页面正常。说明WAF可能采用了简单的“查找-删除”过滤机制把and删除了留下了an d但数据库执行时是anandd- 删除中间的an后变成and。成功验证注入点。第四步id123 union select 1,2,3被拦截。第五步id123 uniunionon selselectect 1,2,3双写绕过联合查询可能成功。如果不成功尝试id123 uni/**/on sel/**/ect 1,2,3。第六步获取数据时information_schema被拦截。尝试使用mysql.innodb_table_stats或sys.schema_table_statistics等替代视图MySQL 5.6。第七步使用sqlmap自动化并编写自定义tamper将union select自动转换为uniunionon selselectect或加入随机注释。8. 防御视角与总结反思作为渗透测试者我们的目标是发现问题。而从防御者角度看这些绕过技巧揭示了WAF部署的常见误区依赖单一WAFWAF应该是纵深防御体系中的一环而非唯一屏障。必须结合安全的编码实践使用参数化查询/预编译语句、最小权限原则、输入输出验证等。规则设置过于宽松或僵化盲目使用默认规则集而不根据业务调整要么导致大量误报要么留下绕过空间。需要定期审查和更新规则并关注WAF的日志分析被拦截和绕过的案例。忽略应用层上下文最有效的防御在代码层面。开发人员应接受安全培训避免拼接SQL字符串。框架提供的ORM或安全查询接口应被强制使用。个人实操中的深刻体会是没有永远有效的绕过方法只有不断演进的攻防博弈。今天有效的技巧明天可能就被加入规则库。因此理解原理远比记忆payload重要。当你明白WAF是如何匹配union select的你自然能想到用uni%0aon%0dselect去尝试当你理解数据库解析SQL的过程你就能创造出各种“语法正确但看似怪异”的语句。在授权测试中我的习惯是每当成功绕过一次我都会问自己如果我是防守方该如何改进规则或代码来堵住这个缺口这种双向思考能让你的安全技能从“术”的层面提升到“道”的层面。最后请务必记住所有技术都应在法律和道德授权的范围内使用我们的终极目标是让网络空间更安全。
SQL注入WAF绕过实战:从字符编码到语句重构的攻防博弈
发布时间:2026/6/23 10:28:47
1. 项目概述当SQL注入遇上WAF这道墙在Web安全测试或渗透测试的日常工作中我们常常会遇到一个令人头疼的“守门员”——Web应用防火墙也就是大家常说的WAF。它的职责就是识别并拦截那些恶意的、不怀好意的请求比如我们最熟悉的SQL注入攻击。但安全攻防从来不是一堵墙就能终结的游戏而是一场持续不断的“猫鼠游戏”。当你的一个精心构造的注入语句被WAF无情地拦截返回一个刺眼的“403 Forbidden”或者“Blocked by WAF”时那种感觉就像被一盆冷水从头浇到脚。今天要聊的就是这场游戏中的“鼠”方技巧SQL注入的WAF绕过方法。这绝不是鼓励大家去做坏事恰恰相反对于安全从业者、开发者甚至是运维人员来说理解攻击者是如何思考、如何绕过防御的是构建更坚固防线的前提。只有知道矛有多锋利才能打造出更坚固的盾。无论是进行授权渗透测试、代码审计还是单纯想深入理解WAF的工作原理掌握一些常见的绕过技巧都至关重要。这篇文章我们就从一个实战者的角度拆解那些让WAF“失明”的经典与新兴技巧并分享在实际操作中积累下来的心得与避坑指南。2. WAF工作原理与SQL注入检测逻辑拆解要绕过它必须先理解它。WAF不是魔法它是一套基于规则有时也结合机器学习的过滤系统。我们可以把它想象成一个站在应用程序前面的、眼神犀利的安检员。这个安检员手里拿着一本厚厚的《可疑行为特征手册》对每一个进来的HTTP请求包括URL参数、Headers、Body进行逐项检查。2.1 WAF的常规检测手段WAF的检测逻辑通常分为几个层次理解这些层次就等于拿到了绕过地图的钥匙。1. 基于正则表达式的模式匹配这是最基础、也最广泛使用的手段。WAF内置了大量正则表达式规则用于匹配已知的攻击模式。比如看到union select、or 11、sleep(、information_schema这些关键字组合警报就会立刻拉响。这些规则库往往来源于公开的漏洞库如OWASP ModSecurity核心规则集和厂商自身的积累。2. 语法/词法分析更高级的WAF会尝试解析输入判断其是否符合合法的SQL语法结构或者是否在看似正常的语法中嵌入了恶意片段。例如它会检查括号是否匹配、字符串引号是否闭合试图识别出超出正常业务逻辑的查询结构。3. 统计学分析与异常检测这类WAF会建立请求的“正常行为基线”。比如一个登录接口正常的用户名参数长度可能在20个字符以内。如果你突然提交了一个长达5000个字符、包含各种特殊符号的用户名即使没有匹配到具体的攻击规则也会因为严重偏离基线而被判定为异常并拦截。4. 语义分析这是目前比较前沿的方向。WAF会尝试理解参数的“意图”。例如在一个商品ID的参数位置输入应该是数字如果你输入了包含SQL关键字的文本即使被编码或分割系统也可能通过上下文分析出其恶意意图。2.2 WAF的软肋与绕过思路起源没有完美的防御。WAF的软肋往往源于其设计目标与真实世界复杂性的矛盾性能与安全的平衡WAF必须快速处理海量请求因此深度分析如完整的SQL语法树解析往往成本高昂多数时候依赖于快速但可能粗糙的规则匹配。误报的容忍度过于严格的规则会导致大量正常业务请求被误拦误报这是业务方无法接受的。因此规则通常会在安全性和可用性之间妥协。规则更新滞后性新的攻击手法层出不穷规则库的更新总有延迟。对应用程序上下文的理解有限WAF站在应用之外它很难百分百理解每一个参数在具体业务代码中的真实用途和处理逻辑。基于这些软肋我们的绕过思路也就清晰了想方设法让你的恶意负载在WAF看来是“正常”或“无法识别”的同时又能被后端的数据库成功解析并执行。核心就是制造“差异”WAF解析的结果 vs. 数据库引擎解析的结果。3. 经典字符绕过技巧实战解析让我们从最基础、也最有效的字符层面技巧开始。这些方法主要利用的是WAF规则编写不够严谨或对数据标准化处理不一致的漏洞。3.1 大小写变奏曲这是最简单的一招。很多基于简单正则匹配的WAF其规则可能是大小写敏感的。例如规则可能只匹配union select但对UnIoN SeLeCt或UNION SELECT视而不见。?id1‘ UnIoN SeLeCt 1,2,3--实操心得在手工测试时可以准备一个大小写混合的常用关键字字典进行模糊测试。但要注意现代成熟的WAF如Cloudflare、AWS WAF大多已经做了大小写归一化处理这一招可能失效但它永远是值得尝试的第一步成本极低。3.2 双写与冗余字符干扰在关键字中间插入一些WAF可能忽略但数据库SQL引擎会自动忽略的字符。最常见的是注释符/**/MySQL中。?id1‘ uni/**/on sel/**/ect 1,2,3 from users--WAF的规则可能直接匹配连续的union select但被/**/隔开后匹配失败。而MySQL数据库在执行SQL前会移除这些注释因此实际执行的语句依然是union select 1,2,3 from users。除了注释还可以使用其他会被数据库忽略的字符如在MySQL中某些版本的某些场景下%0a换行符、%0d回车符、%09制表符也可能被利用。?id1‘ uni%0aon%0dselect 1,2,3--注意事项这种方法高度依赖于具体的WAF实现和数据库类型。需要针对目标环境进行测试。/**/在MySQL中通用性较好但在其他数据库如SQL Server的/**/可能不被支持中需调整。3.3 编码与多重编码的艺术这是绕过中高级WAF的利器。其核心思想是WAF可能只对输入进行一层解码检查而应用程序或数据库可能会进行多层解码。URL编码将关键字符进行URL编码百分号编码。?id1‘ union%20select%201,2,3--这里的%20是空格。如果WAF直接匹配“union select”中的空格而忽略了解码则可能绕过。双重URL编码更保险的做法是进行两次编码。空格-%20-%2520。?id1‘ union%2520select%25201,2,3--假设WAF只做一次URL解码它看到的是union%20select依然包含%20可能不认为这是关键字。但应用服务器如Apache/Nginx或后端代码通常会进行完整的URL解码最终数据库收到的还是union select。十六进制编码将整个或部分关键字转换为十六进制表示。这在绕过对特定字符串的过滤时非常有效。?id1‘ and 1(select 1 from users where user0x61646d696e)--这里0x61646d696e是字符串admin的十六进制。WAF规则可能匹配user‘admin‘但很难去匹配所有可能的十六进制串。Unicode编码/HTML实体编码在Web上下文中有奇效。例如单引号‘可以编码为#x27;或#39;。如果WAF没有规范化这些实体而后端代码在渲染或处理时又将其解码就会产生漏洞。?id1#x27; union select 1,2,3--核心技巧编码绕过的关键在于找到WAF解码层和应用程序解码层之间的“断层”。你需要通过测试判断WAF在哪个环节进行检查而 payload 又在哪个环节被还原。常用的测试方法是先提交一个无害的编码 payload如%41代表 ‘A‘观察返回结果中 ‘A‘ 是否正常显示以此判断解码流程。4. 语句结构与逻辑绕过进阶当字符层面的把戏被识破后我们就需要更深入地玩弄SQL语句本身的逻辑和结构。4.1 内联注释的妙用MySQL特有的内联注释/*!...*/是一个宝藏。其中的代码只有在MySQL特定版本或更高版本下才会被执行。我们可以利用它来包裹整个恶意语句有时能起到混淆作用。?id1‘ /*!union*/ /*!select*/ 1,2,3--更高级的用法是利用/*!50000...*/这种版本号注释但我们的主要目的不是版本控制而是将其作为一个特殊的“标记符”可能干扰WAF的简单分词。4.2 等价函数与操作符替换不要死磕被拦截的关键字寻找它们的“替身”。or 11被拦截试试or 21、or 99100、or true在某些数据库、or ‘a‘‘a‘。and被拦截试试MySQL中。‘admin‘被拦截试试like ‘admin‘、in (‘admin‘)。substring()被拦截试试mid()、substr()、left()。sleep(5)被拦截试试benchmark(10000000, md5(‘test‘))通过执行大量计算来制造延迟。union select被拦截是否可以尝试基于错误的注入或时间盲注完全避开union实战案例在一次测试中information_schema.tables被严格过滤。我们转而使用mysql.innodb_table_statsMySQL特定来获取表名信息成功绕过了基于常见表名的过滤规则。4.3 分块传输编码Chunked Transfer Encoding干扰这是一种协议层的绕过技巧主要针对那些依赖于解析完整HTTP请求体的WAF。通过将请求体分块发送可以扰乱WAF的解析器使其无法正确识别出完整的恶意参数。通常你需要借助工具来构造这种请求比如Burp Suite的 “Chunked Transfer Encoding” 插件。原理是将union select这样的关键词拆散到不同的传输块中WAF可能因为看不到完整的连续数据流而放行但后端Web服务器会正确重组这些块形成完整的攻击语句。注意事项这种方法对WAF的实现要求较高且不一定所有服务器都支持或启用分块传输。它更偏向于一种“奇技淫巧”在常规方法无效时可以尝试。4.4 参数污染与参数拆分利用应用程序处理多个同名参数的逻辑差异。有些WAF只检查第一个或最后一个参数而应用程序可能以不同方式拼接它们。?id1id2‘ union select 1,2,3--或者将 payload 拆分到不同的参数中后端代码错误地将其拼接。?field‘ union selfield2ect 1,2,3--这需要你对目标应用的参数处理逻辑有猜测或了解通过模糊测试来发现。5. 基于时间与布尔盲注的绕过策略当直接的错误回显和联合查询都被封死时盲注就成了唯一的出路。而针对盲注的WAF规则往往侧重于检测明显的延迟函数如sleep,benchmark和布尔判断模式。5.1 时间盲注的隐蔽延迟sleep(5)太明显了我们可以制造更“自然”的延迟。重型查询延迟执行一个查询巨大表或复杂连接的语句来消耗时间。‘ and (select count(*) from information_schema.columns A, information_schema.columns B, information_schema.columns C) 1 and ‘1‘‘1这种笛卡尔积查询在数据量大时会显著耗时。网络延迟诱导在某些情况下可以利用like ‘%a%‘对长文本字段进行模糊查询或者使用regexp进行复杂的正则匹配来消耗数据库CPU时间间接产生延迟。但这需要目标字段存在且数据量足够大。绕过sleep检测的技巧如果将sleep编码成分散的形式如sl/**/eep(5)或者将其放在一个复杂的表达式里有时可以绕过简单的正则匹配。但更高级的WAF会进行语法分析识别出函数调用结构。5.2 布尔盲注的隐式判断避免使用and 11和and 12这种经典模式。可以改用更隐晦的比较。使用位运算‘ and ascii(substr(database(),1,1))164--。将比较转化为移位运算可能绕过对等号和比较符、的简单检测。使用in或between ... and ...‘ and substr(database(),1,1) in (‘a‘,‘b‘,‘c‘)--。利用数学函数‘ and pow(2, ascii(substr(database(),1,1))-96) 0--。构造一个依赖于目标字符的数学表达式。核心思路是让你的布尔判断看起来不像一个典型的盲注判断逻辑更像一个复杂的业务查询条件。6. 工具使用技巧与手工结合sqlmap 是自动化注入的神器但它默认的 payload 很容易被WAF识别。高手都是将手工技巧与工具结合。6.1 定制化sqlmap Tamper脚本sqlmap 的--tamper参数是其灵魂所在。Tamper脚本用于在发送 payload 前对其进行混淆、编码等操作。常用内置Tamperspace2comment.py: 用/**/替换空格。between.py: 用between ... and ...替换大于号和小于号。charencode.py: 对 payload 进行URL编码。randomcase.py: 随机大小写。equaltolike.py: 用like替换。apostrophemask.py: 用UTF-8全角字符伪装单引号。组合使用可以同时使用多个tamper形成组合拳。sqlmap -u “http://target.com/page?id1“ --tamperspace2comment,randomcase,charencode --level3 --risk2自定义Tamper当内置脚本无效时需要根据目标WAF的行为编写自己的Tamper脚本。例如你可以写一个脚本将union select转换成uni%0aon%0dsel%09ect。这需要你具备基本的Python编程能力并理解sqlmap的Tamper接口。6.2 低慢速攻击模式有些WAF针对单个请求进行检测很强但对长时间、低频率的请求流缺乏关联分析能力。sqlmap 的--delay和--time-sec参数可以用于调节请求速度模拟正常用户行为避免触发基于请求速率的异常检测。sqlmap -u “http://target.com/page?id1“ --delay2 --time-sec5这会让sqlmap在每个请求间等待2秒并将时间盲注的延迟基准设为5秒使得攻击流量更“平滑”。6.3 代理与流量分发如果目标IP因为大量攻击请求被临时封禁可以考虑使用--proxy或--proxy-file通过代理池发送请求分散流量来源。同时配合--random-agent随机化User-Agent让请求看起来更像来自不同的浏览器。7. 实战场景与综合绕过思路在实际环境中很少有一种方法能通吃。你需要像侦探一样收集信息逐步试探组合拳出击。7.1 信息收集与指纹识别WAF指纹识别使用工具如WAFW00F或手工方法判断目标使用的WAF类型Cloudflare, Akamai, ModSecurity, 长亭雷池等。不同WAF的规则强度和侧重点不同了解对手是第一步。错误信息分析故意触发一个错误如输入一个单引号观察返回的错误页面。有时错误信息会直接暴露后端数据库类型MySQL, PostgreSQL, SQL Server等甚至WAF的名称和版本。数据库类型直接决定了你可用的绕过函数和语法。参数可接受格式测试测试参数对数据类型、长度、特殊字符的容忍度。例如一个数字型参数是否接受引号是否接受科学计数法这能帮你判断注入点类型和可能的过滤强度。7.2 分层渐进测试法不要一上来就扔最复杂的 payload。建立一个系统的测试流程基础探测测试‘、“、\等字符看是否被过滤或转义是否有错误回显。简单绕过尝试使用大小写、内联注释/**/、简单编码如空格变或%20测试and 11这类简单逻辑。关键字拆分测试如果简单拦截尝试用uni/**/on sel/**/ect。编码测试尝试URL编码、双重URL编码、十六进制编码关键部分。等价替换测试如果union被拦尝试基于错误的注入‘ and updatexml(1,concat(0x7e,database()),1)--或者时间盲注‘ and if(11,sleep(5),0)--。协议/参数层测试在前端方法都无效时考虑分块传输、参数污染、HTTP方法转换GET变POST等。7.3 一个综合案例模拟假设目标URL为http://target.com/news.php?id123存在数字型注入但部署了某品牌WAF。第一步id123‘返回被WAF拦截页面。第二步id123 and 11被拦截。第三步id123 anandd 11双写绕过成功页面正常。说明WAF可能采用了简单的“查找-删除”过滤机制把and删除了留下了an d但数据库执行时是anandd- 删除中间的an后变成and。成功验证注入点。第四步id123 union select 1,2,3被拦截。第五步id123 uniunionon selselectect 1,2,3双写绕过联合查询可能成功。如果不成功尝试id123 uni/**/on sel/**/ect 1,2,3。第六步获取数据时information_schema被拦截。尝试使用mysql.innodb_table_stats或sys.schema_table_statistics等替代视图MySQL 5.6。第七步使用sqlmap自动化并编写自定义tamper将union select自动转换为uniunionon selselectect或加入随机注释。8. 防御视角与总结反思作为渗透测试者我们的目标是发现问题。而从防御者角度看这些绕过技巧揭示了WAF部署的常见误区依赖单一WAFWAF应该是纵深防御体系中的一环而非唯一屏障。必须结合安全的编码实践使用参数化查询/预编译语句、最小权限原则、输入输出验证等。规则设置过于宽松或僵化盲目使用默认规则集而不根据业务调整要么导致大量误报要么留下绕过空间。需要定期审查和更新规则并关注WAF的日志分析被拦截和绕过的案例。忽略应用层上下文最有效的防御在代码层面。开发人员应接受安全培训避免拼接SQL字符串。框架提供的ORM或安全查询接口应被强制使用。个人实操中的深刻体会是没有永远有效的绕过方法只有不断演进的攻防博弈。今天有效的技巧明天可能就被加入规则库。因此理解原理远比记忆payload重要。当你明白WAF是如何匹配union select的你自然能想到用uni%0aon%0dselect去尝试当你理解数据库解析SQL的过程你就能创造出各种“语法正确但看似怪异”的语句。在授权测试中我的习惯是每当成功绕过一次我都会问自己如果我是防守方该如何改进规则或代码来堵住这个缺口这种双向思考能让你的安全技能从“术”的层面提升到“道”的层面。最后请务必记住所有技术都应在法律和道德授权的范围内使用我们的终极目标是让网络空间更安全。