简介
像 Snort 这样的入侵检测系统(IDS)非常依赖规则来识别恶意网络流量。一条精心编写的规则就像一个特征码,当在数据包中观察到特定模式时,系统就会触发警报。
基于特征的检测是通过识别已知模式来工作的,而不是直接理解攻击者的意图。这种方法既快速又实用,但也存在局限性。如果模式定义得太宽泛,会产生误报;如果定义得太狭窄,攻击者可以通过微小的改动绕过检测。因此,编写优秀的规则是在精确度和覆盖范围之间寻找平衡的过程。
在本实验中,你将扮演一名安全分析师。你将编写能够检测应用层攻击的内容匹配 Snort 规则。具体来说,你将分析一个在 PCAP(数据包捕获)文件中捕获的模拟 SQL 注入攻击载荷,并使用基本内容匹配和高级正则表达式(PCRE)来制作精确的 Snort 规则,以检查 HTTP 流量并在检测到恶意字符串时发出警报。
分析攻击载荷 (PCAP)
在这一步中,你将分析一个网络数据包捕获文件,以了解恶意载荷的样子。在编写检测规则之前,安全分析师必须首先确切地知道他们要检测的是什么。
顺序很重要。初学者常犯的一个错误是在检查真实流量之前就开始编写特征码。在实践中,防御者通常从证据开始:一个 PCAP 文件、一段日志样本或漏洞利用的概念验证。只有在理解了可观察的模式后,他们才会将其转化为规则。
你的环境中已经在 ~/project 目录下预配置了一个名为 sqli_attack.pcap 的文件。该文件包含一个模拟的网络数据包,其中攻击者正试图对 Web 服务器进行 SQL 注入攻击。
要检查此 PCAP 文件的内容,你可以使用名为 tcpdump 的工具。tcpdump 命令是一个功能强大的命令行数据包分析器。通过使用 -A 标志,你可以以 ASCII(纯文本)格式打印数据包内容,这非常适合阅读 HTTP 请求。-r 标志告诉 tcpdump 从文件而不是实时网络接口读取数据。
在终端中运行以下命令来分析载荷:
tcpdump -A -r sqli_attack.pcap
你应该会看到类似以下的输出:
reading from file sqli_attack.pcap, link-type EN10MB (Ethernet), snapshot length 262144
10:23:45.123456 IP 192.168.1.100.12345 > 192.168.1.10.http: Flags [P.], seq 1:78, ack 1, win 8192, length 77: HTTP: GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
E..u..@.@............9.P..P.P.......+......GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
Host: example.com
仔细观察输出中的纯文本部分。你可以看到一个针对 /login.php 的 HTTP GET 请求。注意 user 参数:admin'%20UNION%20SELECT%201,2,3--。
%20 是空格字符的 URL 编码表示。UNION SELECT 短语是 SQL 注入攻击的经典特征,攻击者试图将他们自己的恶意数据库查询结果与原始查询合并。这正是我们想要检测的精确特征。
编写内容匹配规则
在这一步中,你将编写第一个自定义 Snort 规则,以检测你在上一步中发现的 SQL 注入特征。
content 关键字是载荷检查的最简单形式。它快速且易于理解,因为它搜索的是字面字符串。字面匹配通常是特征码的第一个草稿,因为它使检测逻辑变得透明。
Snort 规则采用特定的语法编写。基本规则由规则头和规则选项组成。
- 规则头定义了动作、协议、源/目的 IP 地址和端口。
- 规则选项定义了要查找的具体内容以及触发警报时显示的消息。
我们将创建一个规则,在任何发往 80 端口(标准 HTTP 端口)的 TCP 流量中查找确切的字符串 UNION%20SELECT。
使用 nano 文本编辑器打开自定义规则文件:
nano ~/project/rules/local.rules
将以下行添加到文件中:
alert tcp any any -> any 80 (msg:"Basic SQL Injection Detected"; content:"UNION%20SELECT"; sid:1000001; rev:1;)
让我们解析一下这条规则的含义:
alert:规则匹配时采取的动作(生成警报)。tcp:要检查的协议。any any -> any 80:源 IP 和端口(任意)发往目的 IP(任意)的 80 端口。msg:"...":向分析师显示的警报消息。content:"UNION%20SELECT":Snort 将在数据包载荷中搜索的确切字符串。sid:1000001:Snort ID。自定义规则的 ID 应为 1,000,000 或更高。rev:1:规则的修订版本号。
添加该行后,按 Ctrl+O、Enter,然后按 Ctrl+X 保存文件并退出 nano。
你可以使用 cat 命令验证规则文件的内容:
cat ~/project/rules/local.rules
配置 PCRE(正则表达式)
在这一步中,你将通过使用 PCRE(Perl 兼容正则表达式)来增强你的检测能力。
正则表达式增加了灵活性,因为它们描述的是一系列模式,而不是单一的确切字节序列。这虽然强大,但也增加了过度匹配的风险。当攻击者可能改变格式但仍保持底层行为可识别时,防御者会使用 PCRE。
虽然 content 关键字快速且有效,但它非常死板。攻击者经常试图通过稍微改变载荷来逃避检测。例如,攻击者可能使用普通空格(``)、多个空格或加号(+)来代替 %20(URL 编码的空格)。简单的 content 匹配会漏掉这些变体。
PCRE 允许你编写灵活的模式。我们将编写第二条规则,使用正则表达式来捕获 UNION SELECT 攻击的变体。
再次打开你的规则文件:
nano ~/project/rules/local.rules
在第一条规则下方的新行中添加以下新规则:
alert tcp any any -> any 80 (msg:"Advanced SQL Injection Detected"; pcre:"/UNION(%20|\s|\+)SELECT/i"; sid:1000002; rev:1;)
让我们解析一下 pcre 选项:
pcre:"/ ... /i":斜杠表示正则表达式的开始和结束。末尾的i表示搜索不区分大小写(它将匹配union、UNION、UnIoN等)。UNION:匹配单词 UNION。(%20|\s|\+):这是一个带有 OR 逻辑(|)的捕获组。它匹配%20、空白字符(\s)或加号(\+)。SELECT:匹配单词 SELECT。
保存文件并退出 nano(Ctrl+O、Enter、Ctrl+X)。
现在,你的 local.rules 文件应该包含两条旨在捕获 SQL 注入尝试的不同规则。
验证规则检测
在最后一步中,你将测试你的自定义规则。你将以离线模式运行 Snort,指示它读取 sqli_attack.pcap 文件并应用你在 local.rules 中编写的规则。
针对已知样本进行测试至关重要,因为纸面上看起来正确的规则在操作中可能会失败。验证可以确认规则确实在你预期的流量上触发,这是在生产环境中信任该规则之前的最低要求。
Snort 可以使用各种标志运行。我们将使用以下标志:
-q:静默模式。这会抑制大量的横幅和初始化文本,使输出更易于阅读。-c:指定要使用的配置文件或规则文件。-r:指定要读取的 PCAP 文件。-A console:告诉 Snort 将警报直接打印到终端控制台。
运行以下命令来针对恶意载荷测试你的规则:
sudo snort -q -c rules/local.rules -r sqli_attack.pcap -A console
如果你的规则编写正确,你应该会看到类似以下的输出:
10/23-10:23:45.123456 [**] [1:1000001:1] Basic SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
10/23-10:23:45.123456 [**] [1:1000002:1] Advanced SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
恭喜!你的两条规则都成功触发了。第一条规则匹配了确切的字符串,第二条规则使用正则表达式匹配了模式。你已经成功扮演了安全分析师的角色,识别了威胁并部署了特征码来检测它。
总结
在本实验中,你通过编写自定义 Snort 规则获得了网络入侵检测的实践经验。你首先分析了原始数据包捕获,以识别 SQL 注入攻击的特定特征。然后,你学习了如何将该特征转化为基本的内容匹配 Snort 规则。最后,你通过实现 Perl 兼容正则表达式(PCRE)来捕获攻击变体,从而升级了检测能力,并通过针对恶意流量运行 Snort 成功验证了你的规则。这些技能对于任何负责保护网络基础设施的网络安全专业人员来说都是基础。



