Joaquin7gg/soc-triage-agent

GitHub: Joaquin7gg/soc-triage-agent

本地离线的 SOC 日志分诊 Agent,采用「确定性代码检测+本地 LLM 撰写报告」的架构,在不泄露数据的前提下自动分析 SSH 和防火墙日志并映射 MITRE ATT&CK。

Stars: 0 | Forks: 0

# SOC Log Triage Agent · SOC 日志分诊 Agent 一个**本地且离线**的 AI Agent,像 SOC 分析师的 第一步操作那样对安全日志进行分诊:检测攻击模式,将其映射到 **MITRE ATT&CK** 并撰写报告。一切都在你的机器上完成,数据不会 泄露到云端。 它能理解 **SSH** (`auth.log`) 和 **Windows 防火墙** (`pfirewall.log`) 日志,无需你告诉它,就能自动区分你提供的是哪种日志。 ## 为什么要做这个项目? 安全日志包含 IP、用户和访问模式:属于 **GDPR 框架下的个人数据**。它们不应被发送到云服务。因此该 Agent **100% 在本地运行**。在这里,“本地”不是一个技术上的执念,而是 隐私要求——这也是让整个项目有意义的核心论点。 专为在普通硬件上运行而设计:已在配备 **4 GB VRAM 的 RTX 3050** 的笔记本(i5-11400H,32 GB RAM,Windows)上测试过。在此环境下,它能以 52-56 tokens/s 的速度在 **15-25 秒内**生成一份完整的 报告,且整个模型完全在显卡上运行。 ## 核心理念:代码检测,AI 叙述 - **Python 代码(确定性)**负责检测:统计登录失败次数、 交叉比对 IP、检查时间。结果精准且可复现。 - **本地模型(LLM)**仅负责撰写报告和优先级排序。它不进行任何检测, 从而避免小模型产生幻觉。 这种分工也是真实 SOC 产品的运作方式:LLM 协助 检测器,而不是取代它。详见 [`docs/arquitectura.md`](docs/arquitectura.md)。 ## 有效果吗?用测量说话,而非承诺 任何人都可以说“我用本地 LLM 来生成安全报告”。但有趣的 问题是模型是否会胡编乱造。本项目附带了一个**评估框架** (`src/eval.py`),它会将报告运行 N 次并使用 确定性的 Python 进行检查——不存在让一个 LLM 给另一个 LLM 打分的情况。 使用 **Llama 3.2 3B Instruct Q4_K_M**,对三种测试日志 分别进行了 20 次运行。每个日志测试点都不同:基准测试案例、密集案例(当报告变长时会遗漏发现吗?),以及一种**不同格式**的案例 (面对非 SSH 日志它能撑住吗?)。 | 检查项 | `auth.log`
SSH,6 个发现 | `auth_intenso.log`
SSH,11 个发现 | `pfirewall.log`
防火墙,8 个发现 | |---|---|---|---| | **无捏造的 IP** | **20/20** | **20/20** | **20/20** | | **无捏造的 MITRE 代码** | **20/20** | **20/20** | **20/20** | | 提及所有 MITRE 技术 | 20/20 | 20/20 | 20/20 | | 严重性排序正确 | 20/20 | 20/20 | 20/20 | | 报告结构有效 | 20/20 | 20/20 | 20/20 | | 提及所有检测到的 IP | 20/20 | 20/20 | 19/20 | | 标注严重性 | 18/20 | 18/20 | 15/20 | | **完全没有错误的报告** | **18/20** | **18/20** | **15/20** | 最上面两行是关键:**在 60 份报告中,模型没有产生过一次幻觉。**这不是因为它是一个多好的模型(它只是一个量化的 3B 模型),而是因为 架构没有给它捏造的机会:它接收到的是已经被检测、丰富并 排序好的发现,它只需要将其写出来。防火墙格式是在 **完全没有改动一行 AI 部分代码** 的情况下添加的,模型遇到了 新概念——端口、DROP/ALLOW、侦察技术、两个它从未见过的 MITRE 代码——却没有捏造任何一个。 **目前未解决的缺陷**是严重性标注:有些报告没有说明 任何发现的严重程度。数据和顺序都是正确的,但这迫使 分析师通过阅读来推断。测量结果指向了一个具体原因:**失败的都是较短的报告。**在防火墙日志中,出错的报告平均耗时 15.7 秒、长 3100 字符;而正确的报告平均耗时 21.8 秒、长 4000 字符。当模型进行简化时,它最先丢弃的就是标签。 结果有意使用计数而不是百分比表示:两次完全相同的 运行会得出不同的数字,在错误不频繁的情况下,20 次执行只能 给出一个数量级,而不是一个确切数值。写“90%”只是一种虚假的精确。 ### 如果我们让模型自己来组织会怎样? 显而易见的问题:一个真正的“Agent”会自己选择工具,为什么这里的 流程是固定的?这个项目以前只是声称如此而没有实际测量。现在已经测量过了——有一个 完整的自主模式 (`src/autonomo.py`) 经过了同样的测试: ``` python src/eval.py --autonomo ``` | | 编排式 | 自主式 | |---|---|---| | **完全没有错误的报告** | **18/20** | **0/10** | | 成功写出报告 | 20/20 | 2/10 | | 未重复调用 | 设计使然 | 0/10 | | 遵守顺序(先读后测) | 设计使然 | 10/10 | **十分之零**,这还是在每轮给 3 次重试机会且提供无参数 工具来简化任务的情况下。所有 10 次执行都卡在了连续 3 到 11 次 调用同一个工具上,完全无视了返回结果告诉它们 没有任何改变。 有趣的是它**确实**能做到的事情:在遵守顺序上得了 10/10。它从未 试图在读取日志之前进行检测。这不是说它不理解任务——而是 它无法将协议维持足够长的时间以完成它。 这个结论的客观局限,以及为什么它没有断言“小模型不适合做 Agent”,详见 [`docs/arquitectura.md`](docs/arquitectura.md)。 这个框架也能用来测试那些令人尴尬的情况,而这正是核心所在: - 一个看似无害的 prompt 修改将 MITRE 覆盖率从 **90% 暴跌到 5%**,这仅仅是因为有测量工具才被发现。 - 一项检查**挂起了完美无瑕的报告**,因为它的摘要里写着 “按从高到低排序”,而 regex 把这些词算作了发现的标签。 - 同样的检查又出现了**过度通过**的情况,导致本 README 中发布的 数据虚高,直到后来才被修复。一个误判的失败会让你去读报告;而一个误判的通过会让你掉以轻心。这源于同一个 bug,但只有 一个会引起注意。 所有这些问题都是在**阅读报告**时发现的,而不是通过查看百分比。评估 框架也会出错。 这两个故事、测量的局限性以及为什么按严重性排序由 Python 而不是 AI 来做,详见 [`docs/arquitectura.md`](docs/arquitectura.md)。 ## 检测内容 Agent **会根据文件内容自动区分格式**,无需 告诉你提供的是什么。 ### SSH 日志 (`auth.log`) | 检测项 | 严重性 | MITRE ATT&CK | |-----------|-----------|--------------| | 暴力破解(同一 IP 大量登录失败) | 中 | T1110 Brute Force | | 潜在失陷(多次失败后登录成功) | 高 | T1110 + T1078 | | 异常时间登录(凌晨) | 低 | T1078 Valid Accounts | ### Windows 防火墙日志 (`pfirewall.log`) 防火墙看不到用户或密码:它只能看到允许和阻止的连接。 因此检测模式有所不同——主要针对**侦察**,即在攻击前窥探内部情况。 | 检测项 | 严重性 | MITRE ATT&CK | |-----------|-----------|--------------| | 端口扫描(阻止对一台机器大量端口的访问) | 中 | T1046 Network Service Discovery | | 网络扫描(阻止对大量机器的访问) | 中 | T1018 Remote System Discovery | | 阻断后的访问(大量 DROP 后出现 ALLOW) | 高 | T1110 + T1021 | | 反弹 Shell(**向曾经攻击过我们的 IP**连接到异常端口) | 高 | T1571 + T1219 | | 连接异常端口(相同模式,目标无前科) | 中 | T1571 Non-Standard Port | | 允许连接敏感端口(RDP, SMB, SSH, WinRM) | 低 | T1021 Remote Services | 中间两行出自**同一个检测器**,它们之间的区别 最能解释这个项目:网络数据包完全相同,但其中一个指向的是 刚刚在尝试暴力破解的 IP,另一个则不是。这种关联——将第 50 行的出站连接与第 40 行的拦截记录进行交叉比对——Python 只用 三行代码就能完成。而 3B 模型十次里有九次都无法可靠地做到。 ## 使用方法(摘要) ``` pip install -r requirements.txt python src/agent.py # analiza data/auth.log python src/agent.py --sin-ia # solo detección, sin el modelo python src/eval.py -n 20 # mide la fiabilidad del modelo (20 ejecuciones) python src/eval.py --todos # evalúa la suite de logs y compara resultados ``` 生成一份报告 (`informe.md`) 和一份审计追踪 (`audit.jsonl`)。 评估框架会将其结果保存在 `eval_resultados*.json` 中。 完整的安装指南见 [`INSTALL.md`](INSTALL.md)。 ## 结构 ``` soc-triage-agent/ ├── src/ │ ├── agent.py # orquestador (el "bucle") │ ├── tools.py # parsers + detección determinista (SSH y firewall) │ ├── mitre.py # mapeo a MITRE ATT&CK (una tabla por formato) │ ├── llm.py # cliente del modelo local (LM Studio) │ ├── audit.py # registro de auditoría │ ├── eval.py # harness de evaluación (mide al modelo) │ └── autonomo.py # bucle autónomo: experimento de control, no el modo normal ├── data/ # logs SINTÉTICOS de prueba ├── docs/ # arquitectura y decisiones ├── GUIA_CASTELLANO.md # explicación sin tecnicismos └── INSTALL.md # instalación paso a paso ``` ## 局限性(坦诚说明) 本项目是一个**学习练习**,其价值在于 架构和工程判断,而不在于模型的强大程度: - 运行在 **~4B** 的模型上(受限于 4 GB VRAM)。流程 特意设计为编排式的,且该决定是有**数据支撑的**:自主模式的得分为 0/10,而编排式为 18/20(见下文)。 - 检测器非常**简单且基于规则**。真实的 SOC 使用的是 复杂得多的关联引擎。 - 处理 SSH 和 Windows 防火墙日志。Windows 事件 (`Security.evtx`) 将是下一个自然支持的格式。 - 真正复杂的推理需要更多 VRAM 和更大的模型。 - **评估是对三种日志各进行 20 次执行。**涵盖了两种 格式和两种大小,但仍然没有涵盖包含数万个事件的日志。 - **已测量的上限:每份报告约 50 个发现。**这不是模型的问题:而是 8,192 token 的上下文窗口限制,这已经占用了 4 GB VRAM 的 80%。一个超大 的日志不会生成更差的报告——而是会导致 prompt 无法容纳。具体数字和 三种可能的输出详见 [`docs/arquitectura.md`](docs/arquitectura.md)。 - **评估框架不衡量建议是否有用**,只检查数据 是否正确。评判行文质量需要一个 LLM 来评估另一个 LLM,而这将违背项目的原则。这是已知的局限。 这种坦诚是故意的:目标是展示工程判断力, 而不是忽悠。 ## 路线图 - [x] 评估框架:测量模型生成正确报告的频率。 - [x] 包含多种日志的评估套件及它们之间的对比。 - [x] 支持 Windows 防火墙日志,包含自动格式检测 和专属的 MITRE 表。 - [ ] 修复严重性标注:约 20 份报告中有 2 份遗漏了该信息。 已测量,可复现,待修复。 - [x] 反弹 Shell 检测器(向曾经攻击过我们的 IP 连接非标准端口)。关联了两个时间上独立的事件。 - [ ] 将 Windows 事件 (`Security.evtx`) 作为第三种格式。 - [x] “自主循环”模式,用于与编排模式进行对比,**已测量**:0/10 对 18/20。 - [ ] 包含数万个事件的测试日志。已测量的预测:将在约 50 个 发现时崩溃,原因是上下文窗口而非模型质量。如果预测 成真,解决方案是将发现分页(代码),而不是使用更大的模型。 - [ ] 使用更大的模型重复自主/编排模式的对比,以 区分“模型做不到”和“这套架构太脆弱”。 ## 许可证 [MIT](LICENSE) — © 2026 Joaquin Luis Garcia Garcia。可以自由使用、修改和 分享;只需保留版权声明即可。 ## 免责声明 教育性和防御性(蓝队)工具。仅使用**合成数据**。 切勿将真实日志或个人数据上传到代码库。 本项目的部分开发借助了 AI 辅助。 ## English 一个**本地、离线**的 AI Agent,像 SOC 分析师的 第一步操作那样对安全日志进行分诊:它检测攻击模式,将其映射到 **MITRE ATT&CK**,并撰写 报告——一切都在你的机器上完成,数据不会发送到云端。 **为什么在本地运行?**安全日志包含 IP、用户名和访问模式—— 属于 GDPR 下的个人数据。它们不应该发送到云服务。在本地运行 不是一个随念头,这是隐私要求。 **核心理念——代码检测,AI 叙述:**确定性的 Python 负责检测 (统计登录失败次数、关联 IP、检查时间戳);本地 LLM 仅负责撰写和确定报告的优先级。这反映了真实 SOC 产品的运作方式:LLM 辅助检测器,而不是取代它。 **有效果吗?用测量说话,而非承诺。**本项目提供了一个评估框架 (`src/eval.py`),它会将报告运行 N 次并使用确定性的 Python 进行检查——不存在 LLM 给 LLM 打分的情况。它针对两种截然不同的 日志进行了运行——一个基准测试、一个密集型测试,以及一个**不同格式**的日志——这样每一个测试都能探查其他测试涉及不到的地方。在使用 Llama 3.2 3B Instruct Q4_K_M 的 60 多次运行中,该模型**没有捏造任何 IP,也没有捏造任何 MITRE 技术代码**,并且在覆盖每个发现、按严重性排序和报告结构方面均获得了 20/20 的满分。这不是因为它是一个强大的模型——它只是一个量化的 3B 模型——而是因为架构从未给它提供胡编乱造的机会:它接收到的是已经检测、丰富并排序好的发现,只需将它们写出来即可。 防火墙这一列证明了这个设计的正确性:该格式是 在**没有改动 AI 层任何一行代码** 的情况下添加的,且模型处理了它以前从未见过的概念——端口、DROP/ALLOW、侦察技术——20 次测试 20 次成功。增加一种格式意味着编写一个解析器和一些检测器;LLM 永远不知道这件事。仍然存在一个缺陷:大约 20 份 SSH 报告中有 2 份遗漏了严重性标签。 结果有意以计数而非百分比的形式给出——两次完全相同的 20 次运行批次的数据会有所不同,因此 20 次运行给你的是一个数量级,而不是一个确切数字。而且有一段时间,发布出来的数据完全是错的:标注检查把摘要中的散文当成了标签,导致**通过了那些什么都没标注的报告**。一个误判的通过会让你掉以轻心,让你的 README 数据虚高;而一个误判的失败至少会促使你去阅读报告。这两个问题源于同一个 bug。 这个框架在处理那些令人尴尬的用例时发挥了价值,这才是关键所在:一个看似无害的 prompt 修改曾经导致 MITRE 覆盖率从 90% 下降到 5%,而其中一项检查指控模型犯了一个它从未犯过的错误。这两个问题之所以被发现,仅仅是因为有东西在测量——第二个问题只是因为阅读了报告而没有盲信数字才被发现的。关于细节和测量的局限性详见 [`docs/arquitectura.md`](docs/arquitectura.md)。 **目标硬件:**已在配备 **RTX 3050 (4 GB VRAM)** 和 32 GB RAM 的 Windows 笔记本上完成了目标测试。 请参阅 [`INSTALL.md`](INSTALL.md) 进行安装。仅使用**合成数据**——切勿提交真实日志或个人数据。本项目的部分内容是在 AI 辅助下构建的。
标签:ATT&CK映射, LLM, PE 加载器, Python, SOC日志分析, Unmanaged PE, 安全运营, 扫描框架, 无后门, 本地大模型, 红队行动, 自动化报告, 逆向工具, 速率限制处理