VTX-Labs/recon
GitHub: VTX-Labs/recon
vtx-recon:验证密钥,证明能力。
Stars: 0 | Forks: 0
```
██╗ ██╗████████╗██╗ ██╗ ██████╗ ███████╗ ██████╗ ██████╗ ███╗ ██╗
██║ ██║╚══██╔══╝╚██╗██╔╝ ██╔══██╗██╔════╝██╔════╝██╔═══██╗████╗ ██║
██║ ██║ ██║ ╚███╔╝█████╗██████╔╝█████╗ ██║ ██║ ██║██╔██╗ ██║
╚██╗ ██╔╝ ██║ ██╔██╗╚════╝██╔══██╗██╔══╝ ██║ ██║ ██║██║╚██╗██║
╚████╔╝ ██║ ██╔╝ ██╗ ██║ ██║███████╗╚██████╗╚██████╔╝██║ ╚████║
╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝
```
# vtx-recon
**授权交互的秘密情报 — 找到一个密钥,然后证明它实际上能做什么。**
[](https://pypi.org/project/vtx-recon/)
[](https://www.npmjs.com/package/@vtx-labs/recon)
[](https://github.com/VTX-Labs/recon/actions)
[](https://vtx-labs.github.io/recon/)
[](LICENSE)
[](TERMS.md)
找到的秘密仅仅存在并不算发现。找到的秘密,你能证明它确实
做了程序关心的某件事,才是。 [TruffleHog](https://github.com/trufflesecurity/trufflehog)
找到秘密并告诉你它们是否活跃;**vtx-recon 从这里开始** —
它运行有序的、**只读能力等级**来证明 _访问深度_,
将每个密钥分为 **已验证 / 有效 / 被拒绝**,并生成一个
经过编辑、带时间戳的证据包,你可以将其放入报告中。
```
trufflehog ──▶ findings ──▶ vtx-recon ladder ──▶ PROVEN / VALID / DENIED ──▶ evidence bundle
(find + (live/ (safe, ordered (impact tier) (JSON + Markdown,
verify) dead) read-only probes) secrets redacted)
```
## 两种原生实现,一个工具
vtx-recon 以 **两个一等、行为等效的包** 交付 — 选择适合你堆栈的一个。
两者都暴露了相同的 `vtx-recon` CLI、相同的
管道和相同的安全保证。
| | Package | Install | Source |
| :------------ | :----------------------------------------------------------------------- | :------------------------------------------------- | :------------------- |
| 🐍 **Python** | [`vtx-recon`](https://pypi.org/project/vtx-recon/) (PyPI) | `pipx install vtx-recon` | [`python/`](python/) |
| 📦 **Node** | [`@vtx-labs/recon`](https://www.npmjs.com/package/@vtx-labs/recon) (npm) | `npm i -g @vtx-labs/recon` · `npx @vtx-labs/recon` | [`node/`](node/) |
Node 构建没有 **运行时依赖**(内置 `fetch` + `node:crypto`);
Python 构建只依赖于 `httpx`。
## 需求
两个实现都协调 **TruffleHog** 二进制文件 — 首先安装它:
```
# macOS / Linux
brew install trufflehog
# 或:curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sh -s -- -b /usr/local/bin
```
## 快速入门
```
# 在仓库中查找并验证秘密,然后爬取活跃的(只读):
vtx-recon find . --i-am-authorized "bugbounty:acme"
# 验证你已有的单个密钥:
echo "AIza..." | vtx-recon ladder --i-am-authorized "bugbounty:acme"
# 机器可读证据包:
vtx-recon ladder --key ghp_xxx --i-am-authorized "h1:acme" --json
```
无论你安装了 Python 还是 Node 包,命令都是相同的。
默认情况下 **只运行安全的、只读的探测** — 花费金钱、读取
PII 或更改状态的探测是 **受控的**(下面),除非你激活它们,否则永远不会运行。
## 安全模型 — 默认只读,受控构建
每个探测都是两个等级之一:
- **安全** — 只读、不计费、幂等的(列表模型、`GetCallerIdentity`、
`auth.test`、读取令牌作用域)。默认运行。
- **受控** — 计费、读取 PII、更改状态或创建资源
(Gemini `generateContent` / 文件上传、计费的 Maps 调用、Firebase
匿名注册、Stripe 账户读取)。
除非你传递 **两个**:
```
--prove # arm gated probes
--i-am-authorized "" # name the engagement you're authorized to test
```
否则,受控探测在结构上是 **不可达的**。这是在代码中强制执行的
— Python [`safety.py`](python/src/vtx_recon/safety.py)、
Node [`safety.ts`](node/src/safety.ts) — 相同:一个受控探测在
任何网络调用之前如果没有完全授予同意,就会引发
**错误**,并失败。授权范围会原封不动地记录在证据包中,因此
每个动作都可以追溯。能力等级拒绝在没有命名范围的情况下运行。
## 能力等级
**51 个提供商** 随附一个专用等级,从密钥的形状 / TruffleHog 检测器名称自动检测。
每个等级从最便宜/最安全的开始,到最深:
首先是身份/whoami,然后是 reach/scope,然后是影响性的梯级。受控梯级标记为 🔒。
如果一个梯级需要一个引擎无法仅从密钥中推导出的
外部值(第二个凭证的一半、账户/主机/项目 ID),它永远不会发出
实时调用 — 它打印出精确的、可复制粘贴的安全 `curl`,其中密钥保持为 `$KEY`(标记为 _手动_),供授权操作员手动运行。
Python 和 Node 构建都包含相同的提供商,具有相同的梯级。
**云和基础设施**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Google / Gemini** (`AIza…`) | list models → files → cachedContents → corpora; read-only Referer-bypass on a referer-restricted key | `generateContent`, file upload, billable Maps probe, Firebase anon-signup |
| **GCP** (service-account JSON) | mint OAuth2 token → tokeninfo → list projects _(manual: engine can't sign the JWT)_ | list storage buckets 🔒 _(manual)_ |
| **AWS** (`AKIA`/`ASIA`) | STS `GetCallerIdentity` (stdlib SigV4, needs paired secret) | `iam:GetAccountAuthorizationDetails` 🔒 (bulk org/PII read) |
| **Azure** (Storage SAS) | SAS resource probe → service-principal token _(manual: needs account/container)_ | list blobs 🔒 _(manual)_ |
| **Cloudflare** (API token) | verify token → permission groups → list zones | edit DNS record 🔒 _(manual)_ |
| **DigitalOcean** (`dop_v1_`…) | `/account` → list droplets | create droplet 🔒 _(manual)_ |
| **Heroku** (Platform key) | `/account` → list apps | read app config vars 🔒 _(manual)_ |
| **Render** (`rnd_`) | list owners → list services | read service env vars 🔒 _(manual)_ |
| **Vercel** (access token) | `/user` → list projects | read decrypted project env 🔒 _(manual)_ |
| **Netlify** (PAT) | `/user` → list sites | read site/account env 🔒 _(manual)_ |
| **Fastly** (`Fastly-Key`) | token self → list services | purge-all cache 🔒 _(manual)_ |
**数据存储**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Supabase** (`service_role` JWT) | REST root / OpenAPI schema _(manual: needs project ref)_ | list table rows, list auth users 🔒 _(manual)_ |
| **PlanetScale** (`pscale_tkn_`) | list orgs → list databases _(manual: needs token id + org)_ | create branch 🔒 _(manual)_ |
| **Snowflake** (account+user+pass) | `CURRENT_USER()` → list databases _(manual: needs KEYPAIR_JWT)_ | exfil table data 🔒 _(manual)_ |
| **Airtable** (`pat…`) | `whoami`+scopes → list bases | list base records 🔒 _(manual)_ |
| **Algolia** (admin key) | own-key ACL → list all keys → list indices _(manual: needs App ID)_ | clear index 🔒 _(manual)_ |
**CI/CD & packages**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **GitHub** (`ghp_`/`github_pat_`) | `/user` identity → scopes → dangerous-scope flag → reachable private repos → org walk | demonstration state-changing `PUT` 🔒 (proves the boundary is wired) |
| **GitLab** (`glpat-`) | `/user` identity → token scopes | — |
| **Bitbucket** (`ATBB…` app pw) | `/user` whoami → repo permissions _(manual: needs paired username)_ | create repository 🔒 _(manual)_ |
| **CircleCI** (`CCIPAT_`) | `/me` whoami → collaborations | trigger pipeline 🔒 _(manual)_ |
| **Travis CI** (token) | `/user` whoami → list repos | trigger build 🔒 _(manual)_ |
| **Terraform Cloud** (`.atlasv1.`) | account details → list orgs | create run 🔒 _(manual)_ |
| **Docker Hub** (`dckr_pat_`) | auth-token exchange → list namespace repos _(manual: needs username/JWT)_ | delete repository 🔒 _(manual)_ |
| **npm** (`NpmToken`) | `/-/whoami` → token type | publish package 🔒 _(manual)_ |
| **PyPI** (`pypi-` macaroon) | — (upload-only token, no read surface) | publish package 🔒 _(manual)_ |
**通信和电子邮件**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Slack** (`xox…`) | `auth.test` → conversations → users → files | read channel history, post message 🔒 _(manual)_ |
| **Discord** (bot token) | `/users/@me` → guilds | read channel history, send message 🔒 _(manual)_ |
| **Twilio** (`AC…` SID) | account fetch → phone numbers _(manual: needs AuthToken)_ | read balance 🔒 _(manual)_ |
| **SendGrid** (`SG.…`) | `/v3/scopes` (validity + scopes) | send mail 🔒 |
| **Mailgun** (`key-…`) | list domains → list DKIM keys | send message 🔒 _(manual)_ |
| **Mailchimp** (`…-us21`) | API root whoami → list audiences | add list member 🔒 _(manual)_ |
| **Postmark** (server token) | `/server` → delivery stats | send email 🔒 _(manual)_ |
| **Pusher** (channel key) | list channels → channel info _(manual: needs secret+app_id HMAC)_ | trigger event 🔒 _(manual)_ |
**支持与生产力**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Asana** (PAT/OAuth) | `/users/me` → list workspaces | list workspace users (PII) 🔒 _(manual)_ |
| **Linear** (`lin_api_`) | viewer identity → organization | list org users (PII) 🔒 |
| **Notion** (`secret_`/`ntn_`) | `/users/me` bot user | list users, search shared content 🔒 |
| **Intercom** (access token) | `/me` → list admins | list contacts (PII) 🔒 |
| **HubSpot** (`pat-…`/OAuth) | token-info / account-info (whoami + scopes) | list CRM contacts (PII) 🔒 |
| **Zendesk** (`ZendeskApi`) | current user → list users _(manual: needs subdomain+email)_ | list tickets (PII) 🔒 _(manual)_ |
| **Figma** (`figd_`) | `/v1/me` whoami → list team projects _(manual)_ | — |
**可观察性和运维**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Datadog** (`DD-API-KEY`) | `/validate` (live check) → current user → list monitors _(manual: needs app key)_ | — |
| **Grafana** (`glsa_…`) | current user → user permissions → list datasources _(manual: needs host)_ | — |
| **New Relic** (`NRAK-`) | viewer identity → list accounts | — |
| **Sentry** (`sntryu_`/`sntrys_`) | list organizations → list org projects _(manual)_ | read project issues (PII) 🔒 _(manual)_ |
| **PagerDuty** (API key) | `/abilities` → list users | create incident 🔒 _(manual)_ |
**支付和SaaS**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **Stripe** (`sk_`/`rk_`) | `/v1/balance` auth → products → balance transactions | account read, charges list (PII) 🔒 |
| **PayPal** (`PaypalOauth`) | OAuth2 token → userinfo _(manual: needs client id+secret)_ | create payout 🔒 _(manual)_ |
| **Square** (`EAAA…`) | list locations → merchant `/me` → team members | create payment 🔒 _(manual)_ |
| **Shopify** (`shpat_`) | access scopes → shop info _(manual: needs shop domain)_ | list customers (PII) 🔒 _(manual)_ |
**AI**
| Provider | 安全梯级(只读) | 受控梯级 🔒 |
| :------- | :--------------------- | :------------- |
| **OpenAI** (`sk-`/`sk-proj-`) | `/v1/models` (validity) | chat completion (billable) 🔒 |
| **Anthropic** (`sk-ant-`) | `/v1/models` (validity) | create message (billable) 🔒 |
除了这 51 个之外,通用的声明性层是一个 **运行时可扩展性挂钩**:注册一个 `ProviderSpec`(每个梯级一个头部 + 只读端点)来插入新的提供商作为数据,无需更改核心。
声明的计费梯级被视为 **安全** 时会被拒绝;当规范没有自动梯级时,它会打印出精确的安全 `curl`。它不再是上面列出的命名提供商的万能工具 — 每个现在都有自己的专用等级。
## 影响等级
| Verdict | Meaning |
| :--------- | :----------------------------------------------------------------------------------------------------------- |
| **PROVEN** | 一个受控探测(在同意的情况下)运行并展示了实际影响。报告这一点。 |
| **VALID** | 认证和安全的探测证明了访问深度,但没有执行任何有影响的事情。通常具有信息性。 |
| **DENIED** | 活跃但每个探测到的能力都被拒绝。 |
| **/A** | 无法验证,或没有此提供商的等级。 |
## 退出代码
| Code | Meaning |
| :--- | :---------------------------------------------------------------- |
| `0` | 成功 |
| `1` | 运行时错误 |
| `2` | 使用错误 |
| `3` | TruffleHog 二进制文件未找到 |
| `4` | 需要授权范围(没有 `--i-am-authorized` 的等级) |
| `5` | 受控探测被阻止(缺少 `--prove` / 范围) |
## 开发
```
# Python
cd python && pip install -e ".[dev]" && ruff check . && pytest
# Node
cd node && pnpm install && pnpm typecheck && pnpm test && pnpm build
```
两个测试套件都模拟所有网络和 TruffleHog 二进制文件 — 它们永远不会接触真实的 API 或凭证。
## 许可证
[MIT](LICENSE) © [VTX Labs](https://vtxlabs.dev). 使用受 [TERMS.md](TERMS.md)
管理。
由 [VTX Labs](https://vtxlabs.dev) 构建 · [GitHub](https://github.com/VTX-Labs) · [@vtxlabs](https://x.com/vtxlabs)
标签:GNU通用公共许可证, MITM代理, Node.js, Python, 代码审查, 安全实践, 安全意识, 安全测试, 安全社区, 开源许可, 情报分析, 授权访问, 攻击性安全, 文档, 无后门, 红队平台, 网络诊断, 逆向工具