JacobRHess/splunk-bots-hunts

GitHub: JacobRHess/splunk-bots-hunts

一个将 Splunk 威胁狩猎调查与 CI 自动化验证相结合的安全项目,通过完整的入侵场景链路交付可安装、经过测试验证的检测规则和仪表板。

Stars: 0 | Forks: 0

# splunk-bots-hunts [![hunts](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/2885757ad2084631.svg)](https://github.com/JacobRHess/splunk-bots-hunts/actions/workflows/hunts.yml) [![codeql](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/8cab55aef3084636.svg)](https://github.com/JacobRHess/splunk-bots-hunts/actions/workflows/codeql.yml) [![python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3130/) [![license MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) **一个你可以亲自运行,并在 CI 中得到验证的 Boss of the SOC v3 调查项目。** 大多数 BOTS v3 的分析文章只是带有 SPL 截图的博客:静态的、一次只解答一个问题,根本无法判断它们是否依然有效。而本项目是一个代码仓库。每次提交时,CI 都会启动一个 Splunk 容器,通过 HEC 重放作为测试固件的证据,运行每个网络狩猎并验证其答案,运行每个检测并断言其能在恶意数据上触发同时在正常数据上保持静默,并使用 `btool` 验证可安装的 app。如果某个发现失效或某条规则停止触发,构建就会失败。 六个场景贯穿了同一入侵行为的遥测数据,而不是二十个互不相关的问题:一个被入侵的 AWS 账户(01)、其背后的笔记本电脑(02)、该笔记本上的浏览器加密货币挖矿机(03)、第二台主机上的无文件 PowerShell 植入(04)、同一个 `fyodor` 身份从香港的 VPS 被用于攻击 Azure AD(05),以及被盗用的云账户随后在 Office 365 中进行的操作(06)。每个场景都是一次文档化的网络狩猎(包括问题、SPL、关键线索和 ATT&CK 技术),并附带了根据该狩猎逻辑编写的检测规则,这些规则已针对恶意和正常的测试固件进行了测试,并打包为可安装的 Splunk app。 [![Frothly 入侵调查仪表板](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e56bea9a3e084642.png)](docs/img/investigation.png) 交付的调查仪表板:顶部显示云滥用 KPI,随后是经过身份和资产查找丰富的活动记录。每个面板都可以直接钻取查看相关事件。 ## 入侵行为 ``` flowchart LR classDef cloud fill:#1f6feb22,stroke:#58a6ff,color:#c9d1d9; classDef host fill:#3fb95022,stroke:#3fb950,color:#c9d1d9; A["01 · AWS recon
bstoll, no MFA
T1078.004"]:::cloud B["02 · BSTOLL-L logons
remote compromise ruled out"]:::host C["03 · Coinhive miner
browser foothold
T1496"]:::host D["04 · PowerShell implant
FYODOR-L, registry persistence
T1059.001 / T1053.005"]:::host E["05 · Azure AD sign-ins
fyodor from HK VPS
T1078.004 / T1110.003"]:::cloud F["06 · O365 account abuse
bgist shares a lure, fyodor edits mailboxes
T1080 / T1098 / T1531"]:::cloud A -->|how were the keys stolen| B B -->|browser was the weak point| C C -. separate foothold .-> D D -->|same identity reused| E E -->|same accounts, now in O365| F ``` `bstoll` 将场景 01-03 串联起来;`fyodor` 贯穿了 04-06,其中 `bgist` 将云账户从 05 延续到了 06。两个被入侵的用户,数台主机和云租户,构成了 2018-08-20 这一天的时间线。 ## 狩猎与检测 检测回答的是“这发生过吗?”而狩猎回答的是“发生了什么?”每个场景都从一次狩猎开始:对 BOTSv3 入侵的某一部分进行记录在案的调查。随后,它会交付该调查过程所编写出的检测规则,作为可部署的 Splunk 内容。狩猎会在 CI 中断言一个已知的答案;而检测则断言它们会在恶意数据切片上触发,并在正常数据上保持静默。 ## 仓库布局 ``` scenarios/-/ ├── README.md narrative write-up ├── hunts/*.spl one SPL per documented hunt ├── detections.yaml deployable correlation searches (fire/silent fixture test) ├── dashboards/*.xml Splunk dashboard XML ├── fixtures/*.jsonl fixture event slice per index (for CI) ├── answers.yaml { hunts: [{ file, question, expected, field }] } └── attack.yaml { techniques: [{ id, name }] } ``` 生成并已提交的构建产物: ``` splunk_app/froth_bots_hunts/ installable Splunk app (dashboards, ES detections, CIM tags, macros, lookups) docs/index.html static HTML report (GitHub Pages ready) docs/attack-navigator-layer.json MITRE ATT&CK Navigator layer ``` 完整的 BOTSv3 数据集并未包含在 git 中。与每个狩猎一起提交的测试固件都是微小的事件切片,刚好足够在 CI 中运行和测试 SPL。 ## Splunk app `splunk_app/froth_bots_hunts/` 是由场景源码通过 `harness/build_splunk_app.py` 生成的。将其复制到 `$SPLUNK_HOME/etc/apps/` 并重启,或者通过 Manage Apps 上传。它包含: - **Detections** 作为定时 Enterprise Security 关联搜索:`detections.yaml` 中的每个条目都会变成一个保存的搜索(saved search),带有 notable 和 risk 操作、ATT&CK 和分析故事(analytic-story)注解,以及一个可钻取回其事件的 notable 链接。 - **CIM mapping**(`eventtypes.conf` + `tags.conf`):本项目狩猎的每个 BOTS v3 sourcetype 都被标记到 Authentication、Network Resolution、Endpoint 和 Change 数据模型中,因此这些数据可以驱动 `tstats` 并无缝接入 Enterprise Security。 - **Search macros**(`macros.conf`):`frothly_index`、`rfc1918(1)`、`cryptomining_pools`、`frothly_users` 定义了搜索所依赖的灵活可变部分。 - **Context lookups**(`lookups/`):`identities.csv`(员工/管理员/服务角色)和 `assets.csv`(主机所有者 + 关键程度),通过 `transforms.conf` 进行连接。 - **Dashboards**:一个触发状态概览,一个以实体为中心并使用查找数据丰富活动记录、支持钻取事件的**调查**看板,以及六个针对特定场景的仪表板。 CI 会导入测试固件,运行 `harness/run_detections.py` 以断言每个检测的 `fixture_expect`(`fires` 或 `silent`),并使用 `btool` 验证 Splunk 能否正确解析保存的搜索、宏、事件类型、标签和转换,从而确保交付的 app 不会失效或安装失败。 `docs/attack-navigator-layer.json` 层级文件可直接上传至 [ATT&CK Navigator](https://mitre-attack.github.io/attack-navigator/)(“Open Existing Layer”),并根据场景覆盖率进行了评分。 ## 截图 所有仪表板均基于真实的 BOTS v3 数据集渲染。触发状态概览展示了六个场景中每个检测对应的 KPI;红色表示已触发,绿色表示无误报的真阴性。 [![触发状态概览](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/c75978df4e084648.png)](docs/img/overview.png) 六个特定场景看板均可直接钻取至底层事件: | | | | |---|---|---| | [AWS 侦察 (01)](docs/img/aws-recon.png) | [BSTOLL-L 端点 (02)](docs/img/endpoint-logon.png) | [Coinhive 加密劫持 (03)](docs/img/coinhive.png) | | [PowerShell 植入 (04)](docs/img/powershell-implant.png) | [Azure AD 登录 (05)](docs/img/azure-ad-signin.png) | [O365 账户滥用 (06)](docs/img/o365-account-abuse.png) | ## 本地开发 前置条件:Docker Desktop(或原生 Splunk)、Python 3.13、[uv](https://github.com/astral-sh/uv)。 ``` uv sync docker compose -f docker/compose.yml up -d ``` Splunk Web 位于 。开发环境的管理员密码为 `changeme`(可通过设置 `SPLUNK_PASSWORD` 环境变量覆盖)。首次运行时,请通过 Manage Apps → Install from file 安装 BOTSv3 app;安装包位于 。 针对运行中的 Splunk 运行所有记录在案的网络狩猎,然后断言检测是否触发(或保持静默): ``` uv run python harness/run_hunts.py uv run python harness/run_detections.py ``` 所有 25 个网络狩猎不仅针对 CI 固件,更是基于完整的 BOTS v3 数据集进行了验证。端点和网络场景(03 `stream:dns`、04 Sysmon)需要标准的 Splunk add-on 来解析这些 sourcetype(`Splunk_TA_microsoft-sysmon`、`Splunk_Stream`);官方的 BOTS v3 发行版已包含它们。云场景(AWS CloudTrail、O365、Azure AD)无需额外的 add-on 即可解析。 重新生成已提交的构建产物(覆盖率页面、HTML 报告、ATT&CK Navigator 层级文件、Splunk app): ``` uv run python harness/attack_aggregate.py # docs/attack-coverage.md (gitignored) uv run python harness/build_report.py # docs/index.html uv run python harness/build_attack_layer.py # docs/attack-navigator-layer.json uv run python harness/build_splunk_app.py # splunk_app/froth_bots_hunts/ ``` HTML 报告是一个独立的单文件。你可以在本地提供其访问服务,或者使用 GitHub Pages 发布它(Settings → Pages → `main` / `docs`)。 ## CI 包含三个工作流,会在 push 和 PR 时触发: `hunts.yml` 包含两个作业: - **lint**(约 1 分钟):ruff(包含 `S`/flake8-bandit 安全规则)、mypy strict、带有覆盖率门槛的 pytest(纯 Python 路径最低要求 50%)。 - **validate**(约 3 分钟,在 lint 通过后运行):在 Docker 中启动 Splunk,通过 HEC 导入每个场景的测试固件,通过 REST 运行每个网络狩猎的 SPL,断言每个答案,并使用 `btool` 验证生成的 app。 `security.yml` 是专用的安全门禁(在 push、PR 以及每周定时运行): - 针对 Python 的 **bandit** SAST 以及针对锁定依赖项的 **pip-audit**。 - 跨工作目录和完整 git 历史记录的 **gitleaks** 密钥扫描。 - **zizmor** GitHub Actions 工作流安全审计。 `codeql.yml` 运行针对 Python 的 CodeQL 静态分析(当仓库公开时会自动启用)。 所有第三方 actions 均通过 SHA 锁定版本,checkout 设置 `persist-credentials: false`,工作流声明了最小权限的 `permissions:` 块,Splunk CI 镜像通过摘要锁定,并且 Dependabot 保持 actions 和依赖项处于最新状态。请参阅 [SECURITY.md](SECURITY.md)。 ## 安全说明 - 仓库中的凭证仅用于开发:`changeme`/`Chang3me!` 密码,固定的 HEC token `00000000-...`。切勿在 CI 或本地沙箱之外重复使用它们。它们已在 `.gitleaks.toml` 中被列入白名单,作为已知的非敏感信息。 - Python 脚手架仅在针对本地主机 Splunk Docker 镜像时禁用了 TLS 验证(`verify=False`),该镜像在其 mgmt 和 HEC 端点上提供自签名证书。出于此原因,Bandit 的 `B501` 检查被抑制,该范围在 `pyproject.toml` 中定义;部署的 Splunk app 不包含任何 Python 代码,也不进行任何外部调用。 - HTTP-IO 函数上的覆盖率通过 `pragma: no cover` 排除;这些路径由 `validate` CI 作业针对真实的 Splunk 容器进行端到端测试,而不是使用 mock 进行单元测试。 - 网络狩猎固件是 BOTSv3 公开数据(如合成的 AWS 密钥等)的切片,已列入密钥扫描器的白名单。仓库中的任何内容均不包含真实的客户或生产环境遥测数据。 ## 状态 已交付六个场景:包含 25 个网络狩猎和 9 个可部署的检测,涵盖了 19 项 ATT&CK 技术。前三个场景遵循同一条线索:被入侵的 `bstoll` AWS 账户(01),排除了 `BSTOLL-L` 上的远程端点入侵(02),并发现了将攻击者的 JavaScript 注入该笔记本电脑的浏览器加密劫持(03)。场景 04 转向第二台被入侵的主机 `FYODOR-L`,其正在运行无文件 PowerShell 植入。场景 05 跟踪同一个 `fyodor` 身份离开端点进入 Azure AD,凭证从香港的 VPS 登录。场景 06 停留在云端,使用 O365 管理日志展示被盗的 `bgist` 和 `fyodor` 账户在内部进行的操作:`bgist` 通过同一香港 IP 的匿名共享链接暴露了一个 `.lnk` 诱饵,而 `fyodor` 对同事执行了 `Set-Mailbox` 操作,禁用了其中一个账户。生成于 `docs/index.html` 的 HTML 报告索引了每个场景、狩猎、检测和 ATT&CK 技术。随着对数据集分析的深入,我们将添加更多内容。 网络狩猎使用 `index=*` 编写,因此它们既可以针对真实的 `index=botsv3` 运行,也可以针对 CI 固件索引运行;而生成的检测在部署时被限定在 `index=botsv3`。
标签:入侵调查, 安全数据分析, 开源框架, 持续集成, 请求拦截, 逆向工具