mjha-arya/DOC-foundry
GitHub: mjha-arya/DOC-foundry
基于多 Agent 对抗工作流的检测规则自动化工程平台,将威胁情报转化为经蓝红对抗验证的 Sigma 检测规则及完整证据包与审查记录。
Stars: 0 | Forks: 0
# Detection-as-Code Foundry
### 对抗式多 Agent 检测工程工作流 — LangGraph · Pydantic · FastMCP · Claude
将一个威胁(一个 CVE、一个 CISA KEV 条目、一份事件报告、或一个 ATT&CK 技术)
转化为一个**经验证的初版检测**——一个供检测团队进一步加固的可靠起点,而非声称这是最终、永远无敌的防御方案——外加
**三个一起交付的工件**:
1. 一条在蓝红对抗循环中存活的 **Sigma 检测规则**,
2. 一份包含逐轮**收敛历史**的**威胁报告**,以及
3. 一个**证据包**——规则能命中的正样本语料库、它能对其中保持静默的良性基线、一组对抗性变体,以及一个**计算出的覆盖率标签**
(`real-coverage` / `brittle` / `broken`),附带 FP/FN 数据和可复现哈希。
别人无法产出的东西是 #3。模型可以为你写出一条 Sigma 规则;但它无法交给你规则有效的*证据*,一个能*被证明*绕过其脆弱版本的对手,以及一份关于规则如何被加固至稳固的诚实记录。
**两条 pipeline 共享这套 Agent 阵容。** 上面描述的那条是用于**证明**的——蓝队编写,红队攻击,确定性的裁判来做决定。
[**Review Chain**](#the-review-chain--a-second-different-pipeline---chain-and-the-default-ui)
则是用于**审查**的——草稿 → Red Team → 修改 → SOC Lead → 最终规则,并附带塑造该规则的每一条记录。不同的问题,不同的交付物;根据你的需求进行选择。
📄 **先看真实输出:**
[`examples/joomla-icagenda-cve-2026-48939/review-history.md`](examples/joomla-icagenda-cve-2026-48939/review-history.md)
— 对 CISA KEV 条目的一次真实运行,包含三个规则版本和八条审查意见。
## 运行它
```
pip install -r requirements.txt # or just run --evals on stdlib alone
# LIVE — 任意威胁文本;由真实模型生成(需要 GEMINI_API_KEY 或 ANTHROPIC_API_KEY)
python src/run.py "CVE-2026-45659 SharePoint deserialization RCE"
python src/run.py "T1218.011 rundll32 remote scriptlet execution via mshtml"
# CANNED — 固定场景,完全离线,无需密钥(由测试套件驱动)
python src/run.py --threat fixtures/certutil_t1105.json # brittle→repair→proven
python src/run.py --corpus atomic # positives from REAL Atomic Red Team commands
python src/run.py --max-rounds 3 # self-repair loop cap (default 3)
python src/run.py --evals # deterministic engine + proof + workflow tests
python src/run.py --approve alice # human approves → gated deploy succeeds
python src/run.py --claude "..." # force claude-opus-4-8 authoring (ANTHROPIC_API_KEY)
python src/run.py --gemini "..." # force Gemini authoring (GEMINI_API_KEY)
```
**没有默认场景**——Foundry 只处理你提供的威胁。单独运行
`python src/run.py` 没有任何输入可用,程序也会这样提示你。
生成的数据包会写入 `Outputs//`(`rule.yml`、`report.md`、`proof.json`)。
## Review Chain — 第二条、不同的 pipeline(`--chain`,也是默认 UI)
上面的 pipeline 询问的是*“这条规则可证明是正确的吗?”*,并用一个
确定性的判定来回答。**Review Chain** 问的则是另一个问题——*“每个利益相关者会对这条规则说什么,以及应用了他们的反馈后规则会变成什么样?”*——并用**最终规则加上塑造它的完整轨迹**来回答。
```
ingest ─▶ extract ─▶ telemetry ─▶ profile
─▶ Blue: DRAFT v1
─▶ RED TEAM review (findings: where is this evadable / blind)
─▶ Blue: REVISION v2 (each edit cites the finding id it answers)
─▶ SOC LEAD review (findings: volume, triage, severity, tuning)
─▶ Blue: FINAL v3
─▶ package
```
```
python src/run.py --chain "CVE-2026-48939 Joomla iCagenda arbitrary file upload RCE"
python -m uvicorn webui.server:app --port 8000 # → http://127.0.0.1:8000 (chain UI)
# → /classic for the proof loop above
```
Red 和 SOC 并不是同一个审查者戴的两顶帽子——他们朝**相反**的
方向施力。针对规避进行加固会使规则变宽泛;而变宽泛会提高告警量。
按那个顺序运行这两者正是关键所在:最终的规则是同时挺过这两种
压力的幸存者,而审查轨迹准确展示了每一轮付出的代价。
输出会存放在 `Outputs//` 中,命名为 `final-rule.yml`、`review-history.md`
(完整进展的渲染版)和 `review.json`。
### 一个实例 —— 阅读实际输出
**→ [`examples/joomla-icagenda-cve-2026-48939/`](examples/joomla-icagenda-cve-2026-48939/)**
— 针对 CVE-2026-48939(Joomla iCagenda upload-to-RCE,CISA KEV)的一次真实运行,由
`claude-opus-4-8` 编写。三个规则版本、八项发现、完整的审查轨迹:
[`review-history.md`](examples/joomla-icagenda-cve-2026-48939/review-history.md)。
蓝队的初版规则针对一个 Web daemon 派生出一个**运行侦察命令**的 shell 时触发了。
两名审查者从相反的方向将其拆解了:
Red 促使蓝队**放宽**规则;SOC Lead 则直接将其推回去要求**收紧**。
这种张力就是这个产品的意义所在:针对规避进行加固会增加告警量,而
最终规则是同时挺过这两种压力的幸存者。SOC 最后审查,因此交付的产物是
针对处理队列调优过的——v3 强制要求父进程血缘、排除了已知良好的解释器链、
扩展了分诊字段、降级为 `level: medium`,并附带了一份带有遏制阈值的三步响应手册。
## Demo UI (`webui/`) — 实时编写,观看 Agent 工作
```
python -m uvicorn webui.server:app --port 8000
# → http://127.0.0.1:8000 ;输入任意威胁,观察 loop 运行
python tools/warm_cache.py "the exact threat you'll demo" # optional — see below
```
基于**真实** graph 的 FastAPI + SSE。两路数据流交替进行,且都不是
预设好的:**节点事件**在某个 graph 节点真正完成时触发,而**token 事件**
通过 `providers.py` 上的 token 汇集点,*在生成的同时*流式传输每个 Agent 的原始模型输出。
graph 之所以运行在 worker 线程上,正是因为 token 会在节点执行中途到达;它们之间的队列是唯一的耦合,且是单向的。
你会看到:LangGraph 结构在动(运行中的节点在发光,指向它的边在流动,**在修复轮次中回环弧线会闪烁红光**),Agent 控制台逐字打出模型当前正在生成的内容,Sigma 规则逐行编写自身,以及最后收敛时间线、Kartikeya 关卡和可复现哈希的呈现。
**它进行实时编写 —— UI 中没有预设,也没有 fixture/重放路径**,所以任何
威胁都适用。确定性源于 `providers.py` 的磁盘缓存:温度为 0,
以 `sha256(model|system|user)` 为键,因此重新运行*相同的威胁文本*会逐字节重放完全相同的模型输出 → 相同的规则 → 相同的数据包哈希。冷运行的延迟完全
取决于模型(在 `gemini-flash-lite` 上进行 3 轮收敛大约需要 20-40 秒;
更大的模型需要几分钟)。`warm_cache.py` 会为你计划演示的威胁提前支付这笔延迟开销。
## 架构 — 蓝队 vs. 红队、确定性的裁判与自修复循环
```
ingest ─▶ extract ─▶ telemetry (Analyst normalizes; Telemetry fixes the test set)
│
▼
┌──────────────── SELF-REPAIR LOOP (LangGraph conditional edges) ─────────────────┐
│ │
│ blue_author ─▶ evaluate ─▶ battery ─▶ red_propose ─▶ red_verify ─▶ verdict │
│ ▲ (FP/FN) (mutation (Red-Team (engine- (coverage) │
│ │ │ battery) proposes) verifies) │ │
│ │ └── un-evaluable rule ─────────────────────────────┤ │
│ │ (engine refuses → broken, skip the round) │ │
│ └───────────────── repair: verdict ≠ real-coverage ◀────────────┘ │
│ │ │
└──────────────────────────── done: real-coverage OR round == cap ──────┘ │
▼
gate ─▶ bundle
[ blue/red/telemetry/analyst = LLM agents — PROPOSE ]
[ evaluate·battery·red_verify·verdict·gate = deterministic referee — PROVE ]
```
- **Agents (`src/agents.py`)** — 四种不同的角色。**蓝队检测
工程师**编写出在构建上就具备稳健性的初版规则(基于行为 + 命令行
意图,而非单一的脆弱字符串),并在收到脆弱/损坏判定时,利用*具体的*
证据(确切的规避手段 + 误报)重写规则。**Red-Team 对抗者**
在第一轮承诺实施**两种真实的、有文档记录的攻击**,并在每一轮将*同样的这两种*
攻击重新投向加固后的规则——这是一个固定的对抗性测试集,而不是每一轮都进行新的
突袭,因此蓝队关闭了一对有限的漏洞,从而能够实现真实的收敛。
- **研究基础 (`src/knowledge_base.py`` + `rule_corpus/`)** — 一个双分区
**RAG** 知识库,将两个提案者都植根于真实的、由研究员编写的 OSS 之中:
蓝队基于经过同行评审的 **SigmaHQ** 规则进行编写;红队则基于 **MITRE ATT&CK**
防御规避(例如 **T1036.003 Rename System Utilities**)和 **LOLBAS** 发起攻击。
检索器是词法层面的 (BM25),完全离线且具备确定性。它仅为*提案*提供基础依据——它从不触及证明引擎,也从不计入可复现哈希。
- **`src/engine.py`** — 确定性的 Sigma 匹配器(证明核心)。零依赖。
诚实契约:对于它无法真实评估的结构(`|cidr`、
聚合操作、像模型喜欢凭空发明的那种 `|in`),它会直接*抛出异常*,而不是静默通过——
一条无法评估的规则永远不会被评为“已覆盖”。该循环将其视为一个
**broken** 轮次,并将引擎自身的提示信息作为修复
证据交还给蓝队,因此一条无法运行的规则只会消耗一轮,而不是整个运行。
- **`src/evaluator.py`** — FP/FN 评估 + 一个确定性的**对抗性变异**
测试组(binary-rename、casing、whitespace、caret/quote obfuscation、path
relocation),以及 `merge_redteam()`,后者将**引擎验证过的** Red-Team
规避手段折叠进同一个判定中。脆弱性是*测量*出来的,而不是猜出来的。
- **`src/graph.py`** — 循环本体。`red_verify` 会将每一个 Red-Team 事件通过
引擎重放:**只有在引擎确认规则未能触发时,绕过才算数。**
未经验证的提案会被丢弃——对手无法单方面断言发生了绕过。
- **`src/governance.py`** — **Kartikeya's Gate = Blast Radius × Capability Delta**。
那些极具说服力的模型也无法辩驳的结构性不变量:*egress 始终
需要人工介入*,且*非真实的覆盖率底线会判定 blast radius*。
- **`src/mcp_server.py`** — 受治理的工具边界。Graph 既不能获取也不能
部署;`deploy_detection` 会拒绝任何未绑定到确切
数据包哈希的批准 token。**持有特权的是测试框架,而不是 Agent。**
## 预设场景揭示了真相(两轮收敛)
`python src/run.py --threat fixtures/certutil_t1105.json` — 离线,无密钥:
- **Round 1** — 蓝队锚定在 `Image` 路径上。确定性测试组命中了
**binary-rename** 绕过,且 Red-Team 命中了一个真实世界的变体(certutil
被复制为 `AdobeUpdater.exe`),经引擎验证 → 判定为 **BRITTLE** → 循环回退。
- **Round 2** — 蓝队基于防重命名的 `OriginalFileName` 重写规则。测试组
未检测到任何规避,且**相同的** Red-Team 重命名现在被**引擎丢弃**,因为
规则触发了它 → 判定为 **REAL-COVERAGE** → Kartikeya's Gate → 数据包。
报告展示了完整的轨迹(规则 v1 脆弱 → 规避 → 规则 v2 已验证)。这就是
Foundry 对一条*看起来*没问题但实际上有缺陷的规则保持诚实的态度——然后修复它并证明修复是有效的。
这个场景是一个 **fixture**,而不是 demo:它的存在是为了让工作流能离线运行,
并且测试套件有一个确定性的端到端用例。UI 从不触碰它。一个真实的
威胁能否凭借自身价值收敛就是能不能——而“不能”是 Foundry
被构建出来如实报告而非掩盖的真实结果。
## 每次运行仅限一个日志源
Analyst 针对每个行为生成的日志源会为运行选举出单一的类别(多数表决);
Telemetry agent 基于该类别构建固定的语料库,同时告知蓝队该类别
以及语料库携带的确切**字段名**。蓝队看不到任何事件值,也
没有标签,因此它无法过拟合——它只是无法对遥测中不存在的字段进行键控,这会自动导致一次 recall-0 的 `broken` 轮次,且原因与检测质量毫无关系。(一条锚定在 `TargetFilename` 上的规则永远无法在进程创建事件上触发。)
## Kartikeya 对齐
这就是应用于检测工程的 [Shiva/Kartikeya](../README.md) 理论:
部署一个检测是一项**能力请求**(通往 SIEM 的 egress),在任何人
被打扰之前,都要通过 `Gate = Blast Radius × Capability Delta` 进行评分——并且 *没有*
任何自主路径可以推送规则。最小权限和人工把关的 egress 是在代码中计算和
强制执行的,而不是在 prompt 中声明的。
_完全离线/确定性运行。其兄弟项目 senior-security-engineering-agent
使用 Gemini 进行旁白;而 Foundry 使用 Claude 编写——但在两者中,模型仅负责
提案,而证明过程是确定性的。_
## OSS 集成(它所接入的生态系统)
Foundry 的**证明核心**(`engine.py → evaluator.py → governance.py`)是确定性的,并且
是自包含的。它的**接缝**——摄取、编写、转换、测试语料库、部署、报告——被设计为
由开源检测源提供数据:
- [`docs/OSS-PARTNERS.md`](docs/OSS-PARTNERS.md) — 规范的合作伙伴目录:每个 repo 都映射到该
工具实际的 pipeline 阶段,并附带优先级、集成点和**开源许可状态**。
- [`docs/OSS-INTEGRATION-MINDMAP.md`](docs/OSS-INTEGRATION-MINDMAP.md) — 完整的研究图谱。
**首次接入(最高价值):** Atomic Red Team → 正向语料库 + EVTX-ATTACK-SAMPLES → 良性
基线,这样对抗性测试组就能针对*真实*的攻击遥测数据运行。然后是 pySigma + SigmAIQ,用于
多 SIEM 的编写/转换(为此已经预留了 `SigmaRuleArtifact.backends` 插槽)。
标签:AI智能体, Sigma规则, 安全运营, 扫描框架, 目标导入, 逆向工具