aswinra26/ML-Automation-on-Splunk-botsv1
GitHub: aswinra26/ML-Automation-on-Splunk-botsv1
本项目在 Splunk BOTSv1 数据集上手动追踪 APT 杀伤链,并利用 MLTK 的 DensityFunction 模型实现 HTTP 流量异常自动化检测,将平均检测时间缩短至 60 秒以内。
Stars: 0 | Forks: 0
# 基于 Splunk BOTSv1 数据的 ML 自动化威胁狩猎
通过 Splunk BOTSv1 数据集完整追踪了一个 APT 杀伤链,结合手动威胁狩猎与基于 MLTK 的 AI/ML 自动化,进一步缩短平均检测时间。关联了 HTTP 流量与 Sysmon 端点遥测数据,重建了从侦察到 C2 的攻击序列,识别出关键 IOC,包括活跃的恶意软件进程链与 C2 回调。使用 Splunk MLTK 部署了 DensityFunction 异常检测模型,将平均检测时间从数小时缩短至 60 秒以内,并自动生成高严重性告警。
## A. 项目概述与目标
本项目使用 Splunk BOTS v1(Boss of the SOC)数据集——在 SIEM 环境中进行威胁狩猎练习的黄金标准数据集——对模拟的高级持续性威胁(APT)网络入侵进行调查。调查遵循 Lockheed Martin 网络杀伤链模型,以重建完整的攻击序列。
### 目标
1. 使用 Splunk 调查模拟的网络入侵,并应用网络杀伤链方法论进行攻击分析与事件调查。
2. 利用 SPL(搜索处理语言)、仪表盘和日志关联技术分析安全事件,识别入侵指标(IOC)。
3. 使用 Splunk MLTK 开发基本威胁检测工作流,增强异常检测能力并提升安全监控可见性。
## B. 网络杀伤链——攻击流程
Lockheed Martin 网络杀伤链是一个 7 阶段框架,描述了 APT 攻击的展开过程。本项目实际调查的阶段如下所示。
1. 侦察 活跃 — 攻击者使用 Acunetix 扫描 WayneCorp
2. 武器化 日志中未直接观察到
3. 投递 日志中未直接观察到
4. 利用 利用 Web 漏洞上传恶意软件
5. 安装 活跃 — 通过 w3wp.exe 释放并执行 3791.exe
6. 命令与控制 活跃 — 恶意软件向 23.22.63.114:3791 回连
7. 目标达成 本调查未完全追踪
### 发现的攻击序列
以下攻击链通过关联 HTTP 日志与 Sysmon 端点遥测数据重建:
1. 攻击者(40.80.148.42)使用 Acunetix 漏洞扫描器扫描 WayneCorp 服务器
↓
2. Acunetix 发现 Web 应用中的可利用漏洞
↓
3. 攻击者通过 Web 漏洞上传恶意文件 3791.exe
↓
4. IIS 工作进程 w3wp.exe 生成 cmd.exe(Sysmon 事件 ID 1)
↓
5. cmd.exe 执行 3791.exe — 恶意软件现在已在主机上运行
↓
6. 3791.exe 建立到 23.22.63.114 端口 3791 的 C2 连接(Sysmon 事件 ID 3)
## C. 第一阶段——手动威胁狩猎
在自动化之前,首先通过手动方式遵循网络杀伤链追踪攻击,关联 HTTP 流量与 Sysmon 端点遥测日志。
### 步骤 1 | 侦察——发现扫描器
攻击者在利用之前对 WayneCorp 进行了大规模扫描。目标是找出定向目标服务器的 HTTP 流量中“最嘈杂”的 IP 地址。
#### 关键细节
- 目标服务器:192.168.250.70
- 使用的 sourcetype:stream:http(HTTP 流量日志)
- 技术:按源 IP 聚合请求数量,降序排列——排名第一的 IP 即为扫描器
#### SPL 查询
```spl
index=botsv1 sourcetype=stream:http dest_ip=192.168.250.70
| stats count by src_ip
| sort - count
```
查询解释:
- `index=botsv1 sourcetype=stream:http dest_ip=192.168.250.70` — 仅筛选命中 WayneCorp 服务器的 HTTP 日志
- `| stats count by src_ip` — 按源 IP 地址分组计算总请求数
- `| sort - count` — 降序排列,使请求数最高的 IP(扫描器)显示在最前面
#### 发现
扫描器 IP 识别为:40.80.148.42
`src_header` 字段确认了使用的工具:Acunetix 漏洞扫描器。该 IP 发出了数千次请求,远超任何合法用户。
### 步骤 2 | 执行——发现恶意软件
攻击者发现漏洞后,上传了一个恶意可执行文件。对所有日志源进行关键词搜索,可以找到恶意软件出现的位置。
```spl
index=botsv1 sourcetype=stream:http dest_ip=192.168.250.70
| search part_filename{}="*.exe*" OR uri_path="*.exe*"
| table _time, src_ip, uri_path, part_filename{}, http_method
```
#### 关键细节
- Sysmon 事件 ID 1 = 进程创建 — 记录创建了哪个进程、由哪个父进程创建、以及命令行参数
- 观察到的关键父子进程链:w3wp.exe -> cmd.exe -> 3791.exe
- w3wp.exe 是 IIS(Internet Information Services)Web 服务器进程——正常操作下绝不应生成 cmd.exe
#### 查询解释
简单的关键词搜索,在所有索引的 sourcetype 中查找恶意软件文件名。这会显示 Sysmon 事件 ID 1 条目,展示进程创建链。
#### 危险信号——异常进程链
```
w3wp.exe (IIS Web 服务器——应仅提供 HTTP 服务)
|
v
cmd.exe (Windows 命令提示符——Web 服务器的异常子进程)
|
v
3791.exe (恶意软件)
```
Web 服务器生成命令提示符几乎可以确定是 WebShell 执行或远程代码执行(RCE)利用的迹象。
### 步骤 3 | 命令与控制——回连
恶意软件运行后,会建立持久的出站连接到攻击者的 C2(命令与控制)服务器。Sysmon 事件 ID 3 记录进程的所有网络连接。
```spl
index=botsv1 sourcetype=stream:tcp src_ip=192.168.250.70
| stats count by dest_ip, dest_port, src_ip, src_port
| sort - count
```
查看事件,显示到 23.22.63.114 的两个不同目标端口。
| 时间 | dest_port |
|------|-----------|
| 03:30 → 03:49 | 1337 |
端口 1337("leet")是经典的黑客/攻击者端口——绝非巧合。
这三个连接发生在初始 3791 信标之后,暗示:
- 攻击者可能打开了第二个 C2 通道,使用端口 1337
- 或者恶意软件在初始签到后切换了端口
关键细节
- Sysmon 事件 ID 3 = 网络连接 — 记录出站连接的进程名称、目标 IP 和端口
- 按进程名称 3791.exe 过滤,仅查找其出站连接
- 端口 3791 故意与恶意软件文件名一致——这是攻击者的刻意签名
#### 发现
```
C2 服务器:23.22.63.114 | 端口:3791
```
恶意软件连接到一个外部 IP,使用非标准端口且端口号与其自身文件名完全一致。这就是攻击者的 C2 基础设施。
### 已确认的 IOC
| IOC 类型 | 值 |
|----------|-----|
| 扫描器 IP | 40.80.148.42 |
| 扫描工具 | Acunetix 漏洞扫描器 |
| 恶意软件文件名 | 3791.exe |
| 恶意进程链 | w3wp.exe -> cmd.exe -> 3791.exe |
| C2 服务器 IP | 23.22.63.114 |
| C2 端口 | 3791 |
## D. 第二阶段——机器学习自动化(MLTK)
在手动识别攻击模式后,使用 Splunk 机器学习工具包(MLTK)实现未来检测的自动化。这将手动、依赖分析师的过程转换为自动告警,大幅降低平均检测时间(MTTD)。
### 需要在 Splunk 上安装的应用
1. **Splunk AI Toolkit (MLTK)**
→ 取代旧的 "Machine Learning Toolkit" — 提供 `fit`/`apply` 命令
2. **Python for Scientific Computing (windows_x86_64)**
→ DensityFunction 算法所需的后端
→ 缺少时会出现错误:"Failed to find Python for Scientific Computing"
### 步骤 4 | 训练异常检测模型
#### 算法:DensityFunction
DensityFunction 基于训练数据对数字字段的统计概率分布进行建模。低于概率阈值的数据点被标记为异常值(IsOutlier=1)。可以理解为教会 Splunk“正常周一早晨流量”的样子,从而能立即发现激进的扫描器活动。
#### 策略与配置
- 基准单位:每 1 分钟 HTTP 请求计数桶(通过 `timechart span=1m`)
- 阈值:0.01 — 任何概率低于 1% 的数据点被标记为异常值
- 模型名称保存为:`baseline_web_traffic`
- 逻辑:如果 99% 的流量为每分钟 10-50 个请求,那么扫描器每分钟 5000 个请求就是巨大的统计异常
#### SPL 查询——模型训练
```spl
index="botsv1" sourcetype="stream:http"
| timechart span=1m count
| fit DensityFunction count threshold=0.01
into baseline_web_traffic
```
```
```
查询解释:
- `timechart span=1m count` — 将 HTTP 事件按 1 分钟分桶,生成计数时间序列
- `fit DensityFunction count threshold=0.01` — 从训练数据中学习 `count` 字段的概率密度,0.01 为异常值阈值
- `into baseline_web_traffic` — 保存训练好的模型,以便后续在实时数据上重用
### 步骤 5 | 运营部署
应用保存的模型,自动检测异常分钟。
任何超过训练基线的 1 分钟窗口将被标记为 `IsOutlier=1.0`
#### SPL 查询——模型部署
```spl
index="botsv1" sourcetype="stream:http"
| timechart span=1m count
| apply baseline_web_traffic
| where 'IsOutlier(count)'=1.0
| table _time, count, 'IsOutlier(count)'
| sort - count
```
- 字段名必须用单引号包裹:`'IsOutlier(count)'`
- 过滤值必须为浮点数:`=1.0`(而不是整数 `=1`)
- 缺少引号/浮点数 → `where` 子句将返回 0 条结果
### 步骤 6 | 告警规则——Poison Ivy
| 项目 | 内容 |
|------|------|
| **告警名称** | POISON IVY |
| **命名原因** | WayneCorp(蝙蝠侠宇宙)——Poison Ivy 是蝙蝠侠的反派 |
| | 也反映了攻击本身:看起来像正常流量,实则有毒 |
| **告警配置** | |
| 标题 | POISON IVY |
| 描述 | DensityFunction MLTK 模型检测到针对 WayneCorp(192.168.250.70)的异常 HTTP 请求量。可能为侦察扫描器或活跃攻击。请调查 src_ip。 |
| 权限 | 共享于应用内 |
| 告警类型 | 计划 |
| 过期时间 | 24 小时 |
| 严重性 | 高 |
| **触发条件** | |
| 触发告警当 | 结果数 |
| 大于 | 0 |
| 节流 | 启用 — 每 5 分钟抑制一次 |
| **为什么节流 5 分钟?** | |
| 不加节流 → 每分钟触发告警 → 重复告警淹没触发告警列表 |
| 加节流 → 触发一次,抑制 5 分钟,若攻击仍在继续则重新触发 |
| **触发动作** | |
| 动作 | 添加到触发告警 |
| 查看 | 活动 → 触发告警 |
| **如何在 Splunk 中查看** | |
| 活动 → 触发告警 |
| 显示:时间 \| 告警名称 \| 严重性 \| 结果 \| 查看结果链接 |
保存的模型应用于新的或实时 HTTP 数据。任何流量量超过训练基线的 1 分钟窗口将自动设置 `IsOutlier=1`,从而在 Splunk 仪表盘或告警操作中触发告警。
### MLTK 检测工作流
```
实时 HTTP 日志传入 Splunk
|
v
timechart span=1m count --> 1 分钟请求计数桶
|
v
apply baseline_web_traffic --> 每个桶与模型打分
|
v
IsOutlier=1 --> 60 秒内自动触发告警
```
### 对运营的影响
- **无 MLTK**:分析师手动审查日志——扫描器可能在数小时或数天内未被发现
- **有 MLTK**:每个 1 分钟桶自动评分——异常流量出现后 60 秒内触发告警
- **结果**:平均检测时间(MTTD)从数小时/天缩短至 1 分钟以内
#### 发现
扫描器 IP 识别为:40.80.148.42
`src_header` 字段确认了使用的工具:Acunetix 漏洞扫描器。该 IP 发出了数千次请求,远超任何合法用户。
### 步骤 2 | 执行——发现恶意软件
攻击者发现漏洞后,上传了一个恶意可执行文件。对所有日志源进行关键词搜索,可以找到恶意软件出现的位置。
```spl
index=botsv1 sourcetype=stream:http dest_ip=192.168.250.70
| search part_filename{}="*.exe*" OR uri_path="*.exe*"
| table _time, src_ip, uri_path, part_filename{}, http_method
```
#### 关键细节
- Sysmon 事件 ID 1 = 进程创建 — 记录创建了哪个进程、由哪个父进程创建、以及命令行参数
- 观察到的关键父子进程链:w3wp.exe -> cmd.exe -> 3791.exe
- w3wp.exe 是 IIS(Internet Information Services)Web 服务器进程——正常操作下绝不应生成 cmd.exe
#### 查询解释
简单的关键词搜索,在所有索引的 sourcetype 中查找恶意软件文件名。这会显示 Sysmon 事件 ID 1 条目,展示进程创建链。
#### 危险信号——异常进程链
```
w3wp.exe (IIS Web 服务器——应仅提供 HTTP 服务)
|
v
cmd.exe (Windows 命令提示符——Web 服务器的异常子进程)
|
v
3791.exe (恶意软件)
```
Web 服务器生成命令提示符几乎可以确定是 WebShell 执行或远程代码执行(RCE)利用的迹象。
### 步骤 3 | 命令与控制——回连
恶意软件运行后,会建立持久的出站连接到攻击者的 C2(命令与控制)服务器。Sysmon 事件 ID 3 记录进程的所有网络连接。
```spl
index=botsv1 sourcetype=stream:tcp src_ip=192.168.250.70
| stats count by dest_ip, dest_port, src_ip, src_port
| sort - count
```
查看事件,显示到 23.22.63.114 的两个不同目标端口。
| 时间 | dest_port |
|------|-----------|
| 03:30 → 03:49 | 1337 |
端口 1337("leet")是经典的黑客/攻击者端口——绝非巧合。
这三个连接发生在初始 3791 信标之后,暗示:
- 攻击者可能打开了第二个 C2 通道,使用端口 1337
- 或者恶意软件在初始签到后切换了端口
关键细节
- Sysmon 事件 ID 3 = 网络连接 — 记录出站连接的进程名称、目标 IP 和端口
- 按进程名称 3791.exe 过滤,仅查找其出站连接
- 端口 3791 故意与恶意软件文件名一致——这是攻击者的刻意签名
#### 发现
```
C2 服务器:23.22.63.114 | 端口:3791
```
恶意软件连接到一个外部 IP,使用非标准端口且端口号与其自身文件名完全一致。这就是攻击者的 C2 基础设施。
### 已确认的 IOC
| IOC 类型 | 值 |
|----------|-----|
| 扫描器 IP | 40.80.148.42 |
| 扫描工具 | Acunetix 漏洞扫描器 |
| 恶意软件文件名 | 3791.exe |
| 恶意进程链 | w3wp.exe -> cmd.exe -> 3791.exe |
| C2 服务器 IP | 23.22.63.114 |
| C2 端口 | 3791 |
## D. 第二阶段——机器学习自动化(MLTK)
在手动识别攻击模式后,使用 Splunk 机器学习工具包(MLTK)实现未来检测的自动化。这将手动、依赖分析师的过程转换为自动告警,大幅降低平均检测时间(MTTD)。
### 需要在 Splunk 上安装的应用
1. **Splunk AI Toolkit (MLTK)**
→ 取代旧的 "Machine Learning Toolkit" — 提供 `fit`/`apply` 命令
2. **Python for Scientific Computing (windows_x86_64)**
→ DensityFunction 算法所需的后端
→ 缺少时会出现错误:"Failed to find Python for Scientific Computing"
### 步骤 4 | 训练异常检测模型
#### 算法:DensityFunction
DensityFunction 基于训练数据对数字字段的统计概率分布进行建模。低于概率阈值的数据点被标记为异常值(IsOutlier=1)。可以理解为教会 Splunk“正常周一早晨流量”的样子,从而能立即发现激进的扫描器活动。
#### 策略与配置
- 基准单位:每 1 分钟 HTTP 请求计数桶(通过 `timechart span=1m`)
- 阈值:0.01 — 任何概率低于 1% 的数据点被标记为异常值
- 模型名称保存为:`baseline_web_traffic`
- 逻辑:如果 99% 的流量为每分钟 10-50 个请求,那么扫描器每分钟 5000 个请求就是巨大的统计异常
#### SPL 查询——模型训练
```spl
index="botsv1" sourcetype="stream:http"
| timechart span=1m count
| fit DensityFunction count threshold=0.01
into baseline_web_traffic
```
```
- 字段名必须用单引号包裹:`'IsOutlier(count)'`
- 过滤值必须为浮点数:`=1.0`(而不是整数 `=1`)
- 缺少引号/浮点数 → `where` 子句将返回 0 条结果
### 步骤 6 | 告警规则——Poison Ivy
| 项目 | 内容 |
|------|------|
| **告警名称** | POISON IVY |
| **命名原因** | WayneCorp(蝙蝠侠宇宙)——Poison Ivy 是蝙蝠侠的反派 |
| | 也反映了攻击本身:看起来像正常流量,实则有毒 |
| **告警配置** | |
| 标题 | POISON IVY |
| 描述 | DensityFunction MLTK 模型检测到针对 WayneCorp(192.168.250.70)的异常 HTTP 请求量。可能为侦察扫描器或活跃攻击。请调查 src_ip。 |
| 权限 | 共享于应用内 |
| 告警类型 | 计划 |
| 过期时间 | 24 小时 |
| 严重性 | 高 |
| **触发条件** | |
| 触发告警当 | 结果数 |
| 大于 | 0 |
| 节流 | 启用 — 每 5 分钟抑制一次 |
| **为什么节流 5 分钟?** | |
| 不加节流 → 每分钟触发告警 → 重复告警淹没触发告警列表 |
| 加节流 → 触发一次,抑制 5 分钟,若攻击仍在继续则重新触发 |
| **触发动作** | |
| 动作 | 添加到触发告警 |
| 查看 | 活动 → 触发告警 |
| **如何在 Splunk 中查看** | |
| 活动 → 触发告警 |
| 显示:时间 \| 告警名称 \| 严重性 \| 结果 \| 查看结果链接 |
保存的模型应用于新的或实时 HTTP 数据。任何流量量超过训练基线的 1 分钟窗口将自动设置 `IsOutlier=1`,从而在 Splunk 仪表盘或告警操作中触发告警。
### MLTK 检测工作流
```
实时 HTTP 日志传入 Splunk
|
v
timechart span=1m count --> 1 分钟请求计数桶
|
v
apply baseline_web_traffic --> 每个桶与模型打分
|
v
IsOutlier=1 --> 60 秒内自动触发告警
```
### 对运营的影响
- **无 MLTK**:分析师手动审查日志——扫描器可能在数小时或数天内未被发现
- **有 MLTK**:每个 1 分钟桶自动评分——异常流量出现后 60 秒内触发告警
- **结果**:平均检测时间(MTTD)从数小时/天缩短至 1 分钟以内标签:Apex, APT攻击链, BOTS数据集, C2检测, CISA项目, DAST, HTTP流量, IOC, IP 地址批量处理, MLTK, PFX证书, Sysmon, 入侵分析, 命令与控制, 安全运营, 安装恶意软件, 实时检测, 密度函数, 密码管理, 异常检测, 恶意软件分析, 扫描框架, 攻击检测, 机器学习, 端点检测, 网络流量分析, 自动化告警