sanjishkc/wazuh-soc-home-lab
GitHub: sanjishkc/wazuh-soc-home-lab
一个基于 Wazuh 的自建 SOC 实战实验室,完整演示了 SIEM 部署、攻击模拟、告警分类、检测规则编写与误报调优等蓝队核心技能。
Stars: 0 | Forks: 0
# Wazuh SOC 家庭实验室:SIEM、检测工程与告警分类






**作者:** Sanjish KC · **仓库:** `github.com/sanjishkc/wazuh-soc-home-lab`
## 架构

为了适应有限的硬件条件,我采用了单虚拟机设计。只有 Wazuh server 运行在 VM 中,而 Windows 主机本身通过一个轻量级 agent 作为受监控的终端。两者通过隔离的 Host-Only 网络进行通信,因此没有任何实验室流量会离开这台机器。配置 NAT 仅仅是为了让 VM 能够下载软件包。
## 目录
1. [概述](#overview)
2. [展示技能](#skills-demonstrated)
3. [环境与工具](#environment--tooling)
4. [搭建步骤](#build-walkthrough)
5. [排障纪实:无法安装的 Dashboard](#troubleshooting-story-the-dashboard-that-wouldnt-install)
6. [文件完整性监控](#file-integrity-monitoring)
7. [检测 1:新建本地管理员账户 (T1136)](#detection-1-new-local-admin-account-t1136)
8. [检测 2:编码的 PowerShell (T1059.001)](#detection-2-encoded-powershell-t1059001)
9. [检测工程:自定义规则](#detection-engineering-custom-rule)
10. [检测工程:误报调优](#detection-engineering-false-positive-tuning)
11. [经验总结](#lessons-learned)
12. [仓库结构](#repository-structure)
13. [复现指南](#reproduce-it)
14. [参考资料](#references)
## 概述
本项目搭建了一个可运行的 SOC 环境,并完成了 SOC 分析师的日常工作:生成安全遥测数据,检测模拟攻击,将每次检测映射到 MITRE ATT&CK 框架,以及阅读、编写和调优检测规则。
我在普通的硬件上完成了它(一台 8 GB 内存的笔记本电脑,后来升级到了 16 GB)。这个限制是这段经历的一部分,我并没有将其隐瞒。它迫使我采用单 VM 设计,并在某个时刻导致磁盘空间耗尽的故障,而我不得不通过日志进行诊断并修复。
我在本次搭建中完成的工作:
- 在 VM 上部署了完整的 Wazuh 技术栈(manager、indexer、dashboard),并在一次安装失败后将其成功恢复。
- 将 Windows 主机接入为 agent,并利用 Sysmon 和 FIM(文件完整性监控)丰富了其遥测数据。
- 模拟了两次攻击,随后对告警进行了分类排查,搞清了“谁对谁做了什么”,并解码了一个混淆的 PowerShell payload。
- 阅读了一条内置检测规则,发现了其遗漏的场景,并编写了一条自定义规则来覆盖它。
- 调查了一项严重级别告警,确认其为误报,并在未屏蔽真实威胁的情况下对其进行了调优消除。
- 详细记录了每一次故障及其修复过程。
## 展示技能
| 领域 | 本项目中的证明 |
|---|---|
| SIEM 部署与运维 | Wazuh 一体化安装,服务管理,重启后恢复 |
| 终端接入 | Windows 上的 Wazuh agent,通过 Host-Only 网络进行 agent 注册 |
| 遥测数据丰富 | Sysmon(SwiftOnSecurity config),文件完整性监控 |
| 告警分类 | 将告警梳理为操作主体/目标/SID;根据严重程度进行升级判断 |
| 威胁检测 | 新建管理员账户 (T1136),编码的 PowerShell (T1059.001) |
| 检测工程 | 自定义规则 `100100`,捕获内置 `92057` 遗漏的场景 |
| 告警调优 | 对关键规则 `92213` 进行精准的误报抑制 |
| Payload 分析 | 解码 base64 `-EncodedCommand` 以揭示其意图 |
| MITRE ATT&CK 映射 | 在每次检测中标记相关技术 |
| Linux / 基础设施排障 | LVM 磁盘扩容,修复损坏的 dpkg,修复服务 auth-sync |
## 环境与工具
| 项目 | 选择 | 备注 |
|---|---|---|
| Hypervisor | Oracle VirtualBox 7.2 | 支持快照以便安全回滚 |
| Guest OS | Ubuntu Server 24.04.4 LTS | Server 版(无 GUI);受 Wazuh 4.14 支持 |
| SIEM | Wazuh 4.14.6 (辅助一体化安装) | Manager、indexer 和 dashboard |
| 终端 | Windows 11 主机 (16 GB RAM) | 通过 Wazuh agent 监控 (id 001) |
| 终端遥测 | Sysmon + SwiftOnSecurity config | 提供进程、命令行、文件和注册表可见性 |
| 服务器 VM | 8 GB RAM,2 vCPU,54 GB 磁盘 | 根据一体化技术栈的需求配置 |
| 网络 | NAT + Host-only (`192.168.56.0/24`) | NAT 用于联网下载;Host-Only 用于包含的主机到 VM 链路 |
## 搭建步骤
### 1. Ubuntu Server 虚拟机
我在 VirtualBox 中创建了一个 Ubuntu Server 24.04 VM,它配备了两个网络适配器:NAT 用于下载,Host-Only 用于包含的主机到 VM 链接。我在这里遇到了一个 VirtualBox 7.2 的坑:必须将网络设置切换到“专家模式”后,第二个网络适配器才会出现。


### 2. 低 RAM 的安全保障:swap
在安装 Wazuh 之前,我添加了一个 swap 文件,以防止内存峰值触发 OOM(内存耗尽)杀手。

### 3. Wazuh 安装(辅助一体化)
```
curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh && sudo bash ./wazuh-install.sh -a
```

Indexer、manager 和 Filebeat 顺利安装完毕。Dashboard 步骤反复失败,这成了下文单独讲述的故事。修复根本原因后,安装顺利完成:

可以通过 Host-Only 网络在 `https://192.168.56.102` 访问 Dashboard。请注意,它是通过 443 端口提供的 HTTPS,而不是 HTTP。


### 4. 接入 Windows 终端和 Sysmon
我将 Wazuh agent 部署到了 Windows 主机上,并指向 manager 的 Host-Only IP。接着,我使用 SwiftOnSecurity 配置安装了 Sysmon,并添加了一个 `` 块,以便 Wazuh 能接入 `Microsoft-Windows-Sysmon/Operational` 频道的数据。Sysmon 的命令行可见性是让后续检测变得有用的关键,因为它记录了运行的确切命令。
## 排障纪实:无法安装的 Dashboard
Wazuh dashboard 安装失败了四次,每次都导致整个技术栈回滚。这是这个项目中最让我庆幸自己做了记录的部分,因为它展示了我处理问题的方法,而不是靠瞎猜。

我最初的理论是内存问题。我推测是 dashboard 构建步骤耗尽了内存从而被系统 OOM-kill 了,所以我添加了 swap,将 VM 内存从 4 GB 提升到了 5 GB,最终把笔记本电脑升级到了 16 GB 并给 VM 分配了 8 GB。它仍然在同一步骤失败。这排除了内存因素。

所以我停止了猜测,开始查看日志:
```
sudo grep -iE "error|fail|no space|killed" /var/log/wazuh-install.log | tail -40
```
真正的错误就在那里摆着:
```
E: Write error - write (28: No space left on device)
```

根本原因是 Ubuntu LVM 默认的“只用一半磁盘”机制。引导式安装只为根文件系统分配了 50 GB 磁盘中的约 27 GB,剩余的未分配空间留在了卷组中:
```
df -h / # root only 27G, filling during install
sudo vgs # VSize 54G, VFree 27G <-- half the disk unallocated
```
修复只需两条命令。先扩展逻辑卷,然后再扩展其中的文件系统:
```
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv # grow the logical volume
sudo resize2fs /dev/ubuntu-vg/ubuntu-lv # grow the ext4 filesystem
df -h / # now 54G, 43G free
```
还有第二个障碍。之前失败的安装留下了一个被卸载了一半的 `wazuh-manager` 包,其卸载脚本会报错;此外还有一些孤儿进程仍然占用着 1515 和 55000 端口。我手动清理了它们:
```
sudo pkill -9 -f wazuh
sudo rm -f /var/lib/dpkg/info/wazuh-manager.prerm /var/lib/dpkg/info/wazuh-manager.postrm
sudo dpkg --purge --force-all wazuh-manager
sudo rm -rf /var/ossec
```
清理完毕后,重新运行顺利成功。我从中得到的教训是:在动手之前先看日志。我曾在内存理论上花费了时间(以及购买内存的钱),而真正的问题却是 Ubuntu 默认 LVM 布局导致的磁盘空间不足。
重启后又出现了一个问题。Dashboard 报告 `[API connection] No API available to connect`,接着是一个 auth-token 错误。仅仅重启 manager 导致其 API 与 indexer 的安全机制失去了同步。

解决办法是按顺序重启整个技术栈:
```
sudo systemctl restart wazuh-indexer # (wait ~60s)
sudo systemctl restart wazuh-manager # (wait ~30s)
sudo systemctl restart wazuh-dashboard
```
## 文件完整性监控
我在 agent 配置中添加了对 `C:\test` 目录的实时 FIM 监控,然后创建、修改并删除了一个文件。这三个事件均被触发,并生成了文件哈希和内容差异对比。
```
C:\test
```

| 事件 | Wazuh 规则 |
|---|---|
| 文件已添加 | 554 |
| 文件已修改 | 550 |
| 文件已删除 | 553 |
一条值得记录的调注意事项:Wazuh 的 `` 是全局性的,没有针对特定目录的选项。默认针对 `.log/.htm/.jpg/...` 的 `sregex` 忽略规则,在静默状态下抑制了被监控文件夹中的 `.log` 文件。这提醒我们,当忽略规则匹配到路径时,“被监控”并不意味着“会被上报”。
## 检测 1:新建本地管理员账户 (T1136)
在主机上运行并随后清理掉的模拟操作:
```
net user hacker Password123 /add
net localgroup administrators hacker /add
net user hacker /delete # cleanup
```
仅仅这一个动作就在两个数据源中产生了一组相关的告警:Windows 安全事件和显示完整命令行的 Sysmon 进程创建事件。

需要升级处理的是 `rule.id 60154`,即来自 Windows 事件 4732 的“Administrators Group Changed”(级别 12)。我们将其抽丝剥茧,看看是谁对谁做了什么:
- 操作主体 (谁):`LENOVO`,即执行操作的账户
- 目标 (什么):`Administrators` 组,`targetSid S-1-5-32-544`,这是每台 Windows 机器上内置的本地管理员 SID
- `firedtimes: 2`,因为它同时捕获了添加 (4732) 和随后的清理删除 (4733) 操作

关于检测工程的一个观察。Wazuh 将此标记为 T1484(域策略修改),这对于本地管理员组的变更来说是不精确的。T1098 或 T1136 会更贴切。内置的规则到 ATT&CK 的映射虽然有用,但并不总是完全准确。
## 检测 2:编码的 PowerShell (T1059.001)
模拟使用了攻击者实际会使用的混淆形式(`-NoProfile -WindowStyle Hidden -EncodedCommand`)包装的无害 payload:
```
$cmd = 'Write-Host "hello from encoded powershell"'
$enc = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($cmd))
powershell.exe -NoProfile -WindowStyle Hidden -EncodedCommand $enc
```

Wazuh 开箱即用地在 12 级捕获到了它,`rule.id 92057`:“Powershell.exe spawned a powershell process which executed a base64 encoded command.”。

接下来是分析师的操作:解码 payload。攻击者的 `-EncodedCommand` 隐藏了他们实际运行的内容,因此我将其解码以其意图:
```
[System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String(''))
```

在真实的突发事件中,这一步可以揭示恶意软件的真实命令,无论那是一个下载 URL、后续执行的 payload,还是其他东西。
## 检测工程:自定义规则
我阅读了捕获到“检测 2”的内置规则 (`92057`),并发现了两个盲点:
1. 它要求 `parentImage = powershell.exe`,因此它遗漏了从 `cmd.exe`、Office 宏或 `wscript.exe` 启动的编码 PowerShell。
2. 它的正则表达式列出了 `en|enco|encode|encodedcommand`,却跳过了 `enc` 和 `encoded`,而这些恰恰是攻击者最常使用的缩写。
我的自定义规则(`rules/local_rules.xml`,id `100100`,级别 12)去除了父进程限制,并填补了缩写遗漏的漏洞:
```
sysmon_event1
(?i)powershell\.exe.+\-\b(encodedcommand|encoded|encode|encod|enco|enc|en|ec|ea|e)\b
Encoded PowerShell executed (any parent process, incl. -enc/-encoded) - possible obfuscation [custom]
T1059.001
```

为了证明它填补了漏洞,我从 `cmd.exe` 启动了 `powershell.exe -nop -w hidden -enc `,这正是内置规则 92057 会遗漏的场景(错误的父进程,外加 `-enc` 缩写)。规则 `100100` 在 12 级触发了告警,而 92057 却毫无反应。

如果我在面试中如何描述它:
## 检测工程:误报调优
根据数量和严重程度对告警进行排序后,我发现了一些值得深究的问题。级别 15(严重)的告警每天大约触发 25 次。严重告警理应是罕见的,所以我对此进行了调查。
它们是 `rule.id 92213`,“Executable file dropped in folder commonly used by malware”(T1105),触发对象类似于这样的文件:
```
C:\Users\...\AppData\Local\Temp\__PSScriptPolicyTest_..ps1
```
这些看起来像随机且不断变化的文件名,几乎就像 DNS 风格的数据外泄,因此我调查得出了结论,而不是仅仅停留在猜测。结果发现这是 PowerShell 自身的执行策略自检:它会向 Temp 目录写入一个一次性的 `.ps1` 文件,运行它以检查策略,然后将其删除。这是由具有签名的系统级 `powershell.exe` 创建的本地文件,没有网络交互,且使用了随机的临时命名。一种良性行为却被规则 92213 宽泛的“Temp 中任何脚本”的启发式逻辑捕获,这使其成为了一个最高级别的误报。
这次调优(`rules/local_rules.xml`,id `100200`,级别 0)仅屏蔽了该自检行为,而保留 92213 对真实文件植入的监控:
```
92213
(?i)__PSScriptPolicyTest_
Benign PowerShell execution-policy self-test in Temp - tuned FP, rule 92213 stays live for real drops [custom]
```

我双向进行了验证。调优后,PowerShell 自检不再产生告警,但将一个真实的 `ero-virus.bat` 植入 Temp 目录仍然会触发 92213(级别 15)。现在噪音已经消失,而信号保持完好。

级别 15 的误报比一百个级别 3 的误报造成的危害更大,因为这会让分析师开始忽略关键告警队列。这就是为什么我通过设定特定条件来进行调优,而不是直接禁用整条规则。
## 经验总结
1. 让架构适应硬件。单 VM 设计使得完整的 SIEM 能够在受限的笔记本电脑上运行。
2. 让操作系统匹配工具。我使用的是 Ubuntu 24.04,而不是最新的 26.04,因为 Wazuh 4.14 支持它。
3. 采取行动前先阅读日志。Dashboard 失败的真正原因是磁盘空间,而不是内存。
4. Ubuntu 的引导式 LVM 安装通常只使用了一半的磁盘。使用 `lvextend` 加上 `resize2fs` 即可回收空间。
5. 要修复损坏的 dpkg 包,需清空其 `prerm` 和 `postrm` 脚本,然后执行强制完全移除。
6. 遇到 API auth-token 错误后,按顺序重启技术栈:先是 indexer,然后是 manager,最后是 dashboard。
7. Sysmon 的 `commandLine` 字段是将“一个进程运行了”转化为真正检测的关键。
8. 在编写或调优规则之前,先阅读内置规则。它的逻辑会向你展示确切的遗漏之处。
9. 使用特定条件(`if_sid` 加上 `field` 匹配再加上 `level 0`)来调优误报,而不是直接禁用一条同时也能捕获真实威胁的规则。
10. 严重的误报是破坏性最大的一种,因为它会让分析师习惯于忽略最高优先级的队列。
## 仓库结构
```
wazuh-soc-home-lab/
├── README.md # this document
├── images/
│ ├── architecture.svg / .png # architecture diagram
│ └── screenshots/ # evidence for every step
├── rules/
│ └── local_rules.xml # custom rule 100100 + FP tune 100200
└── docs/
├── Wazuh-SOC-Home-Lab-Report.pdf # printable version of this document
└── engineering-log.md # detailed log: issue, diagnosis, fix
```
## 复现指南
1. 创建一个带有 NAT 和 Host-Only 适配器的 Ubuntu Server 24.04 VM。扩展 LVM 根目录以使用整个磁盘。
2. `curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh && sudo bash ./wazuh-install.sh -a`
3. 将 Wazuh agent 部署到 Windows 主机上,并指向 manager 的 Host-Only IP。
4. 使用 SwiftOnSecurity config 安装 Sysmon,并将 `Microsoft-Windows-Sysmon/Operational` localfile 块添加到 agent 中。
5. 将 `rules/local_rules.xml` 放入 `/var/ossec/etc/rules/` 并重启 manager。
6. 运行检测 1 和检测 2 的模拟,并确认告警和自定义规则成功触发。
## 参考资料
- [Wazuh 官方文档](https://documentation.wazuh.com/current/) 和 [安装指南](https://documentation.wazuh.com/current/installation-guide/index.html)
- [Sysmon (Sysinternals)](https://learn.microsoft.com/sysinternals/downloads/sysmon) 和 [SwiftOnSecurity sysmon-config](https://github.com/SwiftOnSecurity/sysmon-config)
- [MITRE ATT&CK](https://attack.mitre.org/):T1136, T1059.001, T1105, T1098
- [Wazuh 规则集参考](https://documentation.wazuh.com/current/user-manual/ruleset/index.html)
*由 Sanjish KC 作为实战蓝队 / SOC 作品集项目搭建并记录。每一张截图均来自我个人的实验室。*
标签:OpenCanary, SOC实验室, Sysmon, Wazuh, x64dbg, 告警分诊