sanjishkc/wazuh-soc-home-lab

GitHub: sanjishkc/wazuh-soc-home-lab

一个基于 Wazuh 的自建 SOC 实战实验室,完整演示了 SIEM 部署、攻击模拟、告警分类、检测规则编写与误报调优等蓝队核心技能。

Stars: 0 | Forks: 0

# Wazuh SOC 家庭实验室:SIEM、检测工程与告警分类 ![状态](https://img.shields.io/badge/status-complete-brightgreen) ![Wazuh](https://img.shields.io/badge/Wazuh-4.14.6-005792) ![操作系统](https://img.shields.io/badge/Guest-Ubuntu%20Server%2024.04%20LTS-E95420) ![终端](https://img.shields.io/badge/Endpoint-Windows%2011%20%2B%20Sysmon-0078D6) ![框架](https://img.shields.io/badge/mapped%20to-MITRE%20ATT%26CK-red) ![关注点](https://img.shields.io/badge/focus-Blue%20Team%20%2F%20SOC-1f6feb) **作者:** Sanjish KC · **仓库:** `github.com/sanjishkc/wazuh-soc-home-lab` ## 架构 ![架构图](https://static.pigsec.cn/wp-content/uploads/repos/cas/3c/3c722c32fdf3847c3fde6cf9de6ae60e42f7d499e5cb5e7dbb0fc845ba7d2215.png) 为了适应有限的硬件条件,我采用了单虚拟机设计。只有 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 的坑:必须将网络设置切换到“专家模式”后,第二个网络适配器才会出现。 ![Ubuntu Server 安装](https://static.pigsec.cn/wp-content/uploads/repos/cas/48/489c2d0ccae34b8b4d971f40929cb28e898ade36ad99e1326ca0f7a616e0bbdc.png) ![Ubuntu 首次启动](https://static.pigsec.cn/wp-content/uploads/repos/cas/c4/c4f07fdde130fefcdcabd6e5b3020ff020deda8b1a6cf4ead3ffb46c020ef690.png) ### 2. 低 RAM 的安全保障:swap 在安装 Wazuh 之前,我添加了一个 swap 文件,以防止内存峰值触发 OOM(内存耗尽)杀手。 ![Wazuh 安装前配置的 Swap](https://static.pigsec.cn/wp-content/uploads/repos/cas/51/51807256a752949f541981d9ad4e76ddb4f4c1d4ce85115c3c7cbad4abfbabe5.png) ### 3. Wazuh 安装(辅助一体化) ``` curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh && sudo bash ./wazuh-install.sh -a ``` ![Wazuh 正在安装](https://static.pigsec.cn/wp-content/uploads/repos/cas/38/38fef14f428076b9fa8562e12c1ba9ee88b18402289f6745bf836b2ddde05c54.png) Indexer、manager 和 Filebeat 顺利安装完毕。Dashboard 步骤反复失败,这成了下文单独讲述的故事。修复根本原因后,安装顺利完成: ![Wazuh 安装成功完成](https://static.pigsec.cn/wp-content/uploads/repos/cas/ea/ea6d4eebf7f8f30430719c9cef2b46ad69566e84692ca53a76258ae6dfad7d0a.png) 可以通过 Host-Only 网络在 `https://192.168.56.102` 访问 Dashboard。请注意,它是通过 443 端口提供的 HTTPS,而不是 HTTP。 ![Wazuh dashboard 登录](https://static.pigsec.cn/wp-content/uploads/repos/cas/dd/dd040f77ebd314953bdabbfb18d23e447524f5e69aa95c3be40d6e33caac08ea.png) ![Dashboard 概览,尚无 agent](https://static.pigsec.cn/wp-content/uploads/repos/cas/ba/ba3b12940e675a7085cd88ea766607ccb44176b2d6aed8ef17fa78076f119f5d.png) ### 4. 接入 Windows 终端和 Sysmon 我将 Wazuh agent 部署到了 Windows 主机上,并指向 manager 的 Host-Only IP。接着,我使用 SwiftOnSecurity 配置安装了 Sysmon,并添加了一个 `` 块,以便 Wazuh 能接入 `Microsoft-Windows-Sysmon/Operational` 频道的数据。Sysmon 的命令行可见性是让后续检测变得有用的关键,因为它记录了运行的确切命令。 ## 排障纪实:无法安装的 Dashboard Wazuh dashboard 安装失败了四次,每次都导致整个技术栈回滚。这是这个项目中最让我庆幸自己做了记录的部分,因为它展示了我处理问题的方法,而不是靠瞎猜。 ![Dashboard 安装失败](https://static.pigsec.cn/wp-content/uploads/repos/cas/00/0058b8e783c1fd1fcc579cfc248867e2b2d35f7a2e5f79c722422d0461d3f90c.png) 我最初的理论是内存问题。我推测是 dashboard 构建步骤耗尽了内存从而被系统 OOM-kill 了,所以我添加了 swap,将 VM 内存从 4 GB 提升到了 5 GB,最终把笔记本电脑升级到了 16 GB 并给 VM 分配了 8 GB。它仍然在同一步骤失败。这排除了内存因素。 ![安装错误再次出现](https://static.pigsec.cn/wp-content/uploads/repos/cas/1f/1f6adb34521bd029c7c50f1968ca8262cfa43bd66f50b95fd0dca81525ffe5ae.png) 所以我停止了猜测,开始查看日志: ``` 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) ``` ![设备上没有剩余空间](https://static.pigsec.cn/wp-content/uploads/repos/cas/4b/4b22c217524a9d981036bb13b97c71f07dc720db941cb830a8cea4d0d6a066b0.png) 根本原因是 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 的安全机制失去了同步。 ![API 连接错误](https://static.pigsec.cn/wp-content/uploads/repos/cas/0f/0f3dfc36c0feb0b86102a261421c07fbc7c207bc5cea73e79925b11e772f6c9c.png) 解决办法是按顺序重启整个技术栈: ``` 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 ``` ![FIM:文件被添加、修改、删除](https://static.pigsec.cn/wp-content/uploads/repos/cas/90/90e62c5eeac72a1456e2eda2da1a4a37d95cce74be810263d5eac4caa7a06c30.png) | 事件 | 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 进程创建事件。 ![捕获到用户创建告警](https://static.pigsec.cn/wp-content/uploads/repos/cas/aa/aaabb4c82e6cca88ba6322384f81817c31cefc3f8a967cce7d1674b6830e785b.png) 需要升级处理的是 `rule.id 60154`,即来自 Windows 事件 4732 的“Administrators Group Changed”(级别 12)。我们将其抽丝剥茧,看看是谁对谁做了什么: - 操作主体 (谁):`LENOVO`,即执行操作的账户 - 目标 (什么):`Administrators` 组,`targetSid S-1-5-32-544`,这是每台 Windows 机器上内置的本地管理员 SID - `firedtimes: 2`,因为它同时捕获了添加 (4732) 和随后的清理删除 (4733) 操作 ![检测 1:规则 ID、MITRE、事件 ID 详情](https://static.pigsec.cn/wp-content/uploads/repos/cas/dc/dcafb44bb4a0a956bdb7e4367598fee977dd0980f5563cffbeda444a30f978ed.png) 关于检测工程的一个观察。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 ``` ![编码的 PowerShell 命令](https://static.pigsec.cn/wp-content/uploads/repos/cas/df/df986db1de550b99e209f9a15a2f0732a4be937a3e7537f94dac658d60f421fb.png) Wazuh 开箱即用地在 12 级捕获到了它,`rule.id 92057`:“Powershell.exe spawned a powershell process which executed a base64 encoded command.”。 ![Wazuh 中的编码 PowerShell 告警](https://static.pigsec.cn/wp-content/uploads/repos/cas/a7/a716f8075f4c31725ab685106af2edb66b52655c98e69c9e0d5d18e312c62948.png) 接下来是分析师的操作:解码 payload。攻击者的 `-EncodedCommand` 隐藏了他们实际运行的内容,因此我将其解码以其意图: ``` [System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('')) ``` ![在日志中发现的已解码 payload](https://static.pigsec.cn/wp-content/uploads/repos/cas/39/39a2d46ef0e5d61b2e0b56439223eb106209e2f1386c8ff42e3061819fb6196c.png) 在真实的突发事件中,这一步可以揭示恶意软件的真实命令,无论那是一个下载 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 ``` ![local_rules.xml 中的自定义规则 100100](https://static.pigsec.cn/wp-content/uploads/repos/cas/a1/a19aa8703ebaba2d37f93b611d04b144d7f7e2112aaf646660456a6d2d36e564.png) 为了证明它填补了漏洞,我从 `cmd.exe` 启动了 `powershell.exe -nop -w hidden -enc `,这正是内置规则 92057 会遗漏的场景(错误的父进程,外加 `-enc` 缩写)。规则 `100100` 在 12 级触发了告警,而 92057 却毫无反应。 ![自定义规则 100100 触发](https://static.pigsec.cn/wp-content/uploads/repos/cas/dc/dc2513e3809d704f19c55cb078074c789d58268e4725a8a567e064614787b578.png) 如果我在面试中如何描述它: ## 检测工程:误报调优 根据数量和严重程度对告警进行排序后,我发现了一些值得深究的问题。级别 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] ``` ![添加用于调优误报的本地规则](https://static.pigsec.cn/wp-content/uploads/repos/cas/a7/a73c9ddf829c852fb2dff35919e9d49bb404decfc800fec737aa0480aa1b6534.png) 我双向进行了验证。调优后,PowerShell 自检不再产生告警,但将一个真实的 `ero-virus.bat` 植入 Temp 目录仍然会触发 92213(级别 15)。现在噪音已经消失,而信号保持完好。 ![误报被静默,真实植入仍被检测](https://static.pigsec.cn/wp-content/uploads/repos/cas/c5/c5a97e4e7538433c19d7747b8381a6d6223084e94d53284499b4811c13919109.png) 级别 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, 告警分诊