从 PCAP 提取攻击串并编写高精度规则

约 35 分钟

能从授权靶场 PCAP 中提取攻击特征串,编写含 content 修饰符与 pcre 的高精度规则并通过回放验证。

上一节的自测题帮你厘清了 distance/within 的相对位置语义,也划定了 pcre 的使用边界——现在就让这两件工具接受实战检验。你手里有一份授权靶场捕获的攻击 PCAP,外加一段正常背景流量。目标很具体:从 PCAP 里找出攻击流,把攻击特征转成 content 与 pcre 表达式,写出一条高精度规则,再用离线回放证明它能命中攻击、且对背景流量零误报。判断规则好坏只有两条标准:该中的必须中,不该中的不能中。流程是四步闭环:定位、提取、编码、验证。社区推荐的路线与此一致——下载一份带恶意软件的 PCAP,在 Wireshark 里分析威胁,写规则,用 -r 离线跑一遍,最后检查 fast.log 是否识别出威胁。缺练习材料时,视频教程作者公开了一个实战攻击 PCAP 下载地址:https://www.mohammedalani.com/dc6-attack.zip 。

核心概念

攻击特征提取:从流量里挑指纹

生活类比:刑警拿到一段监控录像,不会只记下“有人走动”——那太常见。他会盯住嫌疑人独有的细节:步态、外套颜色、掏口袋的小动作。录像反复回放,把细节钉死,再拿去比对。技术定义:攻击特征提取,是从授权 PCAP 中定位攻击流,挑选在攻击中稳定出现、在正常流量中极少出现的字节序列或字节序列组合,作为 content 与 pcre 的匹配依据。挑选标准只有两条:特异——正常流量里几乎见不到;稳定——同种攻击下次出现时它还在。例如“命令执行成功”类攻击中,uid=0 与括号这类结构稳定,而回显内容可能变化:稳定部分写成 content,可变部分交给 pcre。特征太短会误报,太长会漏报;全用固定字节会漏掉变体,全用正则又会拖慢匹配。

核心概念

回放验证闭环:校准命中与误报

生活类比:调吉他弦,不是拧一次就完事。你弹一下,听音准,再拧弦钮,再弹,直到音准。每一次弹奏都是反馈。技术定义:回放验证闭环,是用 -r 把规则跑在 PCAP 上,读 fast.log 与 eve.json 的命中结果,再依据结果调整 depth、offset、distance、within 与 pcre,直到对攻击 PCAP 命中、对背景流量零命中。一次回放只回答一个问题:这条规则放走了什么、误报了谁。反馈来自两个日志:fast.log 给出每一条命中的一行摘要,eve.json 给出结构化告警细节,两者结合才能定位偏差。循环往复,直到收敛。

定位攻击流并提取特征串

  1. 1

    准备两个文件:攻击 PCAP 与一段正常背景流量 PCAP。确认两者都在本机,来源已获授权。还没有攻击 PCAP 时,可用视频作者公开的练习包:https://www.mohammedalani.com/dc6-attack.zip 。

  2. 2

    打开攻击 PCAP,先看协议统计。官方社区建议用 Wireshark 分析威胁;视频教程的做法是打开 Statistics 下的协议层级统计,看各协议占比,把注意力优先放在最常被滥用的协议(通常是 HTTP)上。

  3. 3

    过滤出该协议的流量,逐个查看请求,先看 POST 类——攻击载荷常藏在表单提交里。

  4. 4

    对可疑连接用“跟随 TCP 流”从头读到尾。视频示例里的攻击,正是在表单内容中夹带了 netcat 反向 shell 命令。

  5. 5

    选定特征字节:写下攻击中稳定出现的串。官方快速入门示例用 content:"uid=0|28|root|29|" 表示命令执行后以 root 身份返回的响应,|28|、|29| 是左右括号的十六进制字节。照此格式记录你自己 PCAP 里的特征。

  6. 6

    把特征串放进背景流量里搜一遍:频繁出现说明不够特异,换更长或更独特的片段。

你应该看到

你已确定至少一个攻击流,并写下两份材料:一条稳定的特征串(含十六进制字节表示),以及它出现的位置与方向。

编码规则、回放验证并收紧

  1. 1

    新建规则文件,把特征串写成 content。以官方快速入门中的模板为起点:

    shell
    alert ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
  2. 2

    把特征串替换进模板,用已学的修饰符收紧:大小写不固定加 nocase;位置固定加 depth/offset;特征分两段用 distance/within 约束相对位置;边界或变体用 pcre。每条规则用独立 sid,避免与已有规则集冲突。

  3. 3

    先跑测试模式确认语法无误,再回放。

  4. 4

    用 -r 离线回放攻击 PCAP:

    bash
    suricata -r /path/to/attack.pcap
  5. 5

    查看 fast.log 是否出现你的 sid。没有命中就回 Wireshark 核对特征串,再按第 2 步调整。fast.log 需要在 suricata.yaml 中启用,发行版包通常把配置放在 /etc/suricata/suricata.yaml。

  6. 6

    查看 eve.json 核对告警细节。快速入门建议安装 jq,用它帮助查看 EVE JSON 输出;确认告警消息、sid、时间与 fast.log 一致。

  7. 7

    回放背景流量 PCAP,确认零命中。出现误报就收紧修饰符或换特征串,重复第 3 到第 6 步,直到攻击必中、背景必静。

你应该看到

规则通过 -T 语法测试;回放攻击 PCAP 时,fast.log 与 eve.json 都出现对应 sid 的告警;回放背景流量时零告警。

遇到问题:回放攻击 PCAP 后 fast.log 没有任何命中,或背景流量上告警成片。

可能原因

  • 特征串与实际字节不一致:大小写不同,且没加 nocase。
  • 特征串过长或含可变字节(如会话随机串),真实攻击里已经变化。
  • 规则方向与特征所在流量方向不符:特征在响应里,规则却只匹配请求方向。
  • 把该用相对位置的两段内容硬拼成一个长 content,正常流量偶发相同长串,造成误报。
  • fast.log 输出未在 suricata.yaml 中启用,或配置路径不正确。

排查步骤

  1. 回 Wireshark 重新跟随 TCP 流,逐字节核对提取的串,必要时记录十六进制字节。
  2. 大小写可能变化的部分加 nocase;位置固定的片段加 depth/offset。
  3. 核对特征所在方向,调整 -> 方向或改用 <> 双向匹配。
  4. 把长串拆成两段,用 distance/within 约束相对距离,减少整串偶合。
  5. 检查 suricata.yaml 中 fast 输出已启用且路径正确(发行版包通常位于 /etc/suricata/suricata.yaml)。
  6. 重新 -T 后再次 -r 回放,对比 fast.log 与 eve.json,确认命中集合符合预期。
自检:你从攻击 PCAP 中提取到字符串 uid=0(root),左右括号是十六进制字节 28 与 29。写出对应的 content 片段,并给出至少两种减少误报的修饰符思路。

content:"uid=0|28|root|29|",括号用 |28| 与 |29| 十六进制表示。减少误报的思路:一、给 content 加 depth/offset,限定它在载荷中的出现位置;二、把特征拆成两段,用 distance/within 约束两段之间的相对距离,避免整串在正常流量中偶合;三、大小写不固定时加 nocase;四、边界或数量有变化的部分改用 pcre 表达。

一条规则走完了从 PCAP 到验证的全过程。标准始终是那两条:能中的必须中,不该中的不能中。好的规则集用尽量少的条数覆盖尽量多的攻击,而不是堆出海量噪声。下一步,把同一套定位、提取、验证方法搬到 HTTP 归一化缓冲区上,那里是 Web 攻击检测的主战场。