NullSecHQ/nullsec-framework
GitHub: NullSecHQ/nullsec-framework
一款基于 Bash 的 12 阶段 Bug Bounty 侦察自动化框架,将被动枚举、主动探测、漏洞扫描与密钥提取整合为端到端的完整流水线。
Stars: 1 | Forks: 0
# NullSec — Bug Bounty 侦察自动化框架
```
███╗ ██╗ ██╗ ██╗ ██╗ ██╗ ███████╗ ███████╗ ██████╗
████╗ ██║ ██║ ██║ ██║ ██║ ██╔════╝ ██╔════╝ ██╔════╝
██╔██╗ ██║ ██║ ██║ ██║ ██║ ███████╗ █████╗ ██║
██║╚██╗██║ ██║ ██║ ██║ ██║ ╚════██║ ██╔══╝ ██║
██║ ╚████║ ╚██████╔╝ ███████╗ ███████╗ ███████║ ███████╗ ╚██████╗
╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═════╝
```
**作者:** NULLSEC — Bug Bounty 猎人 & 安全研究员
**平台:** Kali Linux (bash/zsh)
**许可证:** 仅限授权安全测试
## 概述
NullSec 是一个用 Bash 编写的完整 12 阶段 bug bounty 侦察流水线。它将被动枚举、主动探测、漏洞扫描、JavaScript 分析、模式匹配、模糊测试和自动漏洞确认串联成一个端到端的框架——具有三种扫描模式、断点续扫支持和并行执行能力以提升速度。
该脚本旨在针对 HackerOne 及类似 bug bounty 目标在已定义的范围内运行。它处理从首次接触的 DNS 枚举一直到最终报告生成的所有工作。
## 功能
- **12 阶段方法论**,涵盖完整的侦察生命周期
- **三种扫描模式** — `fast`、`normal` 和 `deep` — 分别针对每小时、每天和每周的执行频率进行了优化
- **断点续扫** — 中断的扫描可以通过 `-c` 从上次完成的阶段继续执行
- **并行执行** — 阶段 8 至 11 作为后台作业并发运行,以减少实际运行时间
- **资产评分** — 将多阶段信号合成为排名目标列表,以便昂贵的下游工具优先处理高价值主机
- **云存储枚举** — 并行测试 AWS S3、GCS 和 Azure Blob 存储桶,并支持自动生成的名称组合
- **JavaScript 密钥提取** — TruffleHog(已验证模式)加上高精度正则表达式,用于提取 AWS 密钥、GitHub token、Google API 密钥、Slack token、Stripe 密钥和 PEM 私钥
- **CORS 与 Host Header 注入测试** — 区分 CORS-CRITICAL(反射源)与 CORS-HIGH(通配符 + 凭证),并带有提前退出的限速检测机制
- **优雅中断** — SIGINT/SIGTERM 处理程序会清理临时文件并合并处理中的 `.bak` 文件,确保结果不会丢失
- **自动生成报告** — 包含所有 12 个阶段和发现结果的时间戳摘要
## 环境要求
### 必备工具
| 工具 | 用途 |
|------|---------|
| `subfinder` | 被动多源子域名枚举 |
| `amass` | 深度 DNS 图谱枚举 |
| `assetfinder` | 关联资产发现 |
| `puredns` | DNS 暴力破解与解析 |
| `dnsx` | 子域名解析与泛解析检测 |
| `httpx-toolkit` | HTTP 探测与存活主机发现 |
| `naabu` | 端口扫描 |
| `katana` | 感知 JS 的主动 Web 爬虫 |
| `waybackurls` | Wayback Machine URL 挖掘 |
| `gau` | 历史 URL 挖掘 (Common Crawl, OTX) |
| `unfurl` | URL 参数提取 |
| `arjun` | 主动参数发现 |
| `nuclei` | 基于模板的漏洞扫描 |
| `ffuf` | 目录与内容模糊测试 |
| `jq` | JSON 处理 |
| `curl` | HTTP 请求 |
| `trufflehog` | 已验证的密钥扫描 |
### 可选工具
以下工具在缺失时将被自动跳过:
`gotator`、`gowitness`、`dalfox`、`sqlmap`、`gf`、`anew`、`qsreplace`、`hakrawler`、`cariddi`、`dig`、`cloud_enum`、`s3scanner`
### 字典
该脚本预期 [SecLists](https://github.com/danielmiessler/SecLists) 位于 `/usr/share/wordlists/SecLists`,并且解析器列表位于 `/usr/share/wordlists/resolvers.txt`。这些路径可以在脚本顶部进行配置。
## 安装说明
```
git clone https://github.com/NullSecHQ/nullsec
cd nullsec
chmod +x nullsec.sh
```
在运行之前,请为您的 Kali 环境安装所有必备工具。大多数工具可以通过 `go install` 或 `apt` 获取。
## 运行说明
```
./nullsec.sh -d [options]
```
### 标志参数
| 标志 | 描述 |
|------|-------------|
| `-d ` | 目标域名(必填) |
| `-o ` | 输出目录(默认:`./recon--`) |
| `-m ` | 扫描模式:`fast`、`normal` 或 `deep`(默认:`normal`) |
| `-c ` | 从现有的扫描目录恢复 |
| `-s` | 跳过工具可用性检查 |
| `-u` | 扫描前更新 Nuclei 模板 |
| `-r` | 启用限速模式(各阶段之间休眠 10 秒) |
| `-h` | 显示用法 |
### 示例
```
# 普通扫描(默认,约 30-60 分钟)
./nullsec.sh -d example.com
# 带有自定义输出目录的深度扫描
./nullsec.sh -d example.com -m deep -o ./results/example
# 仅被动快速扫描(适用于每小时自动化)
./nullsec.sh -d example.com -m fast
# 恢复中断的深度扫描
./nullsec.sh -d example.com -c ./results/example -m deep
# 带有 Nuclei 模板更新的限速扫描
./nullsec.sh -d example.com -r -u
```
## 扫描模式
| 模式 | 运行时间 | 运行内容 |
|------|---------|-----------|
| `fast` | 5–15 分钟 | 仅被动子域名来源,不进行暴力破解,仅运行 critical(严重)级别的 Nuclei 模板。专为高频定期执行设计。 |
| `normal` | 30–60 分钟 | 完整发现 + DNS 暴力破解 + 云枚举 + 端口扫描 + JS 分析 + 模式匹配 + 屏幕截图。跳过 Arjun、模糊测试和主动确认。 |
| `deep` | 1–4+ 小时 | 完整的 12 阶段流水线。启用所有阶段,扩展容量(更大的存储桶组合列表、更多 JS 文件、更多屏幕截图)。 |
## 阶段参考
### 阶段 1 — 子域名发现
通过 Subfinder、Amass、Assetfinder 和 crt.sh 证书透明度进行被动枚举,随后进行基于 Hakrawler 响应的发现。可选择运行 PureDNS 暴力破解(最高支持 110,000 词的列表)和 Gotator 排列生成。所有来源的结果将被合并并去重。
### 阶段 2 — 验证与解析
使用 dnsx 解析所有发现的子域名,提取 A 记录,并过滤泛 DNS 记录。对所有已解析的子域名运行 Nuclei 接管模板。
### 阶段 2.5 — 云存储枚举
通过将目标 token(基础域名 + 有意义的子域名标签)与 50 多个云命名后缀组合,生成存储桶名称候选。并行对候选对象进行以下测试:
- **AWS S3** — 直接 HTTP 检查 + 区域 endpoint 探测 + s3scanner(如果可用)
- **Google Cloud Storage** — 并行 curl 检查 + IAM allUsers 检测
- **Azure Blob Storage** — 带有公共容器列表的并行 curl 检查
发现结果将输入到阶段 5 和 7。
### 阶段 3 — HTTP 探测
对所有已解析的子域名运行 httpx-toolkit 以识别存活的 Web 服务。按状态码(200/401/403/500)对结果进行分组,捕获响应元数据,通过基于 IP 的注入执行 vhost 发现,并识别技术栈。
### 阶段 4 — 端口扫描
在存活主机上针对排名前 1000 的端口运行 Naabu。对所有开放的非标准端口探测 HTTP/HTTPS 服务,并将发现的结果合并回存活主机列表。
### 阶段 5 — URL 发现与爬取
多来源 URL 收集:Katana(支持 JS,深度为 3)、Hakrawler、Cariddi(secrets + endpoint 模式)、Waybackurls 和 GAU(Common Crawl + OTX)。将结果分类为 API endpoint、敏感 endpoint、感兴趣文件和 JS 文件。验证存活的 JS 文件并运行 GF 模式匹配(XSS、SQLi、SSRF、redirect、LFI、IDOR)。
### 阶段 6 — 参数发现
使用 Unfurl 对完整的 URL 语料库进行被动参数提取。使用 Arjun 针对排名靠前的存活主机进行主动发现(可配置限制;仅在 deep 模式下运行)。
### 阶段 6b — 资产评分与优先级排序
使用加权评分模型将阶段 1-6 的数据合成为排名主机列表:
| 信号 | 分数 |
|--------|--------|
| 状态码 200(可达) | 5 |
| 状态码 401(需要认证) | 15 |
| 状态码 403(禁止访问) | 15 |
| 状态码 500(服务器错误) | 20 |
| 非标准端口 Web 服务 | 每个端口 10 分 |
| API endpoint | 每个路径 3 分 |
| 敏感 endpoint(admin/debug) | 每个路径 5 分 |
| 感兴趣文件(config/bak/env) | 每个文件 4 分 |
| GF 模式匹配 URL | 每个 URL 2 分 |
| 存活 JS 文件 | 每个文件 2 分 |
| 发现的参数 | 每个参数 1 分 |
| 感兴趣的技术栈关键字 | 10 |
输出包含一份完整的评分列表、前 25% 的目标短名单以及单主机评分摘要。
### 阶段 7 — 漏洞扫描
针对所有存活主机、云发现结果、敏感 endpoint 和 API 路径运行合并的 Nuclei 扫描。导出 JSON,以便通过 jq 将其切片为 API、暴露和 endpoint 的发现集合。严重级别过滤器受模式控制(在 normal 模式下为 critical/high/medium,在 deep 模式下为所有级别)。
### 阶段 8 — JavaScript 分析与密钥提取 *(并行)*
下载最多 `MAX_JS_FILES` 个存活的 JS 文件。在已验证密钥模式下运行 TruffleHog,然后通过定向正则表达式提取 AWS 访问密钥、Google API 密钥、GitHub token、Slack token、Stripe 实时密钥和 PEM 私钥。发现嵌入的完整 URL 和相对 API 路径,将其在存活主机上进行扩展,并使用 httpx 进行探测。
### 阶段 9 — 漏洞模式匹配 *(并行)*
对于所有候选类别,优先使用 GF 模式输出(高信号)而非后备正则表达式:SSRF、开放重定向、XSS、SQLi、LFI 和 IDOR。针对前 50 个 XSS 候选对象运行 Dalfox 自动 XSS 测试。在强制范围限制下,以前 10 个 SQLi 候选对象批量模式(level 2,risk 2)运行 SQLMap。在存活主机上测试 CORS 错误配置(反射源和通配符+凭证)以及 Host Header 注入,并带有限速退出机制。
### 阶段 10 — 屏幕截图与视觉侦察 *(并行)*
跨四个类别的批量 gowitness 扫描:403 Forbidden 页面(绕过候选对象)、敏感 endpoint、admin/panel/dashboard 主机以及所有存活主机。
### 阶段 11 — 目录与内容模糊测试 *(并行)*
针对评分最高的存活主机,使用 raft-large-directories 进行 ffuf 递归目录暴力破解。
### 阶段 12 — 主动漏洞确认
使用阶段 9 的模式发现结果运行 Nuclei 确认,定位主动漏洞模板。依赖于阶段 9 完成;在并行块之后运行。
## 输出结构
```
recon--/
├── phase1-subdomains/
│ ├── subfinder.txt
│ ├── amass.txt
│ ├── assetfinder.txt
│ ├── crtsh.txt
│ ├── puredns.txt
│ ├── permutations-resolved.txt
│ └── all-subdomains.txt
├── phase2-validation/
│ ├── resolved.txt
│ ├── valid-subdomains.txt
│ ├── wildcards.txt
│ └── takeover-findings.txt
├── phase2.5-cloud/
│ ├── s3/{exists,readable,writable}.txt
│ ├── gcs/{exists,readable,writable}.txt
│ └── azure/{exists,readable}.txt
├── phase3-probing/
│ ├── live-hosts.txt
│ ├── status-{200,401,403,500}.txt
│ └── clean-hosts.txt
├── phase4-portscan/
│ ├── open-ports.txt
│ └── services-on-ports.txt
├── phase5-urls/
│ ├── all-urls.txt
│ ├── api-endpoints.txt
│ ├── sensitive-endpoints.txt
│ ├── interesting-files.txt
│ ├── live-js-files.txt
│ └── gf-{xss,sqli,ssrf,redirect,lfi,idor}.txt
├── phase6-parameters/
│ ├── parameters.txt
│ └── arjun-all-params.txt
├── asset-scoring/
│ ├── scored-targets.txt
│ ├── top-targets.txt
│ └── scoring-summary.txt
├── phase7-vulns/
│ ├── all-findings.json
│ ├── api-findings.txt
│ ├── exposure-findings.txt
│ └── endpoint-findings.txt
├── phase8-javascript/
│ ├── js-files/
│ ├── trufflehog-secrets.json
│ ├── trufflehog-summary.txt
│ ├── aws-access-keys.txt
│ ├── github-tokens.txt
│ ├── google-api-keys.txt
│ ├── slack-tokens.txt
│ ├── stripe-keys.txt
│ ├── private-keys.txt
│ └── live-js-endpoints.txt
├── phase9-patterns/
│ ├── ssrf-candidates.txt
│ ├── redirect-candidates.txt
│ ├── xss-candidates.txt
│ ├── dalfox-xss-confirmed.txt
│ ├── sqli-candidates.txt
│ ├── sqlmap-results/
│ ├── lfi-candidates.txt
│ ├── idor-candidates.txt
│ ├── cors-findings.txt
│ └── host-injection-findings.txt
├── phase10-screenshots/
│ ├── 403/
│ ├── interesting/
│ ├── admin/
│ └── all/
├── phase11-fuzzing/
│ └── -ffuf.json
├── phase12-active/
│ └── confirmed-vulns.txt
├── reports/
│ └── recon-report.txt
└── .checkpoint
```
## 配置
所有可调值都位于脚本顶部的配置块中。关键设置:
```
# Wordlist 路径
WORDLIST_DIR="/usr/share/wordlists"
DNS_WORDLIST="$SECLISTS/Discovery/DNS/subdomains-top1million-110000.txt"
# 并发
HTTPX_THREADS=30
FFUF_THREADS=20
NUCLEI_RATE_LIMIT=50 # requests/second
# 限制
MAX_JS_FILES=50
MAX_ARJUN_HOSTS=5
MAX_SCREENSHOTS=50
MAX_CORS_HOSTS=100
MAX_BUCKET_MUTATIONS=200
# Nuclei 模板
NUCLEI_TEMPLATES="$HOME/nuclei-templates"
```
对于特定程序的设置(自定义 headers、速率限制、端口扫描限制),请使用一个包装脚本,该脚本加载配置文件并使用适当的标志调用 `nullsec.sh`。这可以将特定于程序的约束保留在核心脚本之外。
## 断点与恢复
当扫描被中断时,清理处理程序会合并所有处理中的 `.bak` 文件,从而保留先前的发现结果。恢复请使用:
```
./nullsec.sh -d example.com -c ./recon-example.com-20250503-143022
```
该脚本从输出目录中读取 `.checkpoint` 文件,并跳过直至(包括)最后完成阶段编号之前的所有阶段。阶段 2.5(云枚举)在恢复时总是重新运行,因为它是幂等且快速的。阶段 8-11 的组检查点仅在所有四个并行阶段完成后才写入,从而确保了清晰的恢复边界。
## 法律免责声明
本工具仅适用于您已获得明确测试授权的目标进行授权安全测试,例如 HackerOne 或类似 bug bounty 平台上的范围内资产。未经授权对您不拥有或未获准测试的系统进行使用是违法的。作者对滥用行为不承担任何责任。
*祝狩猎愉快! 🐛*
标签:ESC6, GitHub, HackerOne, 侦察框架, 子域名枚举, 安全研究员, 实时处理, 密码管理, 应用安全, 开源安全工具, 数据展示, 数据统计, 端口扫描, 系统安全, 红队, 网络安全, 逆向工程平台, 隐私保护