VibhavChennamadhava/Active-Directory-SOC-Splunk-Lab
GitHub: VibhavChennamadhava/Active-Directory-SOC-Splunk-Lab
基于 Vultr 云基础设施搭建的端到端 SOC 实验室,利用 Splunk SIEM 检测未授权 RDP 登录并通过 Shuffle SOAR 自动触发 Discord 通知与 Active Directory 账户禁用的闭环响应。
Stars: 0 | Forks: 0
# Active-Directory-SOC-Splunk 实验室







## 概述
本实验端到端模拟了一个小型企业 SOC pipeline:一台承载 Active Directory Domain Services 的 Windows Server 2022 域控、一台加入域的 Windows 测试工作站,以及一台运行 Splunk Enterprise 作为 SIEM 的 Ubuntu 22.04 主机。两台 Windows endpoint 的遥测数据通过 Universal Forwarder 转发到 Splunk,在此由计划内的 correlation search 检测源自企业 IP 范围之外的未经授权成功 RDP 登录(EventCode 4624,Logon Types 7 和 10)。当规则触发时,Splunk 会将 alert payload 转发给 Shuffle SOAR workflow,该 workflow 会通过 Discord webhook 通知分析师,向他们发送包含是/否处置提示的电子邮件,并在确认后通过 LDAP 在 Active Directory 中禁用违规用户。整个环境运行在单个 VPC 内的 Vultr 云基础设施上,使分析师的体验与真实的 SOC 调查保持一致:检测、triage、决策、响应、确认。
## 目标
- 建立一个可运行的 Active Directory 林(`MyDFIR.local`),包含一台域控、一台加入域的工作站和一个测试用户账户
- 使用 Universal Forwarder 在默认 indexer 端口 (9997) 上,将来自两个 endpoint 的 Windows 安全日志遥测集中到 Splunk
- 编写一个 Splunk SPL 检测规则,按 Logon Type 和源 IP 过滤 EventCode 4624,以呈现未经授权的成功 RDP 登录
- 将 Shuffle SOAR workflow 连接到 Splunk webhook,使触发的告警流入自动化 playbook
- 实现分析师参与的闭环响应:Discord 通知、邮件决策、AD 账户禁用、向频道回传确认消息
- 通过 VPC 隔离、Vultr 防火墙组和基于主机的 `ufw` 规则,实践云网络加固
## 架构

