传统 WAF 通常使用正则表达式的形式, 以关键字定义攻击特征, 拿知名的 modsecurity 引擎来看, 这个世界上 80% 的 WAF 都是由它来驱动的, 但是它通常有一些什么规则, 让我们来剖析一下
union[\w\s]*?select
, 这条规则代表流量中只要包含 union
和 select
这两个单词就会被认为是 SQL 注入
攻击\balert\s*\(
, 这条规则代表流量中只要包含 alert
单词, 并且它的后面有一个左括号 (
就会被认为是 XSS
攻击真正的攻击者是具有对抗性的, 他们可以轻松逃避这些关键字, 从而绕过 WAF 的防护, 以上面的规则为例, 来看他们的漏报例子
union /**/ select
, 在 union
和 select
中间插入了注释字符, 破坏了关键字特征, 因此攻击无法被发现window['\x61lert']()
, 用 \x61
代替了字母 a
, 破坏了关键字特征, 因此攻击无法被发现通过以上的例子, 我们可以得出结论, 传统的基于正则表达式的 WAF 无法真正防住攻击, 总会被黑客绕过
不仅如此, 正则表达式还会造成大量的误报, 导致真正的网站用户受到牵连, 无法正常使用业务, 还是以上面的规则为例, 来看他们的误报例子
The union select members from each department to form a committee.
, 他命中了上面的规则, 会被误认为是 SQL 注入
攻击而拦截, 实际上他只是一个简单的英文句子Her down on the alert(for the man) and walked into a world of rivers.
, 他命中了上面的规则, 会被误认为是 XSS
攻击而拦截, 实际上他只是一个简单的英文句子这里给大家分享两篇课外读物, 看看来自世界黑帽大会 Black Hat 的大神是如何自动化绕过基于正则表达式的 WAF 防护的:
语义分析算法是雷池 WAF 的核心能力, 他不再使用简单的攻击特征去匹配流量, 而是去真正理解流量中的用户输入, 深层分析潜在的攻击行为.
以 SQL 注入为例, 攻击者如需完成 SQL 注入攻击, 需要满足两个条件
union select xxx from xxx where
是符合语法的 SQL 语句片段union select xxx from xxx xxx xxx xxx xxx where
则不是符合语法的 SQL 语句片段1 + 1 = 2
是符合语法的 SQL 语句片段1 + 1 is 2
则不是符合语法的 SQL 语句片段union select xxx from xxx where
存在可能的恶意行为1 + 1 = 2
没什么实际意义雷池会根据 SQL 注入攻击的本质进行攻击检测, 类似下方流程
雷池内置涵盖常用编程语言的编译器,通过对 HTTP 的载荷内容进行深度解码后,按照其语言类型匹配相应语法编译器,进而匹配威胁模型得到威胁评级,阻断或允许访问请求。
计算机专业的同学都学过 编译原理
, 在编译原理中提到的 Chomsky 文法体系, 他将计算机世界的形式语言分为四个类型
这 4 种文法的表达能力从 0 到 3 依次变弱, 我们日常使用的 SQL, HTML, JAVASCRIPT 等编程语言通常是 2 型文法(甚至包含一部分 1 型文法的能力), 而正则表达式实际上对应的就是表达能力最弱的 3 型文法.
正则表达式的表达能力到底有多弱呢, 一个经典的例子是 正则表达式无法计数
, 你甚至无法用正则表达式识别一个合法的括号配对字符串
用表达能力如此之弱的 3 型文法去匹配变化自如的攻击 payload 必然是不可能, 究其原因, 就是由于基于规则匹配的攻击识别方法存在先天不足导致的, 从文法表达能力比较,3 型文法包含在 2 型文法之内,基于正则的规则描述无法完全覆盖基于程序语言的攻击 Payload,这也是基于规则匹配识别攻击的 WAF 防护效果低于预期的根本原因。
因此, 语义分析与正则特征规则匹配型威胁检测方式相比,具有准确率高、误报率低的特点。