sosiska245/reasonfinder
GitHub: sosiska245/reasonfinder
reasonfinder 是一个每周运行的 OSINT 扫描器,自动追踪 macOS/Apple Silicon 上特定软件(如 Reason DAW)的未经授权发布证据,并输出带置信度评分的报告。
Stars: 0 | Forks: 0
# reasonfinder
每周OSINT扫描器,追踪macOS / Apple Silicon上特定软件未经授权发布的可信公开证据。
专为网络安全研究而构建。使用场景组提及、平台标签([U2B]、ARM64)、NFO文件、用户确认和可信聚合器存在等信号,评分范围为0–100的置信度。
## 功能
- 可配置的目标、版本、平台、场景组、可信站点、垃圾黑名单
- 多语言查询:EN、RU、ES、IT、PT、FR、DE
- 两阶段搜索:先进行高信号查询,仅在达到阈值后扩展
- 置信度评分0–100,分为5个标签波段
- 周环比差异:新域名、新组、分数变化、稳定性标志
- HTML报告中每个目标的全部运行历史表格
- 输出:`weekly_report.html`、`weekly_report.md`、`results.csv`、`history/history.jsonl`
- 基于文件的缓存——7天内不会重复查询同一搜索
- 去重:URL精确匹配 + 标题模糊匹配(85%相似度阈值)
- 速率限制 + 指数重试/退避
- 空运行模式(显示查询但不调用API)
- **幽灵模式**(`--ghost`)——完整扫描+报告,不写入历史
- **安全 / 完整报告模式**——安全(默认)在报告中隐藏来源链接,完整则显示
- **自动回退到DuckDuckGo**:当未配置任何API密钥时(免费,无需注册)
## 安装说明
```
git clone https://github.com/yourusername/reasonfinder.git
cd reasonfinder
# 创建虚拟环境(推荐)
python3 -m venv .venv
source .venv/bin/activate
# 安装依赖项
pip install -r requirements.txt
```
## 搜索提供者设置
### 选项 A — 无需设置(DuckDuckGo,免费)
无需API密钥。使用 `provider: "auto"`(默认)即可开箱即用。
结果可能略少于付费API,但无需成本或注册。
### 选项 B — SerpAPI(每月100次免费搜索)
1. 在 https://serpapi.com 注册
2. 从控制面板复制API密钥
3. 在项目根目录创建 `api_keys.env`:
```
SERPAPI_KEY_1=your_key_here
# SERPAPI_KEY_2=second_key_optional
# SERPAPI_KEY_3=third_key_optional
```
### 选项 C — Bing 搜索 API(每月1000次免费查询)
1. 在 https://portal.azure.com 创建Azure账户
2. 创建 **Bing Search v7** 资源
3. 添加到 `api_keys.env`:
```
BING_SEARCH_KEY=your_key_here
```
然后在 `config.yaml` 中设置 `provider: bing`。
## 配置
编辑 `config.yaml` 以自定义目标、版本、场景组、可信站点和评分权重。
```
targets:
- name: "Reason Studios Reason"
versions: ["12", "13", "14"]
protection: "home-grown-online"
aliases: ["Reason DAW", "Propellerhead Reason"]
search:
provider: "auto" # auto | serpapi | bing | duckduckgo
results_per_query: 10
rate_limit_rps: 1.0
deep_fetch_threshold: 20 # score above this triggers phase-2 expansion
```
## 运行
```
# 每周完整扫描
python main.py run
# 试运行(查看查询而不进行 API 调用)
python main.py run --dry-run
# 限制每个目标的查询数(高优先级优先)
python main.py run --max-queries 10
# 基准测试模式(固定查询数量以实现周周公平比较)
python main.py run --benchmark-queries 10
# 列出所有将要运行的查询
python main.py list-queries
# 运行前估算 API 使用量
python main.py estimate
# 从现有历史记录重新生成报告(无 API 调用)
python main.py report-only
# 显示评分历史
python main.py history
python main.py history --target "Reason" --last 20
# Ghost 模式 — 扫描并报告,不保存历史记录
python main.py run --ghost
# 报告模式 — 安全模式隐藏来源链接(默认),完整模式显示它们
python main.py run --mode safe
python main.py run --mode full
python main.py report-only --mode full
```
## 每周定时任务设置
每周一08:00自动运行:
```
crontab -e
```
添加(调整路径):
```
0 8 * * 1 cd /path/to/reasonfinder && .venv/bin/python main.py run >> /tmp/reasonfinder_cron.log 2>&1
```
## 输出文件
默认所有输出写入 `reports/`(可在 `config.yaml` 中配置)。
| 文件 | 描述 |
|------|------|
| `reports/weekly_report.html` | 带可折叠章节的深色主题HTML报告 |
| `reports/weekly_report.md` | Markdown报告 |
| `reports/results.csv` | 所有搜索结果及信号的平面表格 |
| `history/history.jsonl` | 紧凑的累积周分数历史(JSONL格式) |
## 运行测试
```
pytest tests/ -v
```
测试覆盖:
- 查询生成和多语言扩展(`test_query_builder.py`)
- 从结果文本提取信号(`test_result_parser.py`)
- 评分模型的正确性、上限和抗通胀能力(`test_scoring.py`)
- HTML报告结构、可折叠章节、徽章、历史表格(`test_reporter.py`)
## 评分模型
| 信号 | 分数 |
|------|------|
| 可信聚合器命中 | +15(对数饱和,合并上限45) |
| 提及已知场景组 | +20(二元) |
| 引用NFO文件 | +10 |
| 发现U2B / ARM64标签 | +15 |
| 用户确认(工作/测试/确认) | 每个独立域名+5,最高+25 |
| 来自可信站点的论坛讨论 | +15(对数饱和,合并上限45) |
| 仅来自垃圾/黑名单站点的结果 | −30 |
| 未找到命名的场景组 | −15 |
| 未找到用户确认 | −10 |
**置信度上限**(与查询数量无关的硬性上限):
| 条件 | 最高分数 |
|------|---------|
| 无macOS/AS正常工作确认 | 55 |
| 无U2B/ARM64平台标签 | 60 |
| 仅猜测,无场景组 | 45 |
| 所有结果来自垃圾域名 | 50 |
| 少于2个独立的直接发布信号 | 75 |
| 分数 | 波段标签 |
|------|---------|
| 0–20 | 可能伪造 / 无证据 |
| 20–45 | 弱信号 |
| 45–65 | 似合理但未验证 |
| 65–85 | 可能可信 |
| 85–100 | 强公开证据 |
## 缓存
结果以JSON文件缓存于 `cache/` 目录下,键为 `{query_hash}_{ISO_week}.json`。
同一查询在同一ISO周内不会重新获取。TTL可通过 `cache.ttl_days` 配置。
## 项目结构
```
reasonfinder/
├── main.py # CLI entry point (Click)
├── config.yaml # User configuration
├── config_loader.py # Pydantic v2 config validation
├── query_builder.py # Multilingual query generation
├── result_parser.py # Signal extraction
├── scoring.py # Confidence scoring model
├── search_client.py # SerpAPI + Bing + DuckDuckGo, cache, key rotation
├── storage.py # History (JSONL), CSV, deduplication
├── reporter.py # HTML + MD + CSV report generation
├── requirements.txt
├── api_keys.env # NOT committed — API keys (see api_keys.env.example)
├── cache/ # Auto-created query cache (gitignored)
├── reports/ # Auto-created output directory (gitignored)
├── history/ # Auto-created history directory (gitignored)
│ └── history.jsonl # Compact JSONL history
└── tests/
├── test_query_builder.py
├── test_result_parser.py
├── test_scoring.py
├── test_reporter.py
└── fixtures/
└── sample_results.json
```
## 备注
- 从不获取垃圾/黑名单域名的内容——仅元数据,用作弱负面信号
- 第二阶段(中低优先级查询)仅当第一阶段分数 ≥ `deep_fetch_threshold`(默认:20)时运行
- 防止分数通胀:对数饱和的域名计数、域名去重确认、硬性证据上限
- 所有输出均为本地——除配置的搜索API外,不会将数据发送到任何地方
- DuckDuckGo回退使用非官方抓取;结果可能有所不同;付费API提供更一致的覆盖
标签:Apple Silicon, Bing, ESC4, GitHub, HTML报告, macOS安全, OSINT, SerpAPI, 历史追踪, 多模态安全, 多语言搜索, 威胁情报, 定期扫描, 密码管理, 幽灵模式, 开发者工具, 情报收集, 扫描器, 搜索引擎, 数字取证, 时序数据库, 漏洞研究, 缓存去重, 网络安全, 置信度评分, 自动化脚本, 软件盗版追踪, 逆向工具, 防御加固, 限速, 隐私保护