clivoa/harppia

GitHub: clivoa/harppia

一款 OSINT 凭证扫描器,通过扫描多个公共来源监控与用户关键词匹配的泄漏密钥,并支持 GitHub Actions 自动化运行与 Telegram 告警。

Stars: 0 | Forks: 0

# harppia

harppia

OSINT 凭证扫描器 — 监控公共来源,寻找与您的关键词匹配的泄漏密钥。 Harppia 扫描七个层面 — SwaggerHub API 规范、GitHub 代码搜索、公开 Gist、JSON/YAML 格式化的粘贴网站、Sourcegraph(多平台代码搜索)、npm registry 以及可选的 Pastebin — 寻找与您定义的组织、品牌、域或标识符关联的 API key、token、密码及其他密钥。它可以**通过命令行按需运行**,也可以**通过 GitHub Actions 按计划自动运行**。 发现结果按信号强度进行分类。只有高置信度的凭证才会触发 Telegram 警报 — 噪声较大的类别(bearer token、JWT、IP 地址)将记录到 CSV 中供离线审查。 匹配到的密钥值在终端输出、JSON/CSV 导出、报告和 Telegram 警报中默认会被脱敏。每个脱敏的发现结果都包含 `matched_value_hash`,以便您在不暴露原始密钥的情况下关联重复值。 ## 负责任地使用 仅对您被授权监控的资产、品牌、域和组织使用 Harppia。如果您使用此项目监控您所在的公司,请将您的 fork/repo 保持**私有**,并限制对生成输出的访问。发现结果、报告、去重状态、日志和 CSV/JSON 导出可能包含敏感信息,包括泄漏的凭证、内部名称、URL 或其他不应公开暴露的数据。 此工具专为防御性安全和授权的 OSINT 工作流程提供。您需对如何使用它、如何存储结果以及您的使用是否符合适用的法律、合同、内部政策和披露流程负全部责任。维护者对滥用、未经授权的扫描、敏感数据的披露或因使用此工具而产生的任何后果不承担任何责任或义务。 ## 快速开始 ``` git clone https://github.com/clivoa/harppia.git cd harppia python3 -m pip install -r requirements.txt python3 harppia.py -k target-name -k target-domain.example ``` 首次运行无需配置。添加 `--gh-pat` 可解锁 GitHub 搜索和 Gist 扫描,并享受更高的速率限制。 ## 项目结构 ``` harppia/ ├── harppia.py ← ad-hoc CLI entry point ├── compile.py ← aggregates daily findings into CSV reports ├── requirements.txt ← requests only ├── .env.example ← optional environment variable reference ├── SECURITY.md ← security and responsible disclosure notes ├── CONTRIBUTING.md ← development and PR guidance ├── seen_hashes.json ← deduplication state (committed by CI) ├── scanners/ │ ├── swaggerhub.py ← SwaggerHub scanner │ ├── github_search.py ← GitHub Code Search scanner │ ├── github_gist.py ← GitHub Gist scanner │ ├── formatters.py ← JSON/YAML formatter paste site scanner │ ├── sourcegraph.py ← Sourcegraph multi-platform code search │ ├── npm_registry.py ← npm public package registry scanner │ └── pastebin.py ← Pastebin scanner (ad-hoc only — see below) ├── utils/ │ ├── keywords.py ← keyword list to scan for │ ├── patterns.py ← 68 detection regexes + category mapping │ ├── keyword_match.py ← boundary-aware keyword matching │ ├── redaction.py ← matched-value redaction helpers │ ├── telegram.py ← Telegram alert helper │ └── deduplication.py ← SHA256-based cross-run dedup ├── tests/ ← unit tests for matching, redaction, dedup, reports └── .github/workflows/ ├── swaggerhub-scanner.yml ← cron :00 ├── gist-scanner.yml ← cron :15 ├── github-search-scanner.yml ← cron :30 ├── formatter-scanner.yml ← cron :45 ├── sourcegraph-scanner.yml ← cron every 12h ├── npm-scanner.yml ← cron daily ├── compile-reports.yml ← cron :55 └── quality.yml ← compile + unit tests on push/PR ``` ## 临时使用 `harppia.py` CLI 允许您按需扫描 — 无需 GitHub 账户、无需密钥、无需提交。 关键词确认具有边界感知能力:短关键词会匹配类似 token 的出现情况,但不会匹配较长字母数字词中不相关的子字符串。域名关键词也避免在更长的域名内进行匹配。 ### 基本用法 ``` # 扫描所有来源 (swaggerhub, github, gists, formatters, sourcegraph, npm) python3 harppia.py -k target-name -k target-domain.example # 针对特定 scanner python3 harppia.py -k target-name --scanner swaggerhub,gists python3 harppia.py -k target-name --scanner sourcegraph,npm # 保存到文件 python3 harppia.py -k target-name --output findings.json python3 harppia.py -k target-name --output findings.csv --format csv # 仅保存高置信度 secret python3 harppia.py -k target-name --category credential --output secrets.json # 显示完整的匹配值以便进行受控的本地 triage python3 harppia.py -k target-name --category credential --show-secrets # 保存扫描期间发现的 SwaggerHub URL python3 harppia.py -k target-name --scanner swaggerhub --candidates-output swaggerhub-candidates.json # 忽略之前已发现的 findings(全新扫描) python3 harppia.py -k target-name --no-dedup # 在此次运行中抑制 Telegram 警报 python3 harppia.py -k target-name --no-alert # 直接传递 credential — 无需 env vars python3 harppia.py -k target-name \ --gh-pat ghp_xxxxxxxxxxxx \ --telegram-token 123456789:ABCdef \ --telegram-chat -1001234567890 # 延长 GitHub Code Search 的时间窗口 python3 harppia.py -k target-name --since-hours 72 # 跳过 Gist 公共时间线遍历(仅限关键字搜索,速度更快) python3 harppia.py -k target-name --gist-hours 0 # Pastebin(需要 Pro account + whitelisted IP — 见下文) python3 harppia.py -k target-name --scanner pastebin ``` ### 所有选项 | 标志 | 默认值 | 描述 | |---|---|---| | `-k / --keyword` | `utils/keywords.py` | 要扫描的关键词。重复使用可指定多个。如果省略,则回退到 `utils/keywords.py`。 | | `-s / --scanner` | `all` | 要运行的扫描器:`swaggerhub`、`github`、`gists`、`formatters`、`sourcegraph`、`npm` 或 `all`。显式使用 `pastebin`(见下文)。支持以逗号分隔或重复使用。 | | `-o / --output` | — | 将发现结果保存到文件。 | | `--candidates-output` | — | 将发现的候选 URL/元数据保存到 JSON 文件(目前支持 SwaggerHub)。 | | `--format` | `json` | 输出文件格式:`json` 或 `csv`。 | | `--category` | all | 仅打印/保存一个或多个类别的发现结果:`credential`、`token`、`pii`、`infrastructure`。支持以逗号分隔或重复使用。 | | `--no-dedup` | off | 跳过跨运行去重 — 全部重新扫描。 | | `--no-alert` | off | 抑制本次运行的 Telegram 警报。 | | `--show-secrets` | off | 打印并保存完整的匹配密钥值。默认情况下,`matched_value` 会被脱敏,并添加 `matched_value_hash` 用于关联。 | | `--gh-pat` | `$GH_PAT` | GitHub 个人访问令牌。 | | `--telegram-token` | `$TELEGRAM_BOT_TOKEN` | Telegram bot token。 | | `--telegram-chat` | `$TELEGRAM_CHAT_ID` | Telegram 聊天/频道 ID。 | | `--since-hours` | `24` | GitHub 代码搜索的时间窗口(以小时为单位)。`0` = 无时间过滤。 | | `--gist-hours` | `6` | Gist 公开时间线的时间窗口(以小时为单位)。`0` = 跳过时间线,仅进行关键词搜索。 | ## 扫描器 | 扫描器 | `--scanner` | 自动化 | 搜索内容 | |---|---|---|---| | SwaggerHub | `swaggerhub` | 每 6 小时 | SwaggerHub 上的公开 API 规范 | | GitHub 代码搜索 | `github` | 每 6 小时 | 公开 GitHub repo 中的源文件 | | GitHub Gists | `gists` | 每 6 小时 | 公开 Gist(时间线 + 关键词搜索) | | 格式化网站 | `formatters` | 每 6 小时 | jsonformatter.org 上的最近粘贴(YAML/XML 端点) | | Sourcegraph | `sourcegraph` | 每 12 小时 | 跨 GitHub、GitLab、Bitbucket 等平台的公开代码 | | npm registry | `npm` | 每天 | npm 公开 registry 上的包元数据和 README | | Pastebin | `pastebin` | ❌ 仅限临时调用 | Pastebin 上的近期公开粘贴(见下文) | ### Pastebin Pastebin 扫描器使用 [Pastebin Scraping API](https://pastebin.com/doc_scraping_api),这需要: 1. **Pastebin Pro 账户**(订阅等级)。 2. 在您的 Pastebin 账户设置中将运行机器的 **IP 地址加入白名单**。 由于 IP 白名单的要求,Pastebin 扫描器被有意**排除在 `--scanner all` 之外**,并且不包含在自动化的 GitHub Actions 计划中(GitHub Actions 使用动态 IP,无法可靠地将其加入白名单)。它仅在显式调用时可用: ``` PASTEBIN_API_KEY=your_key python3 harppia.py -k target-name --scanner pastebin ``` 要使用它,请在 [pastebin.com/doc_scraping_api](https://pastebin.com/doc_scraping_api) 将您运行该程序机器的 IP 加入白名单。如果您从具有固定 IP 的服务器运行,请将该 IP 添加到白名单并设置 `PASTEBIN_API_KEY` 环境变量。 ## 使用 GitHub Actions 进行自动扫描 为了进行持续监控,请 fork 此 repo 并将其配置为按计划运行。发现结果会自动提交回 repo;另一个单独的 workflow 会编制每日 CSV 报告。 扫描器 workflow 共享一个 `harppia-writes` 并发组,因此计划运行不会同时推送到仓库。一个单独的 `quality.yml` workflow 会在 push、pull request 和手动触发时编译代码并运行单元测试。 ### 1. Fork 此仓库 将您的 fork 保持**私有** — 它将包含与真实泄漏凭证相关的发现数据。 ### 2. 配置您的关键词 编辑 `utils/keywords.py` 并添加您要监控的组织名称、品牌和域名片段。 ``` KEYWORDS = [ # ── Primary targets ──────────────────────────────────────────────────────── "target-name", "target-brand", # ── Domain identifiers (appear in env vars and connection strings) ───────── "target-domain.example", "service.target-domain.example", ] ``` **高效关键词技巧:** - 特定的子品牌名称比通用词汇产生的噪声更小。 - 域名片段(例如 `target-domain.example`)可以捕获连接字符串和电子邮件地址中的凭证。 - 内部平台名称(支付系统、内部 API)能发现单靠品牌名称容易遗漏的开发者配置。 - 每个关键词都会使 GitHub API 调用量成倍增加 — 请保持列表精简。 ### 3. 创建 Telegram bot 1. 打开 Telegram 并开始与 [@BotFather](https://t.me/BotFather) 聊天。 2. 发送 `/newbot` 并按照提示操作。复制 **bot token**(格式:`123456789:ABCdef...`)。 3. 将 bot 添加到应发送警报的频道或群组。 4. 获取您的 **chat ID**: - 对于频道:将任何消息转发给 [@userinfobot](https://t.me/userinfobot)。 - 或者,在向 bot 发送消息后,调用 `https://api.telegram.org/bot/getUpdates`。 - 频道 ID 以 `-100` 开头。 ### 4. 生成 GitHub 个人访问令牌 (PAT) GitHub Search 和 Gist 扫描器使用 PAT 以更高的速率限制访问 API(经过身份验证的为 30 次请求/分钟,未经验证的为 10 次请求/分钟)。该 token 仅需要公开内容的读取权限。 1. 前往 **GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens**。 2. 点击 **Generate new token**。 3. 设置名称(例如 `harppia-scanner`),并在 Repository access 下选择 **Public Repositories (read-only)**。 4. 复制 token。 ### 5. 添加 GitHub Secrets 前往您的 repo → **Settings → Secrets and variables → Actions → New repository secret**。 | Secret | 值 | 需求方 | |---|---|---| | `TELEGRAM_BOT_TOKEN` | 来自 @BotFather 的 Bot token | 所有扫描器(警报) | | `TELEGRAM_CHAT_ID` | 频道/聊天 ID | 所有扫描器(警报) | | `GH_PAT` | 步骤 4 中的 GitHub PAT | GitHub Search, Gists | | `SOURCEGRAPH_TOKEN` | Sourcegraph 访问 token(可选) | Sourcegraph(更高的速率限制) | 在本地运行时,请参阅 `.env.example` 获取相同的变量。Harppia 会直接读取环境变量;在您的 shell 中导出它们,或者传递 CLI 标志,例如 `--gh-pat`、`--telegram-token` 和 `--telegram-chat`。 ### 6. 启用 GitHub Actions 前往您 repo 中的 **Actions** 标签页,如果出现提示,请点击 **Enable workflows**。 每个 workflow 都会在其计划时间自动运行。您也可以通过 **Actions → [workflow name] → Run workflow** 手动触发任何 workflow。 ### Workflow 计划 | Workflow | 计划 | 扫描器 | |---|---|---| | `swaggerhub-scanner.yml` | 每 6 小时的 `:00` | SwaggerHub | | `gist-scanner.yml` | 每 6 小时的 `:15` | GitHub Gists | | `github-search-scanner.yml` | 每 6 小时的 `:30` | GitHub 代码搜索 | | `formatter-scanner.yml` | 每 6 小时的 `:45` | 格式化粘贴网站 | | `sourcegraph-scanner.yml` | 每 12 小时的 `:15` | Sourcegraph | | `npm-scanner.yml` | 每天 `08:30` | npm registry | | `compile-reports.yml` | 每 6 小时的 `:55` | 报告汇总 | | `quality.yml` | push / PR / 手动 | 语法 + 单元测试 | ## 了解发现结果 ### 输出结构 ``` data/ swaggerhub/ 2026-07-02_matches.json github_search/ 2026-07-02_matches.json github_gists/ 2026-07-02_matches.json sourcegraph/ 2026-07-02_matches.json npm/ 2026-07-02_matches.json pastebin/ 2026-07-02_matches.json ← only present when run ad-hoc formatters_2026-07-02_matches.json reports/ 2026-07-02_credential.csv ← Telegram alerts were sent for these rows 2026-07-02_token.csv 2026-07-02_pii.csv 2026-07-02_infrastructure.csv 2026-07-02_summary.json seen_hashes.json ← deduplication state (committed by CI) ``` 当使用 CLI (`harppia.py`) 时,发现结果会打印到终端。使用 `--output` 将它们保存到文件中。`data/` 和 `reports/` 目录仅在由计划扫描器创建,或在直接运行单个扫描器时创建。 ### 发现结果 schema ``` { "source": "sourcegraph", "keyword": "target-name", "url": "https://sourcegraph.com/github.com/user/repo/-/blob/config/app.yml", "repository": "github.com/user/repo", "path": "config/app.yml", "pattern_name": "generic_api_key", "matched_value": "api_...alue (21 chars)", "matched_value_hash": "c38f4f6a16...", "category": "credential", "timestamp": "2026-07-02T12:00:00+00:00" } ``` 默认情况下,在终端输出、保存的 JSON/CSV、报告和 Telegram 警报中,`matched_value` 会被脱敏。仅当需要确切的泄漏值以进行受控的本地分类时,才使用 `--show-secrets`。当直接运行单个扫描器模块时,仅当您特意希望将原始值写入磁盘时,才设置 `HARPPIA_SHOW_SECRETS=1`。 ### 类别 | 类别 | 捕获内容 | 警报 | |---|---|---| | `credential` | API key、密码、私钥、数据库连接字符串、支付密钥 | Telegram + CSV | | `token` | Bearer token、JWT、会话 ID — 常见于 API 文档中,信号较低 | 仅 CSV | | `pii` | 电子邮件地址、CPF、CNPJ | 仅 CSV | | `infrastructure` | IP 地址、对象存储 URL | 仅 CSV | ## 检测模式 `utils/patterns.py` 中定义了 68 种模式,涵盖: - **云和基础设施凭证**:访问密钥 ID、secret key、服务账户标识符、存储连接字符串、对象存储 URL 和网络指标。 - **私钥**:常见的 PEM/私钥块格式及相关密钥材料指标。 - **开发和自动化 token**:源代码控制 token、包 registry token、问题跟踪器 token、bot token、webhook 和嵌入式 URL 凭证。 - **通信和通知密钥**:消息传递、电子邮件传递、电话和 bot 凭证。 - **支付和金融 API 凭证**:处理器 token、商户密钥、client ID、client secret 以及与支付相关的环境变量。 - **数据库连接字符串**:SQL、文档存储、和 JDBC 风格的带有嵌入式凭证的 URI。 - **AI 和应用平台密钥**:模型提供商 API key、后端服务密钥以及应用平台服务凭证。 - **密钥管理和可观测性值**:vault 风格的 token、监控 DSN、API token 和服务角色密钥。 - **泄漏指标**:凭证 JSON 块、证书路径、本地包认证文件以及其他高信号配置片段。 - **通用赋值**:带有误报防护的 `secret_key`、`api_key` 和 `password` 赋值模式。 ### 添加模式 必须同时更新 `utils/patterns.py` 中的 `PATTERNS`(正则表达式)和 `PATTERN_CATEGORY`(类别字符串)。模块加载时的断言强制执行了这一点: ``` # 在 PATTERN_CATEGORY 中 "my_pattern": "credential", # 在 PATTERNS 中 "my_pattern": r"MY_PREFIX_[A-Za-z0-9]{32}", ``` 如果这两个字典不同步,导入时会立即引发 `AssertionError`。 ## 去重 每个发现结果的哈希值为 `SHA256(source | normalized_url | pattern_name | matched_value)`,并存储在 `seen_hashes.json` 中。后续运行会跳过任何已存在的哈希值 — 同一文件中的相同密钥不会被重复警报,而同一模式的新值仍可以被检测到。 GitHub 原始 URL 会被标准化(去除 commit SHA),以便不同 commit 中的同一文件映射到同一个哈希值。 诸如 SwaggerHub 规范和 Gist 文件之类的可变源会在后续运行中重新访问,因此不会遗漏新添加的密钥。去重会抑制已经见过的值的重复警报。 CLI (`harppia.py`) 默认参与相同的去重过程。传递 `--no-dedup` 可执行忽略历史记录的全新扫描。 ## 速率限制 | 来源 | 未经认证 | 已认证 | |---|---|---| | GitHub 代码搜索 | 10 次请求/分钟 | 30 次请求/分钟(使用 `GH_PAT`) | | GitHub Gists 时间线 | 60 次请求/小时 | 5,000 次请求/小时(使用 `GH_PAT`) | | SwaggerHub | 无需认证 | — | | Sourcegraph | 免费层级(受限) | 更高限制(使用 `SOURCEGRAPH_TOKEN`) | | npm registry | 无需认证 | — | | Pastebin Scraping API | 需要 IP 白名单 | 需要 Pro 账户 | 扫描器在请求之间包含 `time.sleep()` 调用以保持在限制范围内。如果您添加了许多关键词: - 减少 `scanners/github_gist.py` 中的 `TIMELINE_PAGES` 以扫描更少的 gist 时间线页面。 - 减少 `scanners/github_search.py` 中的 `EXTENSIONS` 以减少每个关键词搜索的文件类型。 - SwaggerHub 为每个关键词请求前 100 个 `BEST_MATCH` 规范。 - 默认情况下,Sourcegraph 将每个关键词的搜索结果限制为 50 个(`scanners/sourcegraph.py` 中的 `_COUNT`)。 - npm 将每个关键词的完整元数据获取限制为 50 次(`scanners/npm_registry.py` 中的 `_MAX_FULL_FETCH`)。 ## 开发 运行 quality workflow 所使用的相同检查: ``` python3 -m py_compile harppia.py compile.py scanners/*.py utils/*.py tests/*.py python3 -m unittest discover -s tests ``` 测试涵盖了脱敏、去重、报告加载(所有源)、GitHub 搜索 URL/内容处理以及边界感知的关键词匹配。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。
标签:ESC4, GitHub Actions, OSINT, 泄露监控, 自动化告警, 自动笔记, 逆向工具