雷池 WAF 行为分析

这篇主要不是拆源码,而是记录一次偏黑盒的行为观察。通过后台日志和实际拦截效果来看,雷池内部大概率不是“命中一个规则就立刻拦”,而是更接近一种特征叠加后的评分机制

目前我主要看了两个场景:

  • 文件包含
  • 命令执行

最终得到的核心结论是:平衡防护和高强度防护,对应的更像是两套不同的拦截阈值。

先说结论

从这次实验现象看,我目前的判断是:

  1. 某些危险特征本身会被记录,但不一定单独触发拦截。
  2. 当危险特征和更强的攻击语义组合在一起时,请求才会超过阈值。
  3. 切到高强度防护后,阈值下降,所以原本只“记分不拦截”的请求会被直接拦掉。

这不是代码层面的定论,而是根据黑盒测试行为做出的推测;但从现象上看,这个解释是比较自洽的。

文件包含场景

先看一个本地文件包含的测试请求:

http://192.168.137.161/vul/fileinclude/fi_local.php?filename=../../../../etc/rpc&submit=%E6%8F%90%E4%BA%A4

这个请求本身已经很可疑了,正常业务几乎不可能出现这种 ../../../../ 的访问方式,而且实际上已经尝试把系统文件带进来了。
但在平衡防护下,它似乎还达不到拦截阈值。

相对地,如果换成更典型的攻击目标:

http://192.168.137.161/vul/fileinclude/fi_local.php?filename=../../../../etc/passwd&submit=%E6%8F%90%E4%BA%A4

这时就会被拦截。

这里很像是在说:

  • ../../../../ 本身会加分
  • /etc/passwd 这种高危关键词会继续加分
  • 两者叠加后,才超过平衡防护的阈值

高强度防护下的变化

当切换到高强度防护后,前面这个原本不会被拦的请求:

http://192.168.137.161/vul/fileinclude/fi_local.php?filename=../../../../etc/rpc&submit=%E6%8F%90%E4%BA%A4

也会被直接拦截。

甚至连这种更“泛化”的目录穿越:

http://192.168.137.161/vul/fileinclude/fi_local.php?filename=../../../../&submit=%E6%8F%90%E4%BA%A4

在高强度防护下也会拦。

这进一步支持了前面的判断:不是规则有没有命中,而是命中后累计分值是否超过当前模式的阈值。

关于目录层级的一个现象

还有一个比较有意思的点:目录穿越并不是一出现就拦,而是至少穿越到三层及以上时,拦截会明显稳定很多。比如下面这个请求:

http://192.168.137.161/vul/fileinclude/fi_local.php?filename=../../../&submit=%E6%8F%90%E4%BA%A4

从现象上看,这个“层数”似乎也参与了内部判断。

这里我暂时有两个猜测:

  • 雷池只是把 ../ 的数量当成风险特征之一,层数越多分越高。
  • 雷池会结合 URL 路径去粗略判断,当前穿越层数是否已经可能逃出站点目录。

第二种猜测我暂时没有证据,只能先记下来,后续如果有源码或更多样本再验证。

命令执行场景

命令执行这边也能看到类似规律。

如果在 Pikachu 的命令执行点里输入:

127.0.0.1 | cat rce.php

这个请求可以读取当前目录下的文件,但在平衡防护下并不会被拦截。

也就是说,cat 本身不是绝对拦截条件;它可能只是一个高风险特征,但还没高到单独触发拦截。

一旦越权访问,风险分明显上升

只要 cat 读取跨目录文件,就会马上被拦下来,比如:

127.0.0.1 | cat ../xss/xss_01.php

而且即便目标路径根本不存在,只要形态足够危险,也照样会被拦:

127.0.0.1 | cat /sdasdssaasd

这里说明 WAF 看的不是“命令能不能成功执行”,而是请求本身长得像不像攻击

ls 的风险权重明显更低

相比之下,ls 的容忍度就高很多。

例如下面这些请求,基本都能通过:

127.0.0.1 | ls ../xss/
127.0.0.1 | ls /.

这说明在它的规则体系里:

  • ls 可能只是低风险探测行为
  • cat 更接近“直接读取敏感内容”的动作,因此权重更高

如果沿着这个思路理解,前面的现象就都能串起来了:不同命令、不同路径、不同关键词,都会给请求带来不同的风险权重。

我的当前判断

综合文件包含和命令执行两个场景,我目前更倾向于把雷池的这套行为理解成:

  1. 先抽取攻击特征,例如 ../、敏感路径、命令关键字、跨目录访问等。
  2. 再给这些特征分配不同权重。
  3. 最后根据当前防护模式使用不同阈值决定是否拦截。

如果用最粗糙的话来概括,就是:

平衡防护偏向“明显攻击再拦”,高强度防护偏向“可疑就先拦”。

当然,这仍然只是基于现象的推断,不排除它内部还有更细的规则分流、上下文判断,或者针对特定漏洞场景的专项规则。

结尾

这次分析给我最大的感觉是:很多 WAF 的拦截逻辑,未必是外界想象中的“关键词命中即封”。实际产品为了兼顾误报率和业务可用性,通常都会做得更像一个风险评估系统。

也正因为这样,单个 payload 是否拦截,往往不能孤立地看。更合理的观察方式应该是:

  • 当前命中了哪些特征
  • 这些特征的组合是否会叠加
  • 防护模式对应的阈值有没有变化

后面如果我拿到更多日志样本,或者有机会继续对其他模块做对照测试,再把这篇往下补。