| 虚拟机名称 | 角色 | 操作系统 | 公网 IP (Vultr 分配) | 私有 VPC IP |
|---------|------|----|---------------------------|----------------|
| `mydfir-ad-dc01` | Active Directory 域控 | Windows Server 2022 Standard | `216.x.x.136` | `10.22.96.4` |
| `cloud-instance` (测试机) | 加入域的 Windows 工作站 | Windows Server 2022 Standard | `155.x.x.10` | `10.22.96.3` |
| `mydfir-splunk` | Splunk Enterprise SIEM + UF 接收器 | Ubuntu 22.04 LTS | `216.128.x.18` | `10.22.96.5` |
这三台虚拟机均位于多伦多地区的同一个 Vultr VPC 中。虚拟机之间的流量保留在 `10.22.96.0/20` 私有子网内;Vultr 防火墙组控制所有来自公网的入站流量。
## 使用的技术
| 技术 | 版本 | 用途 |
|------------|---------|---------|
| Vultr Cloud | 当前平台 | 为所有三台虚拟机和 VPC 提供底层 IaaS 托管 |
| Windows Server | 2022 Standard | 域控和测试 endpoint 操作系统 |
| Active Directory Domain Services | 内置 (Server 2022) | 身份、身份验证、组策略 |
| Ubuntu Server | 22.04 LTS | Splunk indexer 的主机操作系统 |
| Splunk Enterprise | 9.x (免费试用) | SIEM — 索引、搜索、告警 |
| Splunk Universal Forwarder | 9.x | 将 `WinEventLog:Security` 从 endpoint 发送到 indexer |
| Splunk Add-on for Microsoft Windows | 最新版 | 对 `user`、`Logon_Type`、`Source_Network_Address` 进行字段提取 |
| Shuffle SOAR | 云托管 | 编排平台 — webhook 触发器、分支化 workflow |
| Discord | N/A | 通过传入 webhook 的通知渠道(取代了 Slack) |
| LDAP (通过端口 389) | AD 内置 | Shuffle AD 应用用于禁用账户的通道 |
| `ufw` | 0.36 | Splunk Ubuntu 虚拟机上的基于主机的防火墙 |
## 实验网络设计
该实验建立在位于多伦多地区的单个 Vultr VPC(`10.22.96.0/20`)上。每台虚拟机在部署后都启用了 VPC 成员资格,这迫使系统重启,并为每台主机在私有子网上分配了第二个 NIC。开箱即用的 Windows 主机在第二个 NIC 上启动了 `169.254.x.x` APIPA 地址,而不是预期的 `10.22.96.x` 地址,因此需要在两台 Windows 虚拟机上为 Vultr VPC 适配器手动配置静态 IP、子网掩码和 DNS 指针。
单个 Vultr 防火墙组(`mydfir-ad-project-2.0`)应用于所有三台机器。规则仅根据功能需要逐步添加:
| 端口 / 协议 | 源 | 添加原因 |
|-----------------|--------|--------------|
| TCP 22 (SSH) | 我的公网 IP | 从分析师工作站管理 Ubuntu Splunk 主机 |
| TCP 3389 (MS-RDP) | 我的公网 IP(后来为了告警测试扩大到 `anywhere`) | 管理 Windows 虚拟机,随后故意暴露以生成未经授权的登录遥测 |
| TCP 8000 (Splunk Web) | 我的公网 IP | 从浏览器访问 Splunk Web UI |
| TCP 9997 (Splunk indexer) | VPC 对等节点 | 从两个 Windows endpoint 到 indexer 的 Universal Forwarder 流量 |
| TCP 389 (LDAP) | Shuffle 云出口范围 | Shuffle SOAR 的 Active Directory 应用需要访问 DC 来禁用账户 |
Ubuntu Splunk 主机除了 Vultr 防火墙外,还运行了 `ufw` —— 在流量成功到达 indexer 之前,必须同时开放这两层的端口 8000 (Web UI) 和 9997 (UF 接收器)。
## 检测逻辑
每当账户成功登录时,Windows 都会记录 **EventCode 4624**。对于本实验而言,有趣的插曲在于 Logon Type 字段:
- **Logon Type 10** — RemoteInteractive:典型的 RDP 会话
- **Logon Type 7** — Unlock:之前锁定的 RDP 会话被解锁,这仍然代表机器上的一个交互式会话
对这两种类型进行过滤可以捕获完整的 RDP 风格登录足迹。`Source_Network_Address` 携带原始 IP;空值或 `-` 值是本地登录,为了减少干扰已被剔除。对于“已授权与未授权”的判定,假设企业 IP 范围以 `40.` 开头,因此在演示场景中,任何不以此前缀开头的地址都被视为未授权。
最终搜索计划每分钟运行一次,覆盖过去 60 分钟的数据:
```
index=mydfir-ad EventCode=4624
(Logon_Type=7 OR Logon_Type=10)
Source_Network_Address=*
Source_Network_Address!="-"
Source_Network_Address!=40.*
| stats count by _time, ComputerName, Source_Network_Address, user, Logon_Type
| sort -_time
```
`stats` 行纯粹是为了美观 —— 它将干扰较大的原始事件压缩为分析师进行 triage 实际需要的五个字段。
## SOAR 工作流
```
Splunk alert ──HTTP POST──▶ Shuffle webhook
│
▼
Discord (alert channel)
│
▼
Email user-input node
("Disable this user?")
│
┌───────┴───────┐
YES NO
│ │
▼ ▼
Active Directory (end — no action)
disable user
│
▼
Get user attributes
│
contains "Account disabled"?
│
▼
Discord (confirmation)
"Account has been disabled"
```
逐步说明:
1. Splunk 计划搜索触发,并将其结果 JSON POST 到 Shuffle webhook URI。
2. Shuffle 的 webhook 触发器对 payload 进行标准化;runtime 参数(如 `$exec.result.user`、`$exec.result.Source_Network_Address`、`$exec.result.search_name` 和 `$exec.result._time`)变得可供下游节点使用。
3. Discord HTTP 节点使用频道的传入 webhook URL,将格式化的告警发布到实验 Discord 服务器的 `#alerts` 频道。
4. 用户输入节点向分析师收件箱发送电子邮件,询问*“您想禁用该用户吗?”*,并提供一对 True/False 链接。
5. 如果选择 True,Active Directory 应用将通过 LDAP 进行身份验证(服务器 `10.22.96.4`,端口 389,base DN `CN=Users,DC=MyDFIR,DC=local`),并对告警 payload 中的用户执行 **Disable User** 操作。
6. 随后的 **Get User Attributes** 调用会获取 `userAccountControl`;workflow 根据响应是否包含 `ACCOUNT_DISABLED` 进行分支判断。
7. 如果禁用成功,第二个 Discord 节点将发布确认消息:`Account: 已被禁用。`
## 证据 / 结果
**环境配置**



**Active Directory 配置**




**Splunk SIEM**




**检测和告警**



**SOAR 自动化**




## 挑战与故障排除
**添加 workflow 机器人时 Slack OAuth 返回“Invalid permissions”。** Shuffle Slack 应用在免费 Slack 工作区上的 OAuth 授权步骤持续失败 —— Shuffle 请求的机器人作用域并不都能在我使用的工作区版本上授予。与其去折腾 Slack 工作区管理,不如将通知渠道换成 Discord。Discord 的传入 webhook 是一个单一的 URL,完全不需要 OAuth 握手,因此 Shuffle 中的 HTTP 节点可以直接使用最简单的 `{ "content": "..." }` JSON body 进行发布。整个渠道切换花了大约十分钟。
**Shuffle 云托管的 Active Directory 应用验证失败,报 MD4 哈希类型错误。** 当 AD 节点首次尝试通过 LDAP 绑定到 DC 时,它返回了一个引用 MD4 的 Python `hashlib` 异常 —— Shuffle 云 worker 中的底层 Python runtime 使用的是默认禁用 MD4 的 OpenSSL 版本,而 LDAP NTLM 身份验证路径正好调用了它。解决办法是退回使用管理员凭据直接进行简单绑定,设置 `useSSL=false` 并将 search base 设置为 `CN=Users,DC=MyDFIR,DC=local`。绑定成功了,**Get User Attributes** 调用返回了数据,**Disable User** 也起作用了。彻底的修复方案是运行一个由我控制 Python 镜像的自托管 Shuffle worker。
**VPC NIC 启动时得到的是 `169.254.x.x` APIPA,而不是 `10.22.96.x`。** 在每台 Windows 虚拟机上启用 VPC 并重启后,`ipconfig` 显示新的“Ethernet instance 02”适配器处于链路本地范围内,而不是 VPC 的 `10.22.96.0/20`。Vultr 的控制台不会将 DHCP 推送到 VPC NIC 上 —— 预期是由用户进行静态配置。修复方法是将其适配器设置为*使用以下 IP 地址*,并填入 Vultr UI 中的 VPC IP(DC 上为 `10.22.96.4`,测试机上为 `10.22.96.3`),子网掩码 `255.255.240.0`,DNS 指向加入域的主机的 DC。此后,从 DC `ping 10.22.96.5` 立即成功。
**添加 Vultr 防火墙规则后,端口 8000 上的 Splunk Web 无法访问。** 我在 Vultr 防火墙组中添加了限定在我的 IP 范围内的 TCP/8000 规则,刷新浏览器,但仍然出现连接超时。Ubuntu 主机运行着 `ufw`,并具有自己的默认拒绝入站策略。在 Splunk 主机上运行 `ufw allow 8000` 使 UI 立即加载。同样的双重防火墙模式在 UF 接收器的 9997 端口上又坑了我一次 —— 必须同时打开两层防火墙。
**首次登录时 Splunk 报告 IOWait 性能警告。** Splunk 主机(4 vCPU / 8 GB / 160 GB)的云虚拟机共享 CPU 规格对于实验来说没问题,但在初始索引历史 Windows 事件期间,Splunk 标记出了 IOWait 升高。我记录了这一点,确认磁盘实际上并未饱和,然后继续操作 —— 对于生产部署,这将促使我使用专用 CPU 和 NVMe 支持的磁盘。
**测试机上的 Universal Forwarder 安装无法接受本地 JSmith 用户。** Universal Forwarder MSI 在 Windows 账户下启动其服务,而测试工作站以 `JSmith`(一个没有本地管理员权限的普通域用户)身份登录。安装程序在服务账户步骤抛出异常。注销并以 `MyDFIR\Administrator` 身份(使用 Vultr 控制台上的域管理员凭据)重新启动 MSI 使安装得以完成;随后该服务被重新配置为在 `LocalSystem` 下运行,以便它可以读取 `WinEventLog:Security` 频道。
**必须在 `etc\system\local\` 中手动创建 `inputs.conf`。** 全新的 Universal Forwarder 安装仅在 `etc\system\default\` 下附带 `inputs.conf`,而 Splunk 的最佳实践是在 `local\` 中分层覆盖,而不是编辑默认值。我复制了该文件,以管理员身份在记事本中打开它,附加了以下内容:
```
[WinEventLog://Security]
index = mydfir-ad
disabled = false
```
然后从 `services.msc` 重启了 **SplunkForwarder** 服务。几秒钟内,事件就开始进入 `mydfir-ad` 索引。
## 经验教训
- **两个防火墙意味着两条规则。** 云平台防火墙和主机防火墙(`ufw`,Windows Defender 防火墙)是独立的。一个防火墙中的规则并不适用于另一个,测试期间的静默超时几乎总是可以追溯到我忘记的那一层。
- **VPC 不是自动配置的 —— 它只是被开通了。** 在 Vultr 中勾选启用 VPC 仅会添加 NIC。静态 IP、掩码、网关和 DNS 仍必须在客户端上设置,尤其是 DNS,它会因普通的“找不到域”错误而中断域加入过程。
- **Logon Type 比 EventCode 更重要。** 在任何真实环境中,仅靠 EventCode 4624 实在太吵了。将其与 Logon Type 7 和 10 结合使用,可将搜索范围缩小到交互式/远程交互式会话,这才是真正值得告警的攻击者常用技术。
- **云 SOAR 很方便,但也受限。** Shuffle 云 worker 中禁用 MD4 的 OpenSSL 版本悄无声息地破坏了 LDAP NTLM 路径,而且无法更换 runtime。对于实验之外的任何事情,自托管 worker 才是正确的答案。
- **引入分析师闭环的成本很低。** 用户输入节点将单次的“自动禁用” playbook 变成了一个 triage 流程 —— 告警、提示、确认、行动、再次确认 —— 只需大约五分钟的额外工作。这种模式几乎可以扩展到任何响应行动。
## 未来改进
- [ ] 将 Shuffle 迁移到自托管实例,以解决 MD4 LDAP 问题,并通过 NTLM 绑定解除对 Disable User 操作的阻止
- [ ] 在 Splunk 旁集成 Wazuh HIDS,以进行基于主机的检测和文件完整性监控
- [ ] 为 RDP 登录分析构建 Splunk 仪表板 —— 地理位置、主要源 IP、登录类型细分、失败与成功比率
- [ ] 将检测覆盖范围扩展到暴力破解活动 (EventCode 4625),并添加一条相关性规则,用于检测同一来源的 N 次失败及其随后的 4624 登录
- [ ] 在分析师工作站网段和实验网段之间实施 pfSense,以练习网络隔离和 IDS 部署
## 前置条件
- Vultr 账户(或任何支持 Windows Server 2022 和 Ubuntu 22.04 以及 VPC 功能的云服务提供商)
- 关联到云账户的有效付款方式
- 本地 RDP 和 SSH 客户端
- 用于下载 Splunk Enterprise 和 Universal Forwarder 的 Splunk.com 账户
- Shuffle SOAR 账户(云端对于演示已足够;长期首选自托管)
- 您拥有用于 webhook 控制权的 Discord 账户和服务器
- 具备 Windows 管理和 Linux 命令行的基础知识
## 如何复现
按顺序阅读以下文档:
1. [01 — 环境配置](docs/01-environment-setup.md) — Vultr 虚拟机、防火墙组、VPC、静态 IP 修复
2. [02 — Active Directory 配置](docs/02-active-directory-config.md) — AD DS 安装、林创建、测试用户、域加入
3. [03 — Splunk 配置](docs/03-splunk-configuration.md) — Splunk 安装、Universal Forwarder 部署、遥测验证
4. [04 — 检测与告警](docs/04-detection-and-alerting.md) — EventCode 4624 SPL 搜索、计划告警
5. [05 — SOAR 自动化](docs/05-soar-automation.md) — Shuffle workflow、Discord webhook、分析师邮件、AD 禁用
有关外部参考资料、工具版本以及演示的 MITRE ATT&CK 技术,请参见 [references.md](references.md)。
标签:Active Directory, Checkov, PE 加载器, Plaso, SOAR, 安全实验室, 安全运营, 扫描框架