Giuseppe552/threadr

GitHub: Giuseppe552/threadr

一款面向安全专业人士的本地化 OSINT 图谱构建工具,实现多源数据关联与匿名化采集。

Stars: 1 | Forks: 0

# threadr [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/7161d2437e134204.svg)](https://github.com/Giuseppe552/threadr/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Tests: 380](https://img.shields.io/badge/tests-380_passing-brightgreen)]() [![Plugins: 17](https://img.shields.io/badge/plugins-17-blue)]() OSINT 工具,面向安全专业人士。输入一个电子邮件、域名或用户名——它会将关联的账户、基础设施和元数据映射为一个图谱。 ![threadr scan demo](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/25b662a4f3134210.jpg) 100% 自主托管。无云端。无遥传。你的密钥,你的数据。 ## 运行 无需克隆。下载一个 compose 文件,设置密码,启动即可。 ``` curl -sLO https://raw.githubusercontent.com/Giuseppe552/threadr/main/docker-compose.ghcr.yml printf "NEO4J_PASSWORD=changeme\nREDIS_PASSWORD=changeme\n" > .env docker compose -f docker-compose.ghcr.yml up -d open http://localhost ``` 或者从源码构建: ``` git clone https://github.com/Giuseppe552/threadr.git && cd threadr cp .env.example .env # set NEO4J_PASSWORD, REDIS_PASSWORD docker compose up -d ``` ## CLI ``` npm run cli -- scan user@example.com # JSON to stdout npm run cli -- scan example.com --depth 3 -f graphml > out.xml # GraphML export npm run cli -- scan user@example.com -f stix > scan.stix.json # STIX 2.1 bundle npm run cli -- scan example.com --stealth --proxy-ports 9051-9055 # anonymous npm run cli -- plugins # list all 17 npm run cli -- audit --proxy-ports 9051-9055 # verify anonymity ``` ## 插件 | plugin | accepts | key | | |--------|---------|-----|-| | github | Email | | users, repos | | crt.sh | Domain | | CT → subdomains | | dns | Domain | | A/AAAA/MX/NS/TXT/SOA/CNAME, SPF | | gravatar | Email | | profile via md5 | | social | Username | | 8 platforms | | shodan | IP, Domain | yes | ports, banners | | git-emails | Repo | | commit emails | | whois | Domain | | registrar, registrant | | virustotal | Domain, IP | yes | malicious score | | pgp | Email | | keyserver lookup | | hibp | Email | yes | breach history | | reverse-dns | IP | | PTR records | | reverse-ip | IP | | co-hosted domains | | geoip | IP | | country, city, ASN | | http-fp | Domain | | server, CDN, CMS | | email-check | Email | | SMTP probe, catch-all | | securitytrails | Domain, IP | yes | passive DNS, subdomains | 13 个插件无需密钥。4 个插件需要你自己的 API 密钥(在 UI 或 `.env` 中设置)。
分析引擎 五层数学分析,全部位于 `packages/shared/src/analytics/` 中: | Engine | Method | What it does | |--------|--------|-------------| | 证据融合 | Dempster-Shafer | 以恰当的置信度处理融合冲突的插件输出 | | 谱聚类 | Graph Laplacian eigendecomposition | 社区检测、桥接节点、异常点识别 | | 链路预测 | Katz centrality + Jaccard + Adamic-Adar | 预测应存在但尚未观测到的边 | | 暴露评分 | Shannon entropy | 每个身份的比特级风险评分 | | 图距离 | Wasserstein (Hungarian algorithm) | 扫描快照之间的最优传输 |
隐身模式 `--stealth` 启用 7 层匿名机制: - 每个插件独立 Tor 电路隔离(使用会话 nonce 进行 HMAC-SHA256 加键,映射在每次扫描中变化) - Chrome 请求头顺序模仿(sec-ch-ua、Sec-Fetch-*,顺序完全一致) - 会话 Cookie 与引用链(referrer chains)按域名隔离 - Lévy 稳定时间间隔(α=1.5,无穷方差 — 击败 KS 检验) - 马尔可夫链覆盖流量(7 状态浏览模型) - k-匿名目标诱饵(识别概率:1/(k+1)) - TLS 密码套件混洗(JA3 随机化) 启动 Tor:`docker compose --profile tor up -d` 自审计:`npm run cli -- audit --proxy-ports 9051-9055`
实体解析 当同一真实身份通过不同插件出现(GitHub 用户名、邮箱、域名注册人等),解析器使用基于 Jaro-Winkler 字符串相似度的多字段匹配来识别匹配项。 阻塞索引(blocking index)避免暴力全对比较。实体按精确令牌(邮箱、用户名、头像哈希)和名称二元组建立索引。仅共享令牌的候选对才会进入完整比对。超过 50 个实体的桶会被丢弃为噪声。 结果:1,000 个人物仅需约 5,000 个候选对,而非 499,500。置信度高于 0.85 的匹配自动合并;0.6–0.85 的标记为待审核。
安全加固 自审计于 2026 年 3 月。[Writeup](https://giuseppegiona.com/writing/auditing-my-own-osint-tool)。 - **查询注入防护** — Neo4j 标签与关系类型在查询执行前经过白名单验证,使用反引号进行纵深防御。 - **图谱扩展限制** — 最大深度 2,每批最多 200 个节点,总计最多 2,000 个节点。防止高连通性种子导致的组合爆炸。 - **插件超时** — 每个插件执行超时 30 秒。挂起的插件不会阻塞工作线程。 - **API 密钥加密** — 使用 AES-256-GCM 在存储层加密,密钥通过 HKDF-SHA256 从环境密钥派生。与明文存储的向后兼容。 - **Neo4j 弹性** — 在写入暂停前允许 5 次失败,健康状态在扫描开始时重置。 - **无默认凭据** — docker compose 要求 `.env` 文件并设置密码。
STIX 2.1 导出 `-f stix` 输出符合规范的 STIX 2.1 bundle。确定性 SCO ID(UUIDv5,OASIS 命名空间,RFC 8785 规范化)——相同输入始终生成相同 ID,这意味着跨扫描、跨工具的重复数据删除有效。 映射关系如下: | threadr 节点 | STIX 对象 | ID 贡献属性 | |---|---|---| | Email | `email-addr` | `value` | | Domain | `domain-name` | `value` | | IP | `ipv4-addr` / `ipv6-addr` | `value` | | Username | `user-account` | `account_type`, `user_id`, `account_login` | | Repository | `software` | `name` | | Person | `identity` (individual) | — | | Organization | `identity` (organization) | — | | Breach | `incident` | — | DNS 解析(RESOLVES_TO、HAS_MX)通过域名名称 SCO 上的嵌入式 `resolves_to_refs` 实现,而非独立关系。其余所有内容均作为 SRO,使用 `related-to` 或 `part-of` 适当关联。 未映射内容:端口(无适用于端口扫描结果的 STIX 类型)、电话(无原生 SCO)。这些保留在图谱中,但不出现在 STIX bundle 中。 Bundle 可通过 MITRE 的 `stix2-validator` 默认模式校验。一个提示性警告:`account_type: "github"` 不在 STIX 开放词汇表中(规范允许,但严格校验器不接受)。尚未测试与 OpenCTI 和 MISP 的实时导入——bundle 结构符合规范,但某些 `related-to` 关系可能被仅接受自身关系矩阵的工具静默丢弃。研究笔记位于 [`docs/stix-interop.md`](docs/stix-interop.md)。
加密账户 ECDSA P-256 密钥对认证。无电子邮件、无 KYC。 - 在浏览器中生成密钥对 → 公钥即身份 - 挑战-响应认证(无密码) - HMAC-SHA256 无状态会话 - 存储加密的 API 密钥(通过 HKDF 的 AES-256-GCM)
## 技术栈 ``` web React + Vite + Tailwind + react-force-graph-2d api Hono + SQLite (WAL) + token/ECDSA auth worker BullMQ + 17 plugins + Jaro-Winkler entity resolver + D-S fusion stealth Tor SOCKS5 + browser mimicry + Lévy timing + DoH graph Neo4j + Cypher + 3-hop traversal queue Redis ``` ## 开发 ``` npm run setup # install, copy .env, start neo4j + redis, build npm run dev # api + worker + web in parallel npm test # 380 tests across 33 files ``` ` run setup` 可安全重复执行——如果 `.env` 文件存在则跳过复制,docker compose 是幂等的。 ## 贡献 参见 [CONTRIBUTING.md](CONTRIBUTING.md)。每个插件约 30 行。问题标签为 [`good first issue`](https://github.com/Giuseppe552/threadr/labels/good%20first%20issue) 的任务已准备好供你领取。 ## 许可证 MIT
标签:17插件, 7层匿名, BeEF, BSD, CDN识别, crtsh, DNS查询, Docker, ESC4, GitHub用户, GraphML, Gravatar, JSON导出, Neo4j, NIDS, OSINT, PB级数据处理, Redis, SEO, STIX, STIX2, SYN扫描, TCP SYN 扫描, Web UI, Web界面, 代理, 信息搜集, 元数据分析, 公开数据, 关键词, 匿名网络, 域名信息, 域名解析, 基础设施映射, 多插件, 威胁情报, 子域名枚举, 安全运维, 安全防御评估, 容器化, 开发者工具, 开源许可, 情报收集, 插件扩展, 搜索引擎, 搜索引擎优化, 搜索引擎查询, 数据挖掘, 无云, 无文件攻击, 无需云, 本地部署, 漏洞研究, 爬虫, 社交工程, 社交平台, 社交平台账号, 系统安全, 网络安全, 自动化攻击, 自我托管, 自托管, 证书透明度, 账号关联, 邮箱查询, 隐私保护, 零遥测