arijadhav1/Active-Directory-Homelab

GitHub: arijadhav1/Active-Directory-Homelab

基于 Splunk、Shuffle SOAR 与 Slack 构建的 AD 自动化检测与响应实验环境,实现从异常认证告警到人工审批后自动禁用域用户的完整 SOC 工作流。

Stars: 0 | Forks: 0

# 家庭 SOC 实验室:使用 Splunk + Shuffle 进行 Active Directory 检测与自动响应 这个项目旨在从零开始构建一个真实的检测和响应流水线。其核心思路很简单:模拟一场针对加入域的机器的凭证攻击,在 Splunk 中捕获它,并且不只是生成一个躺在队列里的警报,而是通过一个 SOAR 剧本将整个响应过程自动化,在采取行动之前将决定权交到人类手中。 Screenshot 2026-06-17 at 10 25 02 PM 完整的流程如下:攻击者使用有效凭证向目标机器进行身份验证,Splunk 触发警报,Slack 收到通知,Shuffle 触发剧本,SOC 分析师收到一封询问是否禁用受感染账户的电子邮件,如果他们同意,Shuffle 会指示 Domain Controller 禁用该用户,并发送最终的 Slack 确认通知。 第一部分涵盖了搭建基础设施并让 Active Directory 运行起来的过程。 ## 环境配置 所有组件都运行在托管于 Vultr 的三台云虚拟机上,它们位于同一个硅谷区域,以便通过私有 VPC 网络进行通信。 | 机器 | 角色 | 配置 | |---|---|---| | Ari-ADDC01 | Domain Controller | 2 vCPU,4GB RAM,80GB 存储 | | Cloud Instance | 目标机器 | 1 vCPU,2GB RAM,55GB 存储 | | Ari-Splunk | Splunk 服务器 | 4 vCPU,8GB RAM,160GB 存储 | Splunk 机器的配置有意设得比其他机器更高。日志摄取非常消耗资源,我不希望性能问题妨碍检测工作。 Pasted Graphic ## 网络和防火墙 对于防火墙规则,我创建了一个名为 Ari-AD-Project 的组,并将入站访问限制为两条规则:端口 22 上的 SSH 和端口 3389 上的 RDP,两者都限制为仅允许我的公网 IP 访问。其他所有流量默认丢弃。 Femall Groups  Manage All AD Projec 这三台机器都连接到同一个 VPC,这为它们提供了私有 IP 地址,无需将流量路由到互联网即可进行内部通信。VPC 是特定于区域的,这就是为什么从一开始就让这三台机器都选择硅谷区域至关重要的原因。 我早期遇到的一个问题是:在每台机器上启用 VPC 后,网络适配器显示的是 169.x.x.x 地址,而不是实际的 VPC IP。我不得不进入每台 Windows 机器的适配器设置,手动配置 IP 以匹配分配的 VPC 地址。之后,机器之间的 ping 测试就正常了。 Pasted Graphic 2 ## 安装 Active Directory 解决网络问题后,我远程进入了 Domain Controller,并通过服务器管理器中的“添加角色和功能”安装了 Active Directory Domain Services。安装完成后,右上角会出现一个标志通知,提示您将服务器提升为域控。我点击了它,创建了一个名为 `Ari.local` 的新森林,设置了目录服务还原模式密码,并让它在向导的剩余步骤中自动运行。 提升后机器会自动重启。当它重新启动时,它就是一个全功能的域控制器了。 ## 创建域用户 在“Active Directory 用户和计算机”中,我导航到 `Ari.local > Users`,右键单击并创建了一个新用户,作为攻击模拟的目标账户。 **姓名:** Rachel Wilson **用户名:** RWilson Active Directory Users and Computen ## 将目标机器加入域 在目标机器上,我进入“系统属性”,点击“重命名这台电脑(高级)”,并将成员身份从“工作组”更改为“域”,输入了 `Ari.local`。但在此操作成功之前,机器根本找不到该域。 解决方法是更改 DNS。目标机器的首选 DNS 服务器需要指向 Domain Controller 的 VPC 地址,而不是公共 DNS 解析器。Active Directory 依赖 DNS 来定位域服务,因此如果它没有指向域控,加入域的操作就无从下手。一旦我在适配器的 IPv4 设置中更新了该配置并重试,加入域的操作立即就成功了。 Internet Protocol Version 4 (TCPIPv4) Properties 重启后,我以 `Ari\RWilson` 的身份登录到测试机器。还有一件事需要处理:默认情况下,RWilson 没有被授权进行远程登录。我不得不进入目标机器的远程桌面用户设置,显式添加 RWilson,并使用来自域控的域管理员凭据进行确认。 Screenshot 2026-06-18 at 1 59 06 AM Remote Desktop Users 完成这些操作后,域已启动,用户已就位,目标机器已加入域并且可以访问。接下来是安装 Splunk 并对其进行配置,以开始从这些 Windows 机器中摄取遥测数据。已将 VPC 适配器的首选 DNS 服务器更改为指向 ADDC 的私有 IP,然后成功将机器加入了 Ari.local 域。配置了 RDP 权限,以允许域用户 (RWilson) 通过“远程桌面用户”组进行远程登录访问。 ## 阶段 2:安装 Splunk 和配置遥测 随着域的建立和机器之间能够相互通信,下一步就是获取可见性。这意味着要在 Ubuntu 服务器上安装 Splunk,在两台 Windows 机器上安装 universal forwarders,并让遥测数据流入一个集中式索引。 ### 设置 Splunk Enterprise 由于我使用的是 Mac,一切操作都是通过终端经 SSH 进行。我通过 SSH 连接到 Splunk 机器,更新了软件仓库,然后前往 Splunk 官网获取 Enterprise 免费试用版。我选择了 Linux 的 .deb 包,并直接将 wget 链接复制到 SSH 会话中将其下载到服务器上。 root@Ari-Splunk-# wget -0 splunk-10 4 0-f798d4d49089-11nux-and64 deb 下载完成后,我使用 `dpkg -i` 进行安装,然后导航到 `/opt/splunk/bin`。 root@Ari-Splunkoptsplunk# 1s 使用 `./splunk start --accept-license --answer-yes --run-as-root` 首次启动 Splunk 会初始化所有内容,并且您可以在此处设置 Web 界面的管理员用户名和密码。以 root 身份运行时必须使用 `--run-as-root` 标志,否则 Splunk 将无法启动。 在浏览器中访问 `splunk-ip:8000` 上的 Web UI 时并没有立即成功。需要做两件事:在 Vultr 防火墙组中为端口 8000 添加一条限制为我的 IP 的 TCP 规则,并在 SSH 会话中运行 `ufw allow 8000`。完成这两步后,登录页面才加载出来。 Aten 14 splunk› enterprise 接下来,在 Splunk 内部进行了几项配置: - 在首选项下将时区设置为 GMT - 从应用市场安装了 Splunk Add-on for Microsoft Windows - 在“设置 > 索引”下创建了一个名为 `ari-ad` 的新索引 Screenshot 2026-06-28 at 12 25 43 AM - 在“设置 > 转发和接收”下设置了 9997 上的接收端口 Receive data ### 在目标机器上安装 Universal Forwarder 我从 Splunk 官网下载了 Splunk Universal Forwarder,并在 Windows 目标机器上运行了安装程序。在设置过程中,我将接收索引器指向了 Splunk 服务器的 VPC IP 的 9997 端口。 image 安装后,我导航到 `C:\Program Files\SplunkUniversalForwarder\etc\system\local`。默认情况下那里没有 `inputs.conf` 文件,所以我从默认目录中复制了一个过来,并以管理员身份运行记事本对其进行编辑,在底部添加了以下内容: ``` [WinEventLog://Security] Index = ari-ad Disabled = false ``` inputsconf - Notecad 然后在“服务”中,我打开了 SplunkForwarder 服务,将登录账户切换为 Local System,并重新启动了它。 SplunkForwarder Properties (Local Computer) 重启后,我回到 Splunk 并在“搜索与报告”中运行了 `index=ari-ad`。起初没有返回任何结果。解决方法是在 Splunk 服务器上运行 `ufw allow 9997` 以打开转发端口。之后,事件就开始流入了。 我在 Domain Controller 上重复了相同的过程。一旦两个转发器都在运行,在 Splunk 中检查 host 字段就会显示两个值,确认遥测数据正从两台机器传入。 ### 构建警报 随着遥测数据的流入,我构建了一个 Splunk 警报,以捕获来自预期网络之外的成功 RDP 登录。 Windows 安全事件 ID 4624 涵盖了成功的登录事件。RDP 会话显示为登录类型 7 或 10。我一步步构建了以下搜索: ``` index=ari-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 ``` `Source_Network_Address=*` 过滤器会移除没有网络地址的事件,`!="-"` 会丢弃本地系统噪声,而 `!="99.*"` 会过滤掉我自己授权的 IP,从而确保只有意外的来源才会触发警报。 New Search New Search 为了生成测试事件,我更新了 Vultr 防火墙规则,允许来自任何地方而不是仅限我的 IP 的 RDP 访问,然后从攻击者机器进行了 RDP 登录。原本计划在 UTM 中使用本地的 Kali 虚拟机,但在安装过程中 OpenVPN 一直报错,所以我在 Vultr 上启动了一台轻量级的 Debian 机器并将其命名为 attacker。结果相同,摩擦更小。 Pasted Graphic 2 我将搜索保存为一个名为 `Ari-Unauthorized-Successful-Login-RDP` 的警报,将其设置为按 cron 计划每分钟运行一次,针对过去 60 分钟的数据(`* * * * *`),并将严重性设置为“中”。在保存它的一分钟内,该警报就出现在了“活动 > 触发的警报”下。 Save As Alert Expires Triggered Alerts 接下来是将 Splunk 连接到 Shuffle 并构建自动响应剧本。 ## 故障排除 在此阶段期间有几个地方出了问题,值得记录下来。 从终端进行的 SSH 在连接时卡住了,但没有抛出任何错误。我使用 Nmap 验证了该端口是否确实可达,发现我的公网 IP 已经改变,于是更新了防火墙规则,之后它就连接正常了。 当我第一次运行 `./splunk start` 时,它完全跳过了许可协议和凭据设置。事实证明,在没有显式传递该标志的情况下以 root 身份运行 Splunk 已被弃用。解决方法是使用 `./splunk start --accept-license --answer-yes --run-as-root`。 在测试机器上运行了转发器并重启服务后,Splunk 中没有显示任何事件。问题出在我断开并重新连接了 SSH 会话,但没有重启服务器上的 Splunk。一旦我在 Ubuntu 机器上再次启动它,遥测数据立刻就开始流入了。 ## 阶段 3:集成 Shuffle、Slack 并构建响应剧本 随着 Splunk 警报功能正常运行,下一步是将所有内容连接到一个自动化的响应 流水线中。当检测到未经授权的登录时,会触发 Slack 通知,SOC 分析师 会收到一封询问是否禁用该账户的电子邮件,剩下的操作将根据 他们的回答自动进行。 ### 设置 Shuffle 我访问了 shuffler.io,创建了一个账户,并打开了 Workflows。我创建了一个名为 ari-ad project 的新工作流,并添加了一个 Webhook 触发器作为传入 Splunk 警报的入口点,将其命名为 splunk-alert,并复制了 Webhook URI。 回到 Splunk,我调出已保存的警报,对其进行编辑,并添加了一个 Webhook 操作,将 Shuffle URI 粘贴进去。保存后,我在工作流中将 Webhook 设置为起始节点,并 让警报生成以进行测试。在 Shuffle 中检查“Explore Runs”确认数据 已正确传入。 ### 连接 Slack 我在 Shuffle 应用库中搜索 Slack,将其添加到工作流中,并将其重命名为 Alert-Notification。身份验证是通过 Shuffle 进行的一键登录,并且我确保它 指向了正确的工作区。 在 Slack 端,我创建了一个名为 ari-projects 的新工作区,并添加了一个名为 alerts 的公共频道。为了让 Shuffle 指向正确的频道,我从 频道 URL 的末尾抓取了唯一标识符,并将其粘贴到 Slack 节点的 channel 字段中。 我将 Webhook 节点连接到 Alert-Notification 节点,并将消息配置为 从 Splunk 警报中引入相关字段: 警报:$exec.search_name 时间:$exec.result_time 用户:$exec.result_user 源 IP:$exec.result.Source_Network_Address 重新运行工作流后,通知发布到了 alerts 频道。我还 将时间字段从 epoch 转换为可读格式,这样消息在乍看之下确实能让人明白。 ### 添加分析师决策步骤 剧本并没有在警报一触发就自动禁用账户,而是暂停 并要求分析师做出决定。我添加了一个 User Input 节点,将其重命名为 user_action,并 将问题设置为询问分析师是否要禁用该用户。然后我将 其连接到一个电子邮件操作,将同样的警报详情发送到分析师的收件箱。我还了 消息格式,使其与 Slack 通知中使用的结构相匹配。 ### 连接 Active Directory 随着通知端正常工作,我在工作流中添加了一个 Active Directory 节点,并 将其连接到用户输入。为了对其进行身份验证,我将它指向了 Domain Controller 上端口 389 的 LDAP,将域设置为 ARI,并使用了来自 ADDC 机器的管理员凭据。对于 Base DN,我在 ADDC 的 PowerShell 中运行了 `Get-ADDomain` 并复制了返回的 UsersContainer 值。 让 AD 节点真正工作起来需要进行一些故障排除。最初的身份验证 无法通过,所以我在 Vultr 中为 TCP 1-65535 开放了一条防火墙规则,以排除 连通性问题。这仍然没有解决问题,所以我在 Shuffle 中创建了一个新的身份验证配置文件,这次将 use_ssl 设置为 false,并使用了一个专用的域管理员账户 而不是内置的管理员。我在 Active Directory 中创建了一个新用户,将他们 添加到 Domain Admins 中,并为名为 UPDATE-NEW-Auth 的新身份验证配置文件使用了这些凭据。 在那之后,连接成功建立。 一旦身份验证成功,我将 find 操作设置为 Disable User,将完整的流程 从 Webhook 经 Slack、再到用户输入、最后到 Active Directory 连接起来,并进行端 到端的运行。 ### 确认禁用并通知 Slack 在账户被禁用后,我希望在 Slack 中得到确认,而不是 让工作流就此默默结束。我添加了第二个名为 Update-Notification 的 Slack 节点, 其消息设置为确认哪个账户被禁用,指向相同的 alerts 频道。 为了使确认可靠,我添加了第二个名为 Get-User-Attributes 的 Active Directory 节点,它在禁用操作运行后检查账户状态,并 将其连接到名为 Check_AD_User 的 Refresh 工具。Refresh 工具轮询 userAccountControl 属性,并且仅当 值包含 ACCOUNTDISABLED 时才触发 Update-Notification 的 Slack 消息。这样,确认只有在账户 被真正禁用后才会触发,而不仅仅是因为工作流到达了该步骤。 为了验证“否”路径是否正常工作,我再次运行了该工作流,并在 电子邮件提示处选择了“否”。账户保持启用状态,并且 没有触发进一步的操作。 至此,完整的流水线已经可以端到端工作。未经授权的 RDP 登录会触发 Splunk 警报,Slack 收到通知,分析师收到询问是否采取行动的电子邮件,如果 他们回答是,域账户将被禁用,并且 Slack 会自动确认。 未来计划:待定
标签:SOAR, Terraform 安全, 安全运营, 扫描框架, 活动目录, 自动化响应