pavel-kalmykov/phishing-radar

GitHub: pavel-kalmykov/phishing-radar

基于证书透明度日志的实时钓鱼基础设施检测系统,通过模糊字符串匹配识别仿冒域名并与多源威胁情报交叉关联。

Stars: 0 | Forks: 0

# 钓鱼雷达 基于证书透明度日志的实时钓鱼基础设施检测。在证书颁发时标记域名冒充行为,并将检测结果与活跃的恶意软件情报(CISA KEV、abuse.ch、Spamhaus、MITRE ATT&CK)进行交叉比对。 [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-green.svg)](https://www.python.org/downloads/) [![Status: Archive](https://img.shields.io/badge/status-archive%20%24%200%2Fforever-purple.svg)](#archive-mode) **数据采集窗口:** 2026-04-23 至 2026-05-05。该项目作为实时云部署运行了 12 天,现在作为零依赖的冻结归档保存。该仪表板完全可探索,无需 API 密钥、Docker 或云账号。 ## 快速开始 ``` git clone https://github.com/pavel-kalmykov/phishing-radar.git cd phishing-radar uv sync ARCHIVE_MODE=1 streamlit run dashboard/app.py ``` 在 `http://localhost:8501` 打开。所有六个标签页均可正常使用:概览、实时钓鱼流、威胁态势、地图、健康状况、技术栈。归档横幅表明数据已冻结;日期选择器已锁定至采集范围。 ## 为什么会有这个项目 每个钓鱼网站都需要 TLS 证书。浏览器会将非 HTTPS 网站标记为不安全,因此攻击者会从 Let's Encrypt 和其他公共 CA 为仿冒域名申请证书。这些证书在颁发后的几秒钟内就会出现在证书透明度日志中。 如果你持续关注这个数据流,就能在第一封钓鱼邮件发送之前,在诈骗基础设施搭建过程中发现它们。Phishing Radar 持续监控该数据流,并回答两个问题: 1. 目前有哪些品牌正在被仿冒? 2. 在这些可疑证书中,哪些托管在已知具有敌意的设施上(活跃的僵尸网络 C2、被劫持的 IP 空间、存在被利用的 CVE 的供应商)? ## 仪表板 六个标签页,全部从 97 MB DuckDB 快照中预聚合的 dbt marts 读取数据: | 标签页 | 显示内容 | |---|---| | **概览** | 最常被仿冒的品牌、按恶意软件家族分类的活跃 C2(悬停查看上下文)、检测量趋势 | | **实时钓鱼流** | 每小时标记的证书数量、主要颁发 CA、带有相似度评分的最新 50 项检测 | | **威胁态势** | CISA KEV 每月新增、Spamhaus DROP/EDROP 明细、按勒索软件比例排名的 KEV 供应商、按国家/地区分类的 C2 | | **地图** | 散点地理图,每个托管 C2 基础设施的国家/地区对应一个标记,按活跃数量调整大小,带有恶意软件家族提示框 | | **健康状况** | 端到端管道丢失监控(WebSocket 到检测器跃点)、心跳延迟、每个 worker 的吞吐量 | | **技术栈** | 流式管道、批量摄取和数据源的架构参考面板 | ## 架构(原云部署) ``` flowchart LR subgraph src[Public sources] CT[Certificate Transparency logs] KEV[CISA KEV] FEO[abuse.ch Feodo Tracker] SPAM[Spamhaus DROP/EDROP] MITRE[MITRE ATT&CK] MM[MaxMind GeoLite2] end subgraph fly[Fly.io apps] CS[certstream-server-go] PROD[Python producer] DET[PyFlink detector] SINK[Kafka to MotherDuck sink] KES[Kestra orchestrator] end subgraph cloud[Managed services] RP[(Redpanda Cloud)] MD[(MotherDuck)] ST[Streamlit Cloud] end CT --> CS -->|WebSocket| PROD -->|certstream_events| RP RP --> DET -->|suspicious_certs| RP --> SINK --> MD KEV --> KES FEO --> KES SPAM --> KES MITRE --> KES MM --> KES KES -->|dlt + dbt| MD MD --> ST ``` 该管道通过具有 1 分钟滚动窗口的 PyFlink 检测器每秒处理约 200 个证书,应用 Damerau-Levenshtein 和 Jaro-Winkler 相似度算法,针对配置的品牌列表捕获域名仿冒和同形字攻击。检测结果通过具有幂等保证的 Kafka sink 落地到 MotherDuck,然后由 18 个 dbt marts 对数据进行预聚合以供仪表板使用。 ## 归档模式 云部署于 2026-05-05 结束,当时托管服务(Redpanda Cloud、MotherDuck)已到期。该归档在此代码仓库中保存了每个仪表板 mart 和 134,000 条最新检测结果,全部包含在一个 97 MB 的 DuckDB 文件中。设置 `ARCHIVE_MODE=1`,仪表板将直接读取该文件,实现零外部依赖。 ## 技术栈 | 层级 | 工具 | 备注 | |---|---|---| | 流代理 | Redpanda (Kafka API) | 采集期间使用云服务;完整回放需通过 Docker 使用本地服务 | | 流处理 | PyFlink DataStream | 1 分钟滚动窗口,域名仿冒 + 同形字检测 | | 批量摄取 | dlt | CISA KEV、Feodo、ThreatFox、Spamhaus、MITRE、MaxMind | | 编排 | Kestra | 计划批处理流 | | 数据仓库 | DuckDB | 实时运行期间为 17 GB;97 MB 归档快照 | | 数据转换 | dbt (dbt-duckdb) | 18 个预聚合 marts | | 仪表板 | Streamlit | 归档模式($0)或本地运行 | ## 数据源 | 来源 | 类型 | 更新频率 | |---|---|---| | 证书透明度日志(通过 certstream-server-go) | WebSocket | ~200 证书/秒 | | CISA KEV 目录 | JSON | 每天 | | abuse.ch Feodo Tracker | JSON | 每分钟 | | abuse.ch ThreatFox | JSON | 每分钟 | | Spamhaus DROP / EDROP | TXT | 每天 | | MITRE ATT&CK (Enterprise) | STIX 2 JSON | 每月 | | MaxMind GeoLite2 | CSV | 每周 | ## 完全本地运行(带实时管道) 如果你想使用实时 CertStream 订阅源运行完整管道,你需要 Docker、Python 3.11+、`uv` 和 `just`: ``` cp .env.example .env # no cloud tokens needed just setup # Python deps just up-local # docker-compose: Redpanda + certstream + Kestra export DATABASE_URL=data/local.duckdb just producer & # CertStream to local Redpanda just detect & # PyFlink detector (needs JDK 17) just sink & # Kafka to local DuckDB just monitor & # Observability just batch # one-shot batch ingestion just dbt-run-local # dbt transforms just dashboard # Streamlit at localhost:8501 ``` 完整设置将写入 `data/local.duckdb`(预计在数天内会增长到数十 GB)。归档快照是在 12 天的采集窗口之后从同一管道中提取的。 ## 仓库布局 ``` . ├── batch/ # dlt pipelines (one module per source) ├── dashboard/ # Streamlit app ├── data/ # archive.duckdb (97 MB, committed) ├── dbt/ # dbt project (models, tests, macros) ├── deploy/ # fly.toml per Fly app (historical) ├── kestra/flows/ # Kestra flow definitions (YAML) ├── streaming/ │ ├── producer/ # CertStream to Kafka │ ├── flink/ # PyFlink detection job │ ├── sink/ # Kafka to DuckDB with idempotency │ └── observability/ # Pipeline health monitor ├── tests/ # pytest suite ├── Dockerfile # single image for all Python services ├── docker-compose.yml # Redpanda + certstream + Kestra ├── justfile # cross-OS task runner ├── pyproject.toml └── README.md ``` ## 测试与质量 - **pytest**:26 个断言,涵盖域名仿冒检测器和每个批处理摄取解析器(重试/退避、模拟 HTTP 响应)。 - **dbt**:22 个 schema 测试 + 4 个单一测试(IP 格式健全性、管道健康不变量、CVE 日期健全性、基础模型非空)。 - **ruff**:在 CI 中进行 linting。 - **检测器设计**:`docs/detection_alternatives.md` 记录了从 Levenshtein 到 Damerau-Levenshtein + Jaro-Winkler 的迁移,以及为何放弃 MinHash。 - **内存分析**:`docs/memory_profile.md` 记录了每个服务的 RSS 峰值和规格调整决策。 ## 已知局限性 这些是有意做出的权衡: - **至少一次,而非精确一次。** sink 在 DuckDB 刷新后提交 Kafka 偏移量。如果在刷新和提交之间被终止,下一次运行将进行重放,并在 mart 层进行去重。这适用于分析场景;但不适合用于计费。 - **检测延迟下限。** 1 分钟的滚动窗口保持状态有界。证书在颁发后 60-120 秒出现在仪表板中。这是近实时,而非亚秒级。 - **CT 数据流空白。** 如果生产者与 WebSocket 断开连接,空白期间的事件不会被重放。存在重连逻辑;但没有重放机制。 - **单实例服务。** 每个 Fly app 运行一台机器。没有 HA(高可用性),没有领导者选举。恢复依赖于 Fly 的重启策略。 - **品牌白名单范围。** 检测器仅针对配置的品牌(`STREAMING_BRAND_LIST_PATH`)标记冒充行为。根据设计,列表之外的任何内容都是不可见的。 - **GeoLite2 准确性。** 免费层级,非商业级别。某些 IP 只能解析到国家级别。地图会对并置的标记进行抖动处理,以真实反映分辨率情况。 ## 许可证 MIT。
标签:CISA KEV, Cloudflare, CT logs, dbt, DE Zoomcamp 2026, DuckDB, HTTPS证书, Kubernetes, MITRE ATT&CK, Python, Streamlit, TLS证书, 品牌保护, 域名仿冒, 威胁情报, 开发者工具, 开源, 恶意软件情报, 数据工程, 无后门, 期末项目, 网络安全, 访问控制, 证书透明度日志, 请求拦截, 逆向工具, 钓鱼检测, 隐私保护