macus450-crypto/ioc-triage-cli
GitHub: Macus77a/ioc-triage-cli
一个轻量级 Python CLI 工具,用于对各类 IOC 进行被动威胁情报富化、判定评分和报告导出,帮助 SOC 分析师完成日常分类工作。
Stars: 0 | Forks: 0
# ioc-triage-cli
一个小型 Python CLI,用于 SOC 分类的第一步:接收一个妥协指标,检测其类型,通过被动 Threat Intelligence 来源进行富化,计算基本判定,并打印或导出报告。
该工具目前支持 IOC 类型检测、针对 IPv4 指标的 AbuseIPDB 富化、针对 IPv4/域名/URL/哈希指标的 VirusTotal 富化、针对域名的 DNS A 记录查询、基本判定评分、使用 Rich 格式化的终端报告,以及针对单个 IOC 分析的 JSON 导出。
这不是一个 SIEM、扫描器、沙箱或漏洞利用工具。这是一个围绕真实 SOC 分类工作流构建的学习和作品集项目。
## 为什么开发此工具
我开发这个项目是为了作为初级 SOC / Threat Intelligence 工作流的实践入门。
目标是模拟分析师在审查指标时可能执行的第一个富化步骤:识别 IOC 类型,使用被动来源进行富化,计算基本判定,并准备可读的报告。
该项目在范围上是故意限制的。它专注于安全的被动分析和清晰的报告,而不是扫描、利用或取代分析师的判断。
## 它的功能
该工具从命令行或文本文件接收 IOC,识别其类型,根据 IOC 类型运行被动富化,计算基本判定,并显示可读的分类报告。
当前支持的 IOC 类型:
* IPv4
* 域名
* URL
* MD5
* SHA256
当前富化行为:
| IOC 类型 | 富化来源 |
| -------- | ---------------------- |
| IPv4 | AbuseIPDB, VirusTotal |
| 域名 | DNS Lookup, VirusTotal |
| URL | VirusTotal |
| MD5 | VirusTotal |
| SHA256 | VirusTotal |
| 未知 | 无富化 |
当前判定级别:
* `MALICIOUS`
* `SUSPICIOUS`
* `CLEAN / UNKNOWN`
该项目故意避免将 IOC 称为 `SAFE`。缺乏检测并不能证明指标是无害的。
## 示例输出
示例命令:
```
python -m ioc_triage 185.220.101.45
```
示例报告:

文本回退示例:
```
╭──────────── IOC Triage Report ─────────────╮
│ IOC: 185.220.101.45 │
│ Type: ipv4 │
│ Verdict: MALICIOUS │
│ Severity score: 100 │
╰───────────────────────────────────────────╯
Threat Intelligence Sources
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Source ┃ Status ┃ Key Findings ┃
┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ AbuseIPDB │ ok │ Abuse score: 100, Reports: 115 │
│ VirusTotal│ ok │ Malicious: 19, Suspicious: 1 │
└───────────┴────────┴──────────────────────────────────────┘
Recommendations:
- Block or monitor the IOC according to internal policy.
- Review related authentication, proxy, firewall or endpoint logs.
- Escalate to SOC Tier 2 if this IOC is linked to internal assets.
```
如果输入无法识别:
```
python -m ioc_triage not-a-valid-ioc
```
```
╭─── IOC Triage Report ────╮
│ IOC: not-a-valid-ioc │
│ Type: unknown │
│ Verdict: CLEAN / UNKNOWN │
│ Severity score: 0 │
╰──────────────────────────╯
Recommendations:
- Unsupported or invalid IOC format. Verify the input value.
```
## 开始使用
克隆仓库:
```
git clone https://github.com/macus450-crypto/ioc-triage-cli.git
cd ioc-triage-cli
```
创建虚拟环境:
```
python -m venv .venv
```
激活虚拟环境:
```
# Windows
.venv\Scripts\activate
# Linux/macOS
source .venv/bin/activate
```
安装依赖:
```
pip install -r requirements.txt
```
该项目使用:
* `requests` 用于 AbuseIPDB 和 VirusTotal API 请求
* `python-dotenv` 用于加载环境变量
* `dnspython` 用于 DNS 查询
* `rich` 用于格式化的终端输出
* `pytest` 用于测试
## 环境变量
该项目使用 `python-dotenv` 从环境变量加载配置。
基于 `.env.example` 创建本地 `.env` 文件:
```
VIRUSTOTAL_API_KEY=
ABUSEIPDB_API_KEY=
REQUEST_TIMEOUT=10
```
环境变量:
| 变量 | 用途 |
| -------------------- | ------------------------------------------------------------ |
| `ABUSEIPDB_API_KEY` | 用于 AbuseIPDB IPv4 富化的 API 密钥 |
| `VIRUSTOTAL_API_KEY` | 用于 VirusTotal IPv4、域名、URL、MD5 和 SHA256 富化的 API 密钥 |
| `REQUEST_TIMEOUT` | HTTP 请求和 DNS 查询的超时值 |
您可以通过在以下位置创建账户来获取 API 密钥:
* [VirusTotal 社区](https://www.virustotal.com/gui/join-us)
* [AbuseIPDB](https://www.abuseipdb.com/register)
这两个提供商都提供适合基本个人测试的 API 访问,但免费层级的限制和可用功能可能会随时间变化。
实际的 `.env` 文件不应被提交。
如果缺少 API 密钥,将跳过相关的富化来源,报告将继续使用剩余的可用数据。
## 使用方法
单个 IOC 模式:
```
python -m ioc_triage 185.220.101.45
python -m ioc_triage example.com
python -m ioc_triage http://example.com/login
python -m ioc_triage 44d88612fea8a8f36de82e1278abb02f
python -m ioc_triage e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```
文件模式:
```
python -m ioc_triage --file examples/sample_iocs.txt
```
文件应每行包含一个 IOC。空行和以 `#` 开头的行将被跳过。
示例输入文件:
```
# 用于本地测试的 IOC 示例列表。
192.0.2.10
example.com
http://example.com/login
44d88612fea8a8f36de82e1278abb02f
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```
将单个 IOC 报告导出为 JSON:
```
python -m ioc_triage 185.220.101.45 --export examples/sample_output.json
```
当前限制:JSON 导出已针对单个 IOC 模式实现。文件模式会为每个 IOC 打印报告,但尚不支持将所有结果导出到一个合并的 JSON 文件中。
## JSON 导出示例
导出的报告示例:
```
{
"ioc": "185.220.101.45",
"ioc_type": "ipv4",
"verdict": "MALICIOUS",
"severity_score": 100,
"sources": [
{
"source": "AbuseIPDB",
"status": "ok",
"abuse_confidence_score": 100,
"total_reports": 115,
"country_code": "DE",
"isp": "Network for Tor-Exit traffic.",
"domain": "for-privacy.net",
"usage_type": "Commercial"
},
{
"source": "VirusTotal",
"status": "ok",
"malicious": 19,
"suspicious": 1,
"harmless": 42,
"undetected": 29
}
],
"recommendations": [
"Block or monitor the IOC according to internal policy.",
"Review related authentication, proxy, firewall or endpoint logs.",
"Escalate to SOC Tier 2 if this IOC is linked to internal assets."
]
}
```
## 我学到了什么
在构建这个项目的过程中,我实践了:
* 将 Python CLI 项目构建为更小的模块
* 检测不同的 IOC 类型,如 IPv4、域名、URL、MD5 和 SHA256 哈希
* 以安全、被动的方式使用外部 Threat Intelligence API
* 处理操作性的 API 问题,如密钥缺失、超时、速率限制和无效响应
* 进行 DNS 查询并理解如何对域名指标进行富化
* 设计简单的判定和严重性评分系统
* 创建可读的、分析师风格的终端报告和 JSON 输出
* 为 IOC 检测和判定评分编写测试
## 项目结构
```
ioc-triage-cli/
│
├── examples/
│ ├── invalid_output.json
│ ├── sample_iocs.txt
│ └── sample_output.json
│
├── ioc_triage/
│ ├── enrichers/
│ │ ├── __init__.py
│ │ ├── abuseipdb.py
│ │ ├── dns_lookup.py
│ │ └── virustotal.py
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli.py
│ ├── config.py
│ ├── detectors.py
│ ├── models.py
│ ├── reporter.py
│ └── verdict.py
│
├── screenshots/
│ └── ioc-triage-demo-output.png
│
├── tests/
│ ├── test_detectors.py
│ └── test_verdict.py
│
├── .env.example
├── .gitignore
├── LICENSE
├── requirements.txt
└── README.md
```
主要文件:
| 文件 | 用途 |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `ioc_triage/cli.py` | 参数解析、单个 IOC 模式、文件模式、富化编排、判定计算、报告打印和 JSON 导出调用 |
| `ioc_triage/detectors.py` | IOC 类型检测逻辑 |
| `ioc_triage/enrichers/abuseipdb.py` | 针对 IPv4 指标的 AbuseIPDB 查询 |
| `ioc_triage/enrichers/virustotal.py` | 针对 IPv4、域名、URL、MD5 哈希和 SHA256 哈希的 VirusTotal 查询 |
| `ioc_triage/enrichers/dns_lookup.py` | 针对域名的 DNS A 记录查询 |
| `ioc_triage/verdict.py` | 基本判定和严重性评分计算 |
| `ioc_triage/reporter.py` | Rich 终端报告和 JSON 导出逻辑 |
| `ioc_triage/config.py` | 从环境变量加载 API 密钥和请求超时 |
| `ioc_triage/__main__.py` | 允许使用 `python -m ioc_triage` 运行工具 |
| `examples/sample_iocs.txt` | 用于文件模式的示例输入文件 |
| `examples/sample_output.json` | 针对恶意 IPv4 指标的示例 JSON 报告 |
| `examples/invalid_output.json` | 针对无效 IOC 的示例 JSON 报告 |
| `screenshots/ioc-triage-demo-output.png` | 展示示例终端输出的屏幕截图 |
| `tests/test_detectors.py` | IOC 检测逻辑的测试 |
| `tests/test_verdict.py` | 判定和严重性评分逻辑的测试 |
| `.env.example` | 示例环境配置 |
| `LICENSE` | MIT 许可证文件 |
`models.py` 目前保留用于未来的标准化结果模型。
## 检测逻辑
检测逻辑位于 `detectors.py` 中,并拆分为多个小函数:
* `is_ipv4()`
* `is_url()`
* `is_domain()`
* `is_md5()`
* `is_sha256()`
* `detect_ioc_type()`
当前检测顺序:
```
URL → IPv4 → MD5 → SHA256 → domain → unknown
```
顺序很重要,因为根据定义的宽泛程度,某些值可以匹配多种模式。
## 富化逻辑
检测到 IOC 类型后,CLI 会调用匹配的富化函数。
| IOC 类型 | 富化来源 |
| -------- | --------------------------------------------------------------- |
| IPv4 | AbuseIPDB, VirusTotal |
| 域名 | DNS Lookup, VirusTotal |
| URL | VirusTotal |
| MD5 | VirusTotal |
| SHA256 | VirusTotal |
| 未知 | 无富化;返回不支持/无效的 IOC 建议 |
### AbuseIPDB
IPv4 指标将传递给 `check_ip_abuseipdb()`。
当前的 AbuseIPDB 集成处理:
* 缺少 API 密钥
* 成功的响应
* 速率限制响应
* 非 200 HTTP 响应
* 超时
* 请求错误
* 无效的 JSON 响应
返回的字段包括:
* `abuse_confidence_score`
* `total_reports`
* `country_code`
* `isp`
* `domain`
* `usage_type`
### VirusTotal
IPv4、域名、URL、MD5 和 SHA256 指标将传递给相应的 VirusTotal 助手。
当前的 VirusTotal 集成处理:
* 缺少 API 密钥
* 成功的响应
* 速率限制响应
* 非 200 HTTP 响应
* 超时
* 请求错误
* 无效的 JSON 响应
输出重点关注 `last_analysis_stats`:
* `malicious`
* `suspicious`
* `harmless`
* `undetected`
对于 URL,该工具会在查询 API 之前将 URL 编码为 VirusTotal URL 标识符。
### DNS 查询
域名指标将传递给 `resolve_domain()`。
当前的 DNS 查询会检查 A 记录并处理:
* 成功解析
* 未找到域名
* 现有域名但没有 A 记录
* 超时
* DNS 相关错误
结果使用 `source: "DNS Lookup"`,并在可用时于 `resolved_ips` 中返回解析出的 IPv4 地址。
## 判定逻辑
判定计算位于 `verdict.py` 中。
当前的评分特意保持简单,并基于可用的富化结果:
### AbuseIPDB 规则
| 条件 | 判定影响 |
| ------------------------------- | ----------------------------------------- |
| `abuse_confidence_score >= 80` | `MALICIOUS` |
| `abuse_confidence_score >= 25` | `SUSPICIOUS`,除非已经是 `MALICIOUS` |
### VirusTotal 规则
| 条件 | 判定影响 |
| ----------------- | ----------------------------------------- |
| `malicious >= 5` | `MALICIOUS` |
| `malicious >= 1` | `SUSPICIOUS`,除非已经是 `MALICIOUS` |
| `suspicious > 0` | `SUSPICIOUS`,除非已经是 `MALICIOUS` |
如果未发现强烈的恶意或可疑信号,结果将保持为:
```
CLEAN / UNKNOWN
```
这意味着在可用来源中未发现强烈信号。这并不意味着 IOC 绝对安全。
## 报告
报告层位于 `reporter.py` 中。
它目前提供:
* 一个包含 IOC、类型、判定和严重性评分的 Rich 摘要面板
* 一个包含 Threat Intelligence 来源和关键发现的 Rich 表格
* 基于判定的分析师风格建议
* 通过 `export_json()` 进行 JSON 导出
该报告旨在终端中具有可读性,并适用于初级 SOC 风格的分类工作流。
## 测试
运行测试:
```
python -m pytest
```
当前测试覆盖率:
* 有效的 IPv4 检测
* 有效的域名检测
* 有效的 URL 检测
* 有效的 MD5 检测
* 有效的 SHA256 检测
* 无效的 IPv4 处理
* 无效的域名处理
* 未知输入处理
* 基于 AbuseIPDB 结果的恶意判定
* 基于 AbuseIPDB 结果的可疑判定
* 基于 VirusTotal 结果的恶意判定
* 基于 VirusTotal 恶意检测的可疑判定
* 基于 VirusTotal 可疑检测的可疑判定
* 未发现强烈指标时的 clean/unknown 判定
* 在判定计算期间忽略已跳过或错误的来源
* 当稍后出现较弱的可疑来源时保持恶意判定
当前限制:富化模块、报告器输出和 JSON 导出尚未被测试完全覆盖。
## 当前工作流
```
Input IOC
→ Detect IOC type
→ Run matching passive enrichment sources
→ Calculate basic verdict and severity score
→ Print formatted terminal report
→ Optionally export single IOC report to JSON
```
## 路线图
已完成:
* [x] 带有 `python -m ioc_triage` 的 CLI 入口点
* [x] 单个 IOC 模式
* [x] 文件模式
* [x] IOC 类型检测器
* [x] 检测器测试
* [x] 判定评分测试
* [x] `.env.example`
* [x] 从环境变量加载配置
* [x] 针对 IPv4 指标的 AbuseIPDB 富化
* [x] 针对 IPv4、域名、URL、MD5 和 SHA256 的 VirusTotal 富化
* [x] 针对域名的 DNS A 记录查询
* [x] 基本判定评分
* [x] 严重性评分
* [x] Rich 终端报告
* [x] 分析师风格建议
* [x] 针对单个 IOC 模式的 JSON 导出
* [x] 示例 JSON 报告
* [x] 用于 GitHub README 的截图/演示输出
下一步:
* [ ] 为 AbuseIPDB、VirusTotal、DNS 查询、报告器逻辑和 导出添加测试
* [ ] 为文件模式添加合并的 JSON 导出
* [ ] 使用专用模型规范化富化结果
* [ ] 添加 Markdown 报告导出
* [ ] 改进 Rich 表格中对已跳过、超时、速率限制和错误来源的错误报告
* [ ] 添加更真实的示例 IOC 报告
* [ ] 添加钓鱼 URL 分析模块
## 注意事项
此工具仅用于被动 IOC 分类。
它不会:
* 扫描主机
* 利用系统
* 暴力破解服务
* 下载恶意软件
* 提交自动滥用报告
* 修改外部系统
Threat Intelligence 数据始终需要上下文。公开来源可能会遗漏威胁、返回过时信息或产生误报。该工具旨在支持分类,而不是取代分析师的判断。
## 许可证
该项目基于 MIT 许可证授权。
标签:IOC分析, Python, SOC分析, 威胁情报, 安全规则引擎, 安全运营, 开发者工具, 扫描框架, 无后门, 逆向工具