简介
Snort 是一款功能强大的开源网络入侵检测系统(NIDS)。其最显著的特点之一是灵活的基于规则的语言,允许安全专业人员为恶意网络活动定义签名。
规则是理论与检测之间的桥梁。诸如「端口扫描是可疑的」这类安全构想,只有在将其表达为引擎可以针对真实流量进行评估的形式时,才具有实际操作价值。因此,学习规则语法不仅是为了掌握 Snort 本身,更是为了学习防御者如何将行为转化为机器可读的逻辑。
在本实验中,你将学习自定义 Snort 规则的核心语法和结构。你将编写基础规则,通过定义动作、协议、IP 地址、端口和选项,专门检测并告警特定的 ICMP ping 和异常 TCP 流量模式。实验结束时,你将了解如何构建、测试和验证你自己的 Snort 规则。
理解规则语法和规则头
在这一步中,你将学习 Snort 规则的基本结构,并创建一个文件来存储你的自定义规则。
规则头实际上是一个范围定义。它决定了哪些流量值得进一步评估。这一点至关重要,因为高效的检测始于在应用更深层的内容检查之前,尽可能缩小候选流量集。宽泛的规则头虽然容易编写,但也可能产生更多的噪音。
Snort 规则分为两个主要的逻辑部分:规则头(Rule Header)和规则选项(Rule Options)。
规则头包含规则的动作、协议、源和目标 IP 地址,以及源和目标端口。它规定了谁在与谁通信,以及他们正在使用什么协议。基本语法如下所示:
[Action] [Protocol] [Source IP] [Source Port] -> [Destination IP] [Destination Port] (Options)
以下是规则头各组件的详细说明:
- Action(动作):当 Snort 发现与规则条件匹配的数据包时应采取的操作(例如
alert、log、drop)。 - Protocol(协议):流量的协议(例如
tcp、udp、icmp、ip)。 - IP Addresses(IP 地址):源和目标 IP 地址。你可以使用
any来匹配所有 IP 地址。 - Ports(端口):源和目标网络端口。你可以使用
any来匹配所有端口。 - Direction Operator(方向运算符):
->符号表示流量的方向(从源到目标)。你也可以使用<>来表示双向流量。
为了开始编写我们自己的规则,我们需要一个专门的文件。请确保你位于默认工作目录(~/project)中,并创建一个名为 local.rules 的新文件。
使用 touch 命令创建一个空文件:
touch ~/project/local.rules
你可以通过列出目录内容来验证文件是否创建成功:
ls -l ~/project/local.rules
你应该看到类似以下的输出,确认文件存在且当前为空:
-rw-r--r-- 1 labex labex 0 Jul 25 10:00 /home/labex/project/local.rules
编写 ICMP 检测规则
在这一步中,你将编写第一条 Snort 规则来检测 ICMP 流量。ICMP(互联网控制报文协议)通常被 ping 等网络工具用于检查连通性。
ICMP 是一个很好的教学示例,因为它简单且易于识别,但它也说明了一个实际的操作要点:并非所有的检测都意味着攻击。许多网络合法地使用 ping。分析师的工作是在决定事件是良性还是可疑之前,将规则匹配的内容与环境背景相结合。
我们将编写一条规则,当任何 ICMP 数据包从任何源发送到任何目标时,都会触发告警。
使用 nano 文本编辑器打开你的 local.rules 文件:
nano ~/project/local.rules
在编辑器中输入以下规则:
alert icmp any any -> any any (msg:"ICMP Ping Detected"; sid:1000001; rev:1;)
让我们解析一下这条规则的含义:
alert:要采取的动作。Snort 将生成一条告警。icmp:我们要监控的协议。any any -> any any:流量可以来自任何 IP 和任何端口,并发送到任何 IP 和任何端口。(msg:"ICMP Ping Detected"; sid:1000001; rev:1;):这些是规则选项。msg是告警消息,sid是唯一的 Snort ID(自定义规则的 ID 必须为 1,000,000 或更高),rev是规则的修订版本号。
输入规则后,保存文件并退出 nano:按 Ctrl+O,按 Enter 确认文件名,然后按 Ctrl+X 退出。
现在,让我们测试 Snort 是否能识别我们的规则文件。Snort 有一个测试模式(-T),可以在不实际启动检测引擎的情况下检查配置和规则是否存在语法错误。
运行以下命令来测试你的规则文件:
sudo snort -T -c ~/project/local.rules
当 Snort 初始化时,你会看到大量输出。查看输出底部附近,寻找确认 Snort 已成功验证配置的成功消息:
Snort successfully validated the configuration!
Snort exiting
如果你看到此消息,说明你的 ICMP 规则语法正确。
编写 TCP 端口告警规则
在这一步中,你将编写一条规则来检测特定的 TCP 流量。虽然 ICMP 不使用端口,但 TCP 和 UDP 使用。这使我们能够编写针对特定服务(如 HTTP,端口 80)或 SSH(端口 22)的规则。
端口为你提供了粗略的应用程序上下文。它们虽然不能说明全部情况,但通常是防御者用来区分服务类型的首要依据。一条以目标端口 80 为关键点的规则,本质上是在说:「我关注那些可能指向 Web 服务的流量。」
我们将编写一条规则,当有人尝试连接到端口 80 上的 Web 服务器时,向我们发出告警。
再次使用 nano 打开你的 local.rules 文件:
nano ~/project/local.rules
在现有 ICMP 规则下方添加一行,并输入以下 TCP 规则:
alert tcp any any -> any 80 (msg:"HTTP Traffic to Port 80 Detected"; sid:1000002; rev:1;)
让我们分析这条新规则的规则头:
alert tcp:我们正在为 TCP 协议生成告警。any any:源可以是任何 IP 地址和任何端口。->:流量正流向目标。any 80:目标可以是任何 IP 地址,但目标端口必须是 80。
注意,我们将 sid 增加到了 1000002。每条 Snort 规则都必须有一个唯一的 Snort ID。
保存文件(Ctrl+O,Enter)并退出 nano(Ctrl+X)。
再次提醒,测试规则语法以确保没有拼写错误是一个好习惯。运行 Snort 测试命令:
sudo snort -T -c ~/project/local.rules
滚动到输出底部以确认 Snort 已成功验证配置。现在你应该已经成功加载了两条规则。
包含规则选项(Msg、SID、Rev)
在这一步中,我们将深入探讨规则选项部分。选项部分包含在括号 () 中,并包含用分号 ; 分隔的关键字/值对。
规则选项是将粗略的流量类别转化为有意义告警的地方。清晰的 msg 有助于人类理解事件。唯一的 sid 让系统能够追踪是哪条规则触发了告警。rev 值让团队能够随时间管理检测内容。这些字段支持的是运维,而不仅仅是语法。
你已经使用了三个最基本的选项。第一个是 msg,它是将打印在告警日志中的消息,应该具有描述性。第二个是 sid,代表 Snort ID;用户编写的规则 SID 应大于 1,000,000。第三个是 rev,代表修订版本号;每次修改规则时,都应增加此数字以跟踪版本。
让我们编写一条规则来检测 SSH 连接尝试(端口 22),以练习使用这些选项。
打开你的 local.rules 文件:
nano ~/project/local.rules
将以下规则添加到文件末尾:
alert tcp any any -> any 22 (msg:"SSH Connection Attempt"; sid:1000003; rev:1;)
在这条规则中,我们设置了一个基本的 msg 并分配了一个新的唯一 SID(1000003)。
假设我们稍后决定更新此规则的消息以使其更具体。我们将更改 msg 并将 rev 增加到 2。现在让我们这样做。修改你刚才写在文件底部的 SSH 规则,使其看起来像这样:
alert tcp any any -> any 22 (msg:"Possible SSH Brute Force Attempt"; sid:1000003; rev:2;)
保存文件(Ctrl+O,Enter)并退出 nano(Ctrl+X)。
最后,再运行一次语法检查,确保你的所有三条规则格式都完美无缺:
sudo snort -T -c ~/project/local.rules
寻找验证成功的消息。现在,你已经成功使用规则头和选项编写并构建了多个自定义 Snort 规则。
总结
在本实验中,你学习了编写自定义 Snort 规则所需的基础技能。你探索了规则的结构,将其分为规则头和规则选项。你成功编写了用于检测常规 ICMP 流量和特定 TCP 端口流量的规则。此外,你还学习了如何利用 msg、sid 和 rev 等基本规则选项,使你的告警具有描述性和唯一可识别性。这些技能构成了创建高级网络入侵检测签名的基础。



