能用 nocase、depth、offset 修饰符缩小匹配范围并减少误报。
上一课你通过测试模式、PCAP 回放和 fast.log,亲手验证了 content 对 ASCII 字面量和 |xx| 十六进制字节都能精确命中。验证之后,两个隐患浮出水面:content 默认大小写敏感,还会在整段载荷里任意位置搜索。结果有两个问题:攻击者换个大小写,规则就漏报;同一个串出现在无关位置,规则就误报。
接下来你用三个修饰符解决:nocase、depth、offset。它们都跟在 content 后面,作用是把搜索范围收窄。范围越窄,误报越少,引擎要比较的字节也越少。
核心概念
nocase:让匹配忽略大小写
类比:门卫拿着名单找人,只认“Li Ming”这一种写法,写成“li ming”就被放走了。nocase 相当于告诉门卫:写法不分大小写,字母相同就算找到。
定义:nocase 是紧跟 content 的修饰符,令该 content 的匹配不区分字母大小写,即执行不区分大小写的搜索。例如 content:"GET"; nocase; 能同时命中 GET、get、Get。
把 nocase 加进规则:
alert tcp any any -> any any (msg:"HTTP GET 请求"; content:"GET"; nocase; sid:2100011; rev:1;)现在 get、Get、gEt 都能命中,大小写变体不再漏报。注意:nocase 只作用于它前面那一个 content;规则里若有多个 content,需要各自声明修饰符。
核心概念
depth 与 offset:把搜索框进窗口
类比:在一面长墙上找一行字。整面墙逐字看,慢,还容易认错,墙尾相似的涂鸦也会干扰你。你先从墙头量到字的大致位置(offset),再限定只看墙头起多长一段(depth),范围就清楚了。
定义:offset:N 指定 content 从载荷第 N 个字节起才开始搜索(从 0 计数);depth:N 限制搜索最远到载荷起点算起的第 N 个字节。组合使用后,搜索被限制在 offset 到 depth 之间的窗口内,单位都是字节。
窗口匹配示例:
alert tcp any any -> any any (msg:"窗口内的 admin"; content:"admin"; offset:10; depth:20; sid:2100012; rev:1;)载荷第 10 字节到第 20 字节之间出现 admin 才告警。窗口之外出现的 admin 不再触发,位置相近但无关的流量被过滤掉。窗口收得越紧,误报越少;但要保证目标串完整落在窗口内,否则连真实告警一起漏掉。
什么时候值得用窗口匹配?目标串在载荷里的位置相对固定时,offset 与 depth 最能发挥作用。位置越确定,窗口收得越小,误报越少。位置不确定时,先用宽松窗口,观察误报来源后再逐步收紧。
动手前先用 Wireshark 打开 PCAP,定位目标串实际出现的字节位置,再据此写 offset 与 depth。凭感觉圈窗口容易把目标告警圈掉;回放后目标告警消失,就回到载荷里核对位置。
本课回放只针对本地 PCAP 与授权靶场流量,不要对未授权或生产网络启用规则做探测,验证一律在离线回放中完成。回放前确认 suricata.yaml 已启用 fast.log 输出,否则告警无处可查。
收紧边界并对比命中变化
- 1
确认
suricata.yaml中已启用fast.log输出;未启用先补上(沿用上一节配置)。 - 2
用上一节的测试模式命令校验基线规则,确认语法无误。
- 3
用
suricata -r path-to-pcap回放基线规则,统计fast.log中目标 sid 的告警行数,记为基线。bashsuricata -r path-to-pcap - 4
改写规则:目标
content加nocase,再按目标串实际位置补offset与depth,把匹配框进窗口。 - 5
再次用测试模式校验改写后的规则,通过后回放同一份 PCAP。
- 6
对比两次
fast.log中该 sid 的告警行数,并确认目标告警仍然出现。
你应该看到
二次回放后,目标 sid 在 fast.log 中的行数明显少于基线,且目标告警仍出现。命中减少、目标仍在,边界收紧有效;若目标告警消失,说明窗口圈错,参考 troubleshoot 排查。
遇到问题:加上 offset/depth 后回放,目标告警在 fast.log 中消失。
可能原因
- 目标串实际位置落在
offset与depth圈出的窗口之外。 offset与depth的含义用反,搜索窗口与预期不符。- 窗口内目标串的大小写与规则不一致,且规则未加
nocase。 - 规则语法或修饰符顺序有误,规则未被引擎正常加载。
排查步骤
- 先过测试模式,确认规则被正常加载、无语法错误。
- 用 Wireshark 查看载荷中目标串的实际字节位置,重新计算
offset与depth。 - 大小写不稳定就先加
nocase,再单独调整窗口,一次只改一个变量。 - 每次改动后回放同一 PCAP,对照
fast.log行数变化定位问题。
自检:目标串 Login 在载荷中出现三次:第 4 字节是 login,第 12 字节是 Login,第 30 字节是 Login。规则为 content:"Login"; nocase; offset:6; depth:20;。哪一处会告警?为什么?
只有第 12 字节那处告警。nocase 让大小写不敏感,第 4 字节的 login 也算候选命中;但 offset:6 从第 6 字节才开始搜索,第 4 字节在窗口之前。depth:20 限定最远到第 20 字节,第 30 字节在窗口之外。窗口内只剩第 12 字节。