deaconsec/suricata-detection-lab

GitHub: deaconsec/suricata-detection-lab

基于 pfSense 分段网络和 Suricata 构建的跨网段 IDS 实验室,演示了从攻击检测到自定义规则工程的完整蓝队实践流程。

Stars: 0 | Forks: 0

# Suricata 检测实验室 - 基于 pfSense 的跨网段 IDS 在现有的分段 pfSense 实验室中构建基于网络的入侵检测链路。脆弱的 Web 服务 (DVWA) 受到来自不受信任网段的攻击;Suricata 会检查跨网段流量。文中记录了三个检测案例,以及通过编写自定义规则独立修复检测漏洞的过程。 本实验室建立在 [`network-segmentation-pfsense`](#) 的基础之上,并补充了防御/蓝队方面的内容:不仅是分段隔离,还实现了检测。 ## 结果! - **在现有网络分段基础上构建了可正常运行的跨网段检测流水线** - **记录了三个检测案例:侦察 (nmap)、漏洞扫描 (nikto)、SQLi 攻击 (sqlmap)** - **独立诊断出的检测漏洞(ET Open 与具体的 UNION-SELECT 特征之间的覆盖缺失)** - **编写、调试并验证了自定义的 Suricata 规则签名** ## 拓扑结构 所有组件均虚拟化运行在同一宿主机上 (KVM/QEMU),pfSense 作为一台配有四个 libvirt 网络的虚拟机运行。 | 网段 | 子网 | 角色 | |------------|------------------|----------------------------------------------| | GUEST | 10.10.20.0/24 | 攻击者 (Kali, 10.10.20.100) | | PRODUCTION | 10.10.40.0/24 | 目标 (Ubuntu Server + DVWA, 10.10.40.100) | | MGMT | 10.10.50.0/24 | 管理 | Suricata 以 **IDS 模式**(仅告警,不阻断)运行在 **PRODUCTION 接口** (vtnet3) 上。 原因:需要监控的是受保护的区域,而非攻击源。从 GUEST 到 PRODUCTION 的攻击流量必然经过 pfSense,并在该处接受检查。 ## 架构搭建 ### 1. 防火墙 - 在保持默认拒绝原则的前提下设定严格放行例外 攻击路径仅需一条穿过网段边界的通道。我们没有将 GUEST 对 PRODUCTION 的访问权限完全敞开,而是设定了最小化的放行例外: 仅限单一主机、单一端口。 ![防火墙规则:源 = 特定的 GUEST 主机,目标 = DVWA,仅开放 80 端口](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/2ecf02f64e012700.png) - **放行 (Pass):** GUEST 主机 10.10.20.100 → 10.10.40.100,**仅限 TCP/80** - 网段之间其余的 Implicit Deny 规则保持不变。 - 注意规则顺序(首条匹配优先生效):放行规则必须位于**现有**的阻止规则**之上**,否则会优先触发阻断。 ![GUEST 规则:位于阻止规则之上的严格放行规则](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5bfd587d95012701.png) 此外,还对 PRODUCTION 的出站流量进行了安全加固(此前该网段处于完全的 Default-Deny 状态,无法访问互联网): - **阻断 (Block):** PRODUCTION → GUEST 以及 PRODUCTION → MGMT(防止 Lateral Movement) - **放行 (Pass):** PRODUCTION → any(受控的互联网访问,用于拉取软件包/镜像) 规则构建逻辑:将用于阻止 Lateral Movement 的 Block 规则放置在宽泛的互联网 Pass 规则之前。不受欢迎的内部目标会在触发放行规则之前被拦截。这体现了“防止 Lateral Movement”的原则。 ![PRODUCTION 规则:优先阻断至 GUEST/MGMT 的 Lateral Movement,然后放行互联网访问](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/ade272c3ec012703.png) ### 2. 脆弱的目标主机 位于 PRODUCTION 网段的 Ubuntu Server (10.10.40.100,由 pfSense 通过 DHCP 分配)。 ![PRODUCTION 网段中的虚拟机:enp1s0 网卡 IP 为 10.10.40.100,默认网关为 10.10.40.1](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/41cd94d214012704.png) DVWA 作为 Docker 容器运行,方便复现且可随时销毁重建。端口映射 `-p 80:80` 使得 DVWA 可以在 10.10.40.100:80 上被访问,这正是防火墙放行例外所针对的地址: ``` sudo docker run -d -p 80:80 --name dvwa vulnerables/web-dvwa ``` ![DVWA 容器运行中,映射了 80 端口](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/ff17ae0bc7012705.png) 从 Kali 确认了连通性,跨网段访问正常工作: ![从 Kali (GUEST 网段) 跨越网段边界成功访问 DVWA 登录页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/bb975d08fd012706.png) ### 3. Suricata 在 pfSense 上安装组件,选用接口 PRODUCTION,运行模式为 IDS。 ![Suricata 安装完成](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/b45ecbf36b012708.png) 规则集:**ET Open** (Emerging Threats Open)。pfSense 本身也提示,其覆盖范围不如 ETPro 广。这一点在后续操作中变得尤为关键: ![选择 ET Open(覆盖范围不及 ETPro)](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/3d9a235530012709.png) ![ET Open 规则集下载成功](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5c6c5e1108012711.png) 由于使用的是虚拟网卡,我们禁用了 Hardware Offloading (Checksum/TSO/LRO),否则 Suricata 会观察到不完整的数据包。接口已正常运行,Blocking 已被禁用(纯 IDS 模式): ![PRODUCTION 运行中,Blocking 已禁用](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/3424d78c7f012712.png) ## 检测案例 ### 案例 1 - 侦察 (nmap) 完整的扫描起初被防火墙拦截。nmap 的主机发现机制 发被最小权限规则(仅允许 TCP/80)阻断,对目标的 Ping 请求没有响应,因此主机显示为“宕机 (down)”。 ![对 DVWA 的 Ping 失败 - 网络分段生效](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/6fa3733e33012713.png) ![nmap 报告 "Host seems down" - 主机发现被拦截](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5afc1f0775012715.png) 使用 `-Pn` 跳过主机发现,`-p80` 针对被允许的端口,扫描得以通过并成功识别出 Apache 2.4.25: ![nmap -sV -Pn -p80:主机存活,80/http 端口开放](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/802f71a519012716.png) Suricata 告警:**`1:2024364 ET SCAN Possible Nmap User-Agent Observed`** (属于 `emerging-scan.rules` 类别)。该规则匹配 `http.user_agent` 中的 `content:"|20|Nmap"` - 即检测发生在 Layer 7,基于 HTTP 探测的 User-Agent 进行识别,而不是依赖传统的端口扫描启发式算法。这就是为什么即使是单端口扫描也能被检测到的根本原因。 ![Suricata 告警:ET SCAN Possible Nmap User-Agent,SID 2024364](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/efa2964a8a012717.png) ### 案例 2 - Web 漏洞扫描器 (nikto) ``` nikto -h http://10.10.40.100 ``` ![针对 DVWA 运行的 nikto 扫描](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/732c868f9f012719.png) 在三个类别中产生了广泛的告警: - **Web-Attack (Pri 1):** 针对 ColdFusion、WordPress 插件的探测 (ET WEB_SERVER / WEB_SPECIFIC_APPS)。注意:DVWA 并未运行这些软件 - Suricata 是针对流量中的*尝试行为*进行告警,与目标处是否攻击成功无关。 - **协议异常 (Pri 3):** SURICATA 自带的引擎识别出错误的 HTTP 请求(模糊/无效的 Host header)。 - **Info (Pri 3):** Spring-Boot-Actuator 探测。 SOC 分析定性:这不是一次针对性的单点攻击,而是一个在几秒钟内发射大量 Web 探测的源 = 自动化扫描器。这些事件通过告警关联被归纳为单一的安全事件。 ![nikto 告警:Web-Attack,协议异常,Info](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/962e6daab5012720.png) ### 案例 3 - 针对性 SQL 注入 (sqlmap) ``` sqlmap -u "http://10.10.40.100/vulnerabilities/sqli/?id=1&Submit=Submit" --cookie="PHPSESSID=; security=low" --batch --dbs ``` `id` 参数可以通过四种技术进行注入(布尔盲注、报错注入、时间盲注、UNION query);后端数据库、Web 服务器 (Apache 2.4.25) 和操作系统 (Debian 9) 信息均被成功读取。sqlmap 在启发式扫描中还报告该参数可能存在 XSS 漏洞。由于重点关注的是 SQLi 检测,此处未对该发现做进一步深入。 ![sqlmap:id 参数可注入,技术栈信息被读取](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/a70e77376a012722.png) ## 检测漏洞与自定义规则 **现象:** 成功的 sqlmap 攻击(包含 SQLi payload 的 146 个 HTTP 请求)**未**产生任何 SQL 注入告警,尽管 Suricata 能够看到这些流量(同时进行的 nmap 依然触发了告警 - 证明流水线完好)。 **原因:** 当前激活的 ET Open 规则中,没有任何一条能匹配这种具体的攻击模式: - `emerging-sql` 规则针对的是**直接的数据库流量**(`$SQL_SERVERS`,端口 1433/3306)- 而不是针对 80 端口 HTTP 参数中的 SQLi。 ![emerging-sql:规则针对数据库端口 1433/3306,而非 HTTP](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/a4aad7b43c012724.png) - 虽然也存在一些通用的 SQLi Web 规则(`ET WEB_SERVER SQLi`,`ATTACKER SQLi`),但它们匹配的是其他模式(如 `SELECT and sysobject`,`Schema Columns`),或者部分在默认情况下处于禁用状态 - 没有一条规则能够捕获 HTTP URI 中具体的 `UNION SELECT` 字符串。 ![通用 SQLi Web 规则:匹配其他模式,部分已禁用](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e4c6731b14012725.png) 这是开源规则集在面对通用 Web SQLi 时存在的真实覆盖盲区(ET Open 自身也提示了其覆盖范围受限),并非配置错误。 ![sqlmap 执行后空白的告警日志 - 攻击发生了,但没有规则被触发](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/4b84bcb48a012726.png) **解决方案 - 编写自定义签名** (`custom.rules`): ``` alert http any any -> $HOME_NET any (msg:"LOCAL SQLi UNION SELECT detected in HTTP request"; flow:established,to_server; http.uri; content:"UNION"; nocase; content:"SELECT"; nocase; distance:0; classtype:web-application-attack; sid:1000001; rev:1;) ``` 逻辑分析:如果发往 `$HOME_NET` 的已建立 HTTP 请求中,URI 包含紧跟 `SELECT` 的 `UNION`(不区分大小写,`distance:0` 允许匹配 `UNION ALL SELECT`),则触发告警。这种特征模式在合法请求中几乎不存在 → 因此误报率极低。SID 设定为 1000001(本地规则范围 ≥ 1000000)。 ![PRODU 规则输入框中的自定义规则](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/c03cffa3f5012728.png) **调试:** 规则的第一版未能加载。排查步骤如下: 1. 使用保证可被读取的 payload 进行 curl 测试,排除了编码问题的可能。 2. 启动日志 (`suricata.log`) 显示了两个解析错误:将方向操作符错写成了 `>` 而不是 `->`,以及 `msg` 字段后漏掉了冒号 `:`。 3. 修复后,规则顺利加载(错误日志行消失) ![启动日志中的解析错误:">" 不是有效的方向操作符](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/027239be80012729.png) **验证:** 使用保证可被明文读取的 payload: ``` curl "http://10.10.40.100/vulnerabilities/sqli/?id=1+UNION+SELECT+1,2&Submit=Submit" --cookie "PHPSESSID=; security=low" ``` ![在 URI 中包含可读 UNION SELECT 的 curl 测试](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/abfeb7cd67012730.png) **结果:** 自定义签名可靠地触发了告警 - **`1:1000001 LOCAL SQLi UNION SELECT detected in HTTP request`**: ![自定义规则触发:SID 1:1000001](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/9a910fc673012732.png) ![自定义规则触发:SID 1:1000001,第二部分](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e879ac47c2012733.png) **规则的局限性(已知):** 它仅涵盖了 UNION 注入这种变体。 报错注入(`EXTRACTVALUE`)、时间盲注(`SLEEP`)和布尔盲注(`OR NOT ...`)并不包含 `UNION SELECT`,因此需要编写其他的自定义签名。我们优先考虑编写命中率精确的规则,而不是包含过多判断条件、容易导致误报的臃肿规则。 ## 技术侧重点 - 防火墙(pfSense,最小权限规则,Lateral-Movement 阻断)· - IPS/IDS(Suricata,接口布局选择,规则分类)· - Detection Engineering(签名构建,自定义规则,通过日志排错)· - 同一核心逻辑中体现的攻防双重视角
标签:CISA项目, DOE合作, Metaprompt, pfSense, Suricata, 插件系统, 现代安全运营, 网络安全, 网络流量分析, 虚拟化实验环境, 请求拦截, 隐私保护