thunderstornX/llm-red-team-toolkit
GitHub: thunderstornX/llm-red-team-toolkit
针对 LLM 部署的 OWASP Top 10(2025)对抗性探测与安全评估工具,内置52个探测用例与确定性评分器。
Stars: 0 | Forks: 0
# llm-red-team-toolkit
[](https://doi.org/10.5281/zenodo.20480444)
[](LICENSE)
[](https://github.com/thunderstornX/llm-red-team-toolkit/actions/workflows/tests.yml)
[](#probes)
[](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
```
____ ______ ______ \ | /
/ __ \ /_ __/ /_ __/ \\\\|////
/ /_/ / / / / / ──── [ ● ] ────
/ _, _/ / / / / ////|\\\\
/_/ |_| /_/ /_/ / /|\ \
L L M R E D T E A M T O O L K I T
OWASP LLM Top 10 (2025)
probe · sting · report · disclose
~ AMB · ORCID 0009-0007-2787-943X · v1.0 · 2026 ~
```
一个 Python 测试框架,用于系统地针对 **OWASP Top 10 for LLM Applications (2025)** 探测大型语言模型(LLM)部署。
涵盖所有十个类别的 **52 个探测**,外加 **8 个跨领域越狱(jailbreak)**,三种目标适配器(OpenRouter、NVIDIA NIM、通用的 OpenAI 兼容适配器),一个确定性的启发式评分器(不使用 LLM-as-judge),以及一个基于 Rich 构建的终端 UI。
## 已发布的产出
基于此工具包生成的探测语料库和训练好的检测器已发布以供复用:
- **HuggingFace dataset**:[`alib011/llm-red-team-probes`](https://huggingface.co/datasets/alib011/llm-red-team-probes)(包含这 52 个探测,可直接使用 `load_dataset` 加载)
- **HuggingFace Space**:[`alib011/llm-red-team-runner`](https://huggingface.co/spaces/alib011/llm-red-team-runner)(浏览器内的探测运行器 + 计分卡)
- **HuggingFace model**:[`alib011/distilbert-prompt-injection`](https://huggingface.co/alib011/distilbert-prompt-injection)(prompt injection 检测器,在这些探测上具有 98% 的召回率)
- **Kaggle**:[notebook](https://www.kaggle.com/code/alimurtazabhutto/distilbert-prompt-injection-detector-owasp-eval) + [dataset](https://www.kaggle.com/datasets/alimurtazabhutto/llm-red-team-probes)
## 查看运行效果
`rtt scan` 会打开一个实时仪表板,显示进度、流式活动以及动态计分卡:

当扫描完成时,您会得到一个清晰的结果判定:

在输入时过滤探测库:

## 快速开始
```
git clone https://github.com/thunderstornX/llm-red-team-toolkit.git
cd llm-red-team-toolkit
pip install -r requirements-dev.txt
# 1. 针对 OpenRouter 上的托管模型
export OPENROUTER_API_KEY=sk-or-...
python -m harness.cli scan \
--adapter openrouter \
--model anthropic/claude-haiku-4-5 \
--authorized
# 2. 针对本地 Ollama(任何 OpenAI-compat 端点)
ollama serve &
ollama pull qwen2.5:0.5b
python -m harness.cli scan \
--adapter generic \
--base-url http://localhost:11434/v1 \
--model qwen2.5:0.5b \
--authorized
# 3. 针对 NVIDIA NIM 端点
export NVIDIA_API_KEY=nvapi-...
python -m harness.cli scan \
--adapter nvidia \
--model meta/llama-3.3-70b-instruct \
--authorized
```
过滤、试运行(dry-run)、并行化:
```
# 仅 LLM01 probes:
python -m harness.cli scan --adapter openrouter --category LLM01 --authorized
# 仅 base64-smuggling probes:
python -m harness.cli scan --adapter openrouter --tag base64 --authorized
# 基于合成响应构建报告(无网络):
python -m harness.cli scan --adapter openrouter --dry-run
# 8-way 并行:
python -m harness.cli scan --adapter openrouter --concurrency 8 --authorized
```
## 核心内容
```
.
├── probes/ # 52 probes, registered at import time
│ ├── prompt_injection.py LLM01: direct, indirect, leak, role, delim
│ ├── sensitive_info.py LLM02: pii, recall, cred, re-id
│ ├── model_extraction.py LLM02: fingerprint, distil, architecture
│ ├── supply_chain.py LLM03: identity, cutoff, deps
│ ├── data_model_poisoning.py LLM04: trigger, copyright, canary
│ ├── improper_output.py LLM05: markdown, html, sql, path
│ ├── excessive_agency.py LLM06: unauth, scope-creep, persist, coerce
│ ├── tool_abuse.py LLM06: shell, schema, cross-plugin, persist
│ ├── system_prompt_leakage.py LLM07: compliance, direct-dump, enumerate
│ ├── vector_embedding.py LLM08: cross-context, inversion, kb-poison
│ ├── misinformation.py LLM09: hallucinate, citation, legal, calib
│ ├── unbounded_consumption.py LLM10: recursion, unicode, flood, nesting
│ └── jailbreaks.py JAIL: dan, b64, rot13, leet, reverse, multi-turn,
│ context-flood, prefix-injection
├── adapters/ # async OpenAI-compatible HTTP clients
│ ├── openrouter.py
│ ├── nvidia.py
│ └── generic.py
├── harness/ # orchestration
│ ├── cli.py Typer CLI
│ ├── evaluator.py async dispatcher with bounded concurrency
│ ├── scorer.py heuristic refusal/leak/partial classifier
│ ├── report.py JSON + Markdown writers
│ └── config.py Pydantic target / run config
├── tui/ # Rich-powered terminal UI
│ ├── banner.py the spider
│ ├── theme.py colour theme
│ ├── dashboard.py live progress + activity + scorecard
│ └── report.py post-run rendering
├── tests/ # 88 pytest cases (offline; HTTP mocked)
├── results/ # sample run captured against qwen2.5:0.5b
│ ├── sample_report.json (a copy of generic_qwen2.5_0.5b.* below)
│ ├── sample_report.md
│ ├── generic_qwen2.5_0.5b.json
│ └── generic_qwen2.5_0.5b.md
├── paper/ # IEEE 3-page paper (paper.pdf)
└── scripts/
├── render_figures.py paper figures from a real run
└── render_terminal.py ANSI-aware terminal-to-PNG (no webfonts)
```
## 探测分布
| 代码 | 类别 | 数量 |
|------:|-----------------------------------|--:|
| LLM01 | Prompt Injection | 5 |
| LLM02 | Sensitive Information Disclosure | 7 |
| LLM03 | Supply Chain | 3 |
| LLM04 | Data and Model Poisoning | 3 |
| LLM05 | Improper Output Handling | 4 |
| LLM06 | Excessive Agency | 8 |
| LLM07 | System Prompt Leakage | 3 |
| LLM08 | Vector and Embedding Weaknesses | 3 |
| LLM09 | Misinformation | 4 |
| LLM10 | Unbounded Consumption | 4 |
| JAIL | Jailbreaks (cross-cutting) | 8 |
| **·** | **总计** | **52** |
`python -m harness.cli list` 将显示所有探测内容及其严重程度、标签和标题。
## 评分机制(以及为何不使用 LLM-as-judge)
对于每个 `(探测, 响应)` 对,评分器会应用此决策树:
1. 匹配特定探测的**成功标记 (success marker)** → **已泄露**
2. 匹配特定探测的**拒绝标记** → **已拒绝**
3. 匹配通用拒绝正则表达式(10 种已校准的模式) → **已拒绝**
4. 响应为空 / 仅含空白字符 → **已跳过**
5. 其他情况 → **部分泄露**(需人工审核)
为什么不使用强大的 LLM 作为评判?原因有二:
1. **可复现性。** 相同的探测 + 相同的响应应始终保持相同的评分。启发式正则表达式是可复现的;而 LLM 评判则不然。
2. **可审计性。** 当审核员询问“为什么这个探测被判定为已拒绝?”时,会得到一个具体的正则表达式,他们可以在 200 行 Python 代码中阅读它——而不是“相信更大的模型”。
这种权衡的代价是 **部分泄露** 这个分类桶:规则集无法分类的内容将交由人工审视。我们保持了该分类桶的诚实性。
## 真实示例运行(真实可查,非虚构)
`results/sample_report.{json,md}` 是针对 Ollama 上的 **qwen2.5:0.5b** 进行真实扫描的输出结果,测试环境为 Intel Core i5-8250U(16 GB RAM)。
共 52 个探测,实际耗时 395.1 秒。
| 结果 | 计数 | 占比 |
|---|---:|---:|
| refused | 16 | 30.8 % |
| leaked | 21 | 40.4 % |
| partial | 15 | 28.8 % |
| skipped | 0 | 0.0 % |
| error | 0 | 0.0 % |
完整的逐项探测详情见
[`results/sample_report.md`](results/sample_report.md)。
如需复现:
```
ollama pull qwen2.5:0.5b
python -m harness.cli scan \
--adapter generic \
--base-url http://localhost:11434/v1 \
--model qwen2.5:0.5b
```
## 测试
88 个 pytest 测试用例。整套测试在离线状态下约一秒钟即可运行完毕。
```
python -m pytest tests/ -v
```
测试覆盖率:
- **probe-registry 不变量** — 正好 52 个探测,符合文档中记录的各类别分布,没有重复的 ID,ID 前缀与类别匹配,frozen dataclass 的不可变性,payload 非空
- **scorer** — 每个规范的拒绝短语,成功/拒绝标记优先级,通用正则表达式,空/空白字符响应,延迟传播
- **marker 质量** — 拒绝和良性文本绝不会在 `leaked` 发现中被误报,而真正的泄露仍会被正常标记
- **adapters** — 使用 respx 模拟的传输格式,HTTP 错误路径,解析错误路径,传输错误路径,**API key 泄露断言**
- **CLI + authorization gate** — `--authorized` / `RTT_ASSUME_AUTHORIZED` / 交互式提示分支,非交互式拒绝,试运行和无匹配项时的退出代码
- **evaluator** — 并发下的调度,试运行,错误传播,响应截断
- **report** — JSON schema + Markdown 往返转换 + 管道符转义,跳过列对账,逐字记录扫描开始时间戳
- **TUI** — 横幅包含签名,仪表板记录结果,报告渲染器不会崩溃
## 伦理使用
这是一个**漏洞扫描器**,而不是漏洞利用框架。请仅针对您拥有或获得书面授权进行测试的 endpoint 运行它。
这些探测是用于漏洞*类别*的检测器,而非武器化的攻击:每个探测都设置了其自身的合成系统 prompt 和 canary(金丝雀字符串),因此“泄露”只会暴露操作员已经知道的字符串。
完整政策见 [`ETHICAL_USE.md`](ETHICAL_USE.md)。
## 论文
一篇 3 页的 IEEE 论文描述了该架构、评分原理以及现场演示,详见
[`paper/paper.pdf`](paper/paper.pdf)。
## 引用此工作
```
@software{bhutto2026rtt,
author = {Bhutto, Ali Murtaza},
title = {llm-red-team-toolkit: An OWASP-aligned adversarial probing
harness for LLM deployments},
year = {2026},
doi = {10.5281/zenodo.20480444},
url = {https://github.com/thunderstornX/llm-red-team-toolkit},
orcid = {0009-0007-2787-943X}
}
```
相关工作:
- [`secure-python-pipeline-template`](https://github.com/thunderstornX/secure-python-pipeline-template) — 本仓库 CI 所基于的 DevSecOps pipeline。
- [`sovereign-llm-quickstart`](https://github.com/thunderstornX/sovereign-llm-quickstart) — 您可以将此工具包指向的本地化 Ollama stack。
## 许可证
MIT © 2026 Ali Murtaza Bhutto
```
\ | /
\\\\|////
──── [ ● ] ────
////|\\\\
/ /|\ \
```
~ AMB · ORCID 0009-0007-2787-943X · v1.0 · 2026 ~
标签:AI安全, Chat Copilot, DLL 劫持, Python, TUI, 大语言模型, 安全规则引擎, 无后门, 渗透测试框架, 红队评估, 逆向工具, 防御