therandomsecurityguy/flan-go-scan
GitHub: therandomsecurityguy/flan-go-scan
Flan 是一个用 Go 编写的模块化网络扫描器,集成了端口扫描、服务指纹识别、云端资产发现及 AI 分析功能。
Stars: 16 | Forks: 1

# flan
[](https://go.dev/dl/)
[](LICENSE)
[](https://github.com/therandomsecurityguy/flan-go-scan/actions/workflows/ci.yml)
Flan 是一个用 Go 编写的瑞士军刀式网络扫描器。它是 [Flan Scan](https://github.com/cloudflare/flan) 的继任者。
## 功能
- 具有并发限制的 TCP 端口扫描
- 通过 [fingerprintx](https://github.com/praetorian-inc/fingerprintx) 进行 51 种协议的服务指纹识别(SSH、HTTP、MySQL、Redis、RDP、PostgreSQL 等)
- 技术检测(Wappalyzer)和 CPE 生成
- TLS 证书检查(版本、密码套件、主题、颁发者、SAN、过期时间、自签名)
- 通过 `--tls-verify` 进行可选的严格 TLS 证书验证
- 通过 NVD API 按 CPE 查询 CVE
- 主机发现(TCP 探测以跳过死主机)
- 通过 10 个无需密钥的来源进行被动子域枚举(crt.sh、Common Crawl、Wayback Machine、RapidDNS、Anubis、Digitorus、HudsonRock、SiteDossier、THC、ThreatCrowd)
- CDN 检测(Cloudflare)—— 默认情况下在 CDN 主机上仅扫描端口 80/443
- DNS 枚举,支持通配符检测和自定义字典/解析器
- 通过 `CLOUDFLARE_API_TOKEN` 进行基于 Cloudflare Zone 的目标发现
- 通过标准 AWS SDK 凭证链或 `--aws-profile` 进行 AWS 资产发现
- NS、MX、TXT、CNAME 记录查询
- 支持 CIDR 和标准输入
- nmap top 100/1000 端口列表,以及扩展的 2000/5000 预设
- 扫描检查点和恢复
- 针对大规模运行的扫描防护(`max_targets`、`max_ports_per_target`、`max_duration`)
- 进度报告
- 通过 `--udp` 进行 UDP 服务检测(DNS、NTP、SNMP、IPSEC)
- 通过 `--crawl` 进行带有应用指纹识别的 Web 爬虫(基于路径、Header 和 Cookie 检测 60 多种 CMS、框架和管理工具)
- 针对云/管理/数据层面的默认深度产品指纹识别,例如 Kubernetes、Grafana、Vault、Elasticsearch、PostgreSQL、Redis、LDAP、SMB、GraphQL、OpenVPN 和 IPsec
- 上下文感知的速率限制和 TLS 检查 —— 在 Ctrl+C 时干净关闭
- 在 SIGINT/SIGTERM 时优雅关闭
- 通过 [Together API](https://together.ai) 进行 AI 驱动的安全分析(`Qwen/Qwen3.5-9B`)—— 每次扫描提供简要摘要,使用 `--analyze` 提供详细报告
- 带有 TTY 检测的精美流式 CLI 输出(管道传输时为 JSONL)
- 每次运行的扫描元数据报告(`scan-metadata-*.json`),用于审计
- JSON、JSONL(流式)、CSV 和文本输出
- 域模式输出保留子域和 IP 上下文(`hostname (ip):port`)
- 安全 Header 检查在 `2xx/3xx` HTTP 响应上进行评估;`4xx/5xx` 响应报告为已跳过
- 可通过 YAML 配置
## 架构

## 安装
从 GitHub 安装:
```
go install github.com/therandomsecurityguy/flan-go-scan/cmd/flan@latest
```
从源码安装(go 版本 > 1.21):
```
git clone git@github.com:therandomsecurityguy/flan-go-scan.git
cd flan-go-scan
go build -o flan ./cmd/flan
./flan --help
```
Docker:
```
git clone git@github.com:therandomsecurityguy/flan-go-scan.git
cd flan-go-scan
docker build -t flan .
docker run --rm flan --help
docker run --rm flan -t scanme.nmap.org --json
```
## 用法
```
flan --help
```
扫描单个目标:
```
flan -t scanme.nmap.org
```
扫描一个域(DNS 枚举 + 端口扫描):
```
flan -d example.com
```
从文件扫描 top 1000 端口:
```
flan -l targets.txt --top-ports 1000
```
直接对已开放的端点进行指纹识别:
```
flan -t scanme.nmap.org:22 --fingerprint-only
```
直接对已知的数据库或服务端点进行指纹识别:
```
flan -t 10.0.0.15:5432 --fingerprint-only
```
针对常见控制平面和管理层面的高信噪比平台指纹会自动显示,包括 `Kubernetes`、`Grafana`、`Vault`、`Artifactory`、`Elasticsearch`、`Consul`、`Prometheus`、`TeamCity` 和 `etcd`。
从标准输入扫描 CIDR 范围:
```
echo "10.0.0.0/24" | flan -l -
```
使用自定义字典和解析器扫描:
```
flan -d example.com -w wordlist.txt -r 8.8.8.8:53
```
仅被动枚举(跳过暴力破解):
```
flan -d example.com --passive-only
```
仅输出子域(subfinder 风格,每行一个):
```
flan -d example.com --subdomains-only
```
域扫描端口配置:
```
flan -d example.com --subdomain-ports web
```
调整被动枚举来源/设置:
```
flan -d example.com --subfinder-all --subfinder-max-time 10 --subfinder-threads 20
```
扫描 CDN 主机上的所有端口(默认仅 80/443):
```
flan -d example.com --scan-cdn
```
从 Cloudflare Zone 发现扫描目标:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include api.example.net
```
将 Cloudflare 发现限制为匹配的主机名:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include "api.example.net" --cloudflare-exclude "internal.example.net"
```
仅打印 Cloudflare 发现的主机名:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include "api.example.net" --subdomains-only
```
从 AWS 发现扫描目标:
```
AWS_PROFILE= flan --aws --aws-regions us-west-2
```
仅打印 AWS 发现的目标:
```
AWS_PROFILE= flan --aws --aws-regions us-west-2 --subdomains-only
```
写入标准化的 AWS 清单快照以便后续比对:
```
AWS_PROFILE= flan --aws --aws-regions us-west-2 --aws-inventory-out reports/aws-inventory.json
```
当存在之前的快照时,仅扫描新增或更改的 AWS 目标:
```
AWS_PROFILE= flan --aws --aws-regions us-west-2 --aws-inventory-out reports/aws-inventory.json --aws-delta-only
```
从 kubeconfig 验证 Kubernetes 访问:
```
flan --kubeconfig ~/.kube/config --kube-context prod-cluster
```
从已验证的集群枚举外部可访问的 Kubernetes 资源并扫描它们:
```
flan --kubeconfig ~/.kube/config --kube-context prod-cluster --kube-inventory
```
写入标准化的 Kubernetes 清单快照以便后续比对:
```
flan --kubeconfig ~/.kube/config --kube-context prod-cluster --kube-inventory --kube-inventory-out reports/kubernetes-inventory.json
```
当存在之前的快照时,仅扫描新增或更改的 Kubernetes 资源:
```
flan --kubeconfig ~/.kube/config --kube-context prod-cluster --kube-inventory --kube-inventory-out reports/kubernetes-inventory.json --kube-delta-only
```
写入标准化的 Cloudflare 清单快照以便后续比对:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include "api.example.net" --cloudflare-inventory-out reports/cloudflare-example-net.json
```
将当前的 Cloudflare 清单与之前的快照进行比对:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include "api.example.net" --cloudflare-inventory-out reports/cloudflare-example-net.json --cloudflare-diff-against reports/cloudflare-example-net-prev.json
```
当存在之前的快照时,仅扫描新增/更改的 Cloudflare 主机:
```
flan --cloudflare --cloudflare-zones example.net --cloudflare-include "api.example.net" --cloudflare-inventory-out reports/cloudflare-example-net.json --cloudflare-delta-only
```
启用 UDP 扫描:
```
flan -t scanme.nmap.org --udp
```
爬取 HTTP/HTTPS 服务以查找端点、敏感路径和应用指纹:
```
flan -t example.com --crawl
```
运行正常扫描并让 Flan 自动显示更深层的产品指纹:
```
flan -t api.example.com
```
使用自定义深度进行爬取:
```
flan -t example.com --crawl --crawl-depth 3
```
使用详细的 AI 驱动分析进行扫描(需要 `TOGETHER_API_KEY`):
```
flan -t scanme.nmap.org --analyze
```
使用自定义资产上下文文件进行策略感知的 AI 分析:
```
flan -t api.example.com --context /path/to/context.yaml
```
## 运行时行为
Flan 使用确定性的解析器链:如果提供了自定义解析器则使用它,否则使用系统解析器,然后是配置的后备解析器。解析器和缓存统计信息会记录在扫描元数据中。
```
scan:
rate_limit: 200
workers: 100
max_host_conns: 0
max_targets: 5000
max_ports_per_target: 5000
max_duration: 30m
dns:
resolver: ""
fallback_resolvers: ["1.1.1.1:53", "8.8.8.8:53"]
lookup_timeout: 3s
```
使用 `--workers`、`--rate-limit` 和 `--max-host-conns` 来调整扫描并发性,使大规模清单支持的运行对共享目标和负载均衡服务更加温和。
### 控制平面与发现

### Cloudflare 发现
Cloudflare 发现是基于 Zone 的。它保留 `A`、`AAAA` 和 `CNAME` 扫描候选,默认跳过验证、通配符和非公网 IP 记录。它可以持久化标准化的清单快照,在运行之间进行比对,并可选择将扫描范围缩小到新增或更改的主机。如果省略了 `--cloudflare-diff-against` 但设置了 `--cloudflare-inventory-out`,Flan 将重用清单输出路径作为比对基准。
```
cloudflare:
enabled: false
zones: []
include: []
exclude: []
token_env: CLOUDFLARE_API_TOKEN
timeout: 15s
inventory_out: ""
diff_against: ""
delta_only: false
```
```
GitHub Actions: set CLOUDFLARE_API_TOKEN as a repository secret.
Optional scope inputs: CLOUDFLARE_ZONES, CLOUDFLARE_INCLUDE, CLOUDFLARE_EXCLUDE, CLOUDFLARE_TOP_PORTS.
```
### AWS 发现
AWS 发现是以清单为先的。它从 `Route53`、`EC2`、`ELB/ELBv2`、`CloudFront`、`API Gateway`、`Lightsail`、`EKS`、`Lambda` 函数 URL 和 S3 网站端点收集公共扫描目标。它可以持久化标准化的清单快照,在运行之间进行比对,并可选择将扫描范围缩小到新增或更改的目标。如果省略了 `--aws-diff-against` 但设置了 `--aws-inventory-out`,Flan 将重用清单输出路径作为比对基准。
```
aws:
enabled: false
profile: ""
regions: []
include: []
exclude: []
timeout: 15s
inventory_out: ""
diff_against: ""
delta_only: false
```
```
Authentication uses the standard AWS SDK credential chain.
Common options: AWS_PROFILE=, aws sso login, or environment credentials.
```
### Kubernetes 访问
Kubernetes kubeconfig 支持是显式的。Flan 可以通过 API 服务器 `/version` 端点验证集群访问,或者在启用 `--kube-inventory` 时从已验证的集群访问中枚举外部相关资源。当前的清单阶段专注于 API 服务器元数据、`Ingress` 资源、`LoadBalancer` 服务和外部可访问的 `NodePort` 服务。Kubernetes 衍生的扫描结果会将集群、命名空间、资源种类和暴露元数据带入输出和 AI 摘要中。
```
kubernetes:
enabled: false
inventory: false
kubeconfig: ""
context: ""
timeout: 10s
inventory_out: ""
diff_against: ""
delta_only: false
```
```
Path resolution order when Kubernetes mode is enabled: --kubeconfig, config file, KUBECONFIG, then ~/.kube/config.
Use --kube-context when the kubeconfig contains multiple contexts.
Use --kube-inventory to turn authenticated cluster access into scan targets.
If --kube-diff-against is omitted but --kube-inventory-out is set, Flan reuses the inventory output path as the diff base.
```
## 标志
| 标志 | 描述 |
|------|-------------|
| `-t` | 目标主机/IP |
| `-l` | 目标文件(默认 `ips.txt`,`-` 表示标准输入) |
| `-d` | 通过 DNS 枚举的域 |
| `-p` | 要扫描的端口 |
| `--top-ports` | 使用常用端口配置:`100`、`1000`、`2000` 或 `5000` |
| `--subdomain-ports` | 域模式端口配置:`web`、`standard` 或 `full` |
| `-c` | 配置文件(默认 `config/config.yaml`) |
| `--workers` | 并发扫描工作线程数 |
| `--rate-limit` | 全局每秒扫描请求数 |
| `--max-host-conns` | 每个主机 IP 的最大并发扫描连接数(`0` 表示禁用) |
| `--fingerprint-only` | 将手动输入视为 `host:port` 目标并跳过主机发现 |
| `-w` | 自定义 DNS 子域字典 |
| `-r` | 自定义 DNS 解析器(ip:port) |
| `--cloudflare` | 从 Cloudflare Zone DNS 记录中发现扫描目标 |
| `--cloudflare-zones` | 逗号分隔的 Cloudflare Zone 过滤器 |
| `--cloudflare-include` | 逗号分隔的主机名包含过滤器 |
| `--cloudflare-exclude` | 逗号分隔的主机名排除过滤器 |
| `--cloudflare-inventory-out` | 将标准化的 Cloudflare 清单快照写入此路径 |
| `--cloudflare-diff-against` | 将当前的 Cloudflare 清单与之前的快照进行比较;省略时默认为 `--cloudflare-inventory-out` |
| `--cloudflare-delta-only` | 当存在之前的快照时,仅扫描新增/更改的 Cloudflare 主机 |
| `--aws` | 从 AWS 资产中发现扫描目标 |
| `--aws-profile` | 要使用的 AWS 共享配置配置文件 |
| `--aws-regions` | 逗号分隔的 AWS 区域过滤器 |
| `--aws-include` | 逗号分隔的 AWS 目标包含过滤器 |
| `--aws-exclude` | 逗号分隔的 AWS 目标排除过滤器 |
| `--aws-inventory-out` | 将标准化的 AWS 清单快照写入此路径 |
| `--aws-diff-against` | 将当前的 AWS 清单与之前的快照进行比较;省略时默认为 `--aws-inventory-out` |
| `--aws-delta-only` | 当存在之前的快照时,仅扫描新增/更改的 AWS 目标 |
| `--kubeconfig` | 用于 Kubernetes 验证的 kubeconfig 路径 |
| `--kube-context` | 可选的 kubeconfig 上下文 |
| `--kube-inventory` | 从选定集群枚举外部可访问的 Kubernetes 资源 |
| `--kube-inventory-out` | 将标准化的 Kubernetes 清单快照写入此路径 |
| `--kube-diff-against` | 将当前的 Kubernetes 清单与之前的快照进行比较;省略时默认为 `--kube-inventory-out` |
| `--kube-delta-only` | 当存在之前的快照时,仅扫描新增/更改的 Kubernetes 资源 |
| `--passive-only` | 跳过暴力破解,仅使用被动来源 |
| `--subdomains-only` | 打印发现的子域并退出(不进行端口扫描) |
| `--subfinder-sources` | 逗号分隔的被动来源覆盖 |
| `--subfinder-exclude-sources` | 逗号分隔的要排除的被动来源 |
| `--subfinder-all` | 使用所有 subfinder 被动来源 |
| `--subfinder-recursive` | 仅使用支持递归的被动来源 |
| `--subfinder-max-time` | 最大枚举时间(分钟) |
| `--subfinder-rate-limit` | 被动枚举 HTTP 请求/秒 |
| `--subfinder-threads` | 被动枚举线程数 |
| `--subfinder-provider-config` | subfinder 提供者配置路径 |
| `--scan-cdn` | 扫描 CDN 主机上的所有端口(默认:仅 80/443) |
| `--udp` | 启用 UDP 扫描(默认端口 53、123、161、500) |
| `--crawl` | 爬取 HTTP/HTTPS 服务以查找端点、敏感路径和应用指纹 |
| `--crawl-depth` | 最大爬取深度(默认:2) |
| `--tls-enum` | 枚举支持的 TLS 版本和密码套件(每个 TLS 端口约 60 个连接,默认关闭) |
| `--tls-verify` | 验证 TLS 证书以进行 TLS 检查、爬取、Header 探测和 TLS 枚举 |
| `--context` | 资产上下文 YAML 文件(如果存在则自动加载 `config/context.yaml`) |
| `--analyze` | 通过 Together API 进行详细的 AI 安全分析(需要 `TOGETHER_API_KEY`) |
| `--json` | JSON 输出 |
| `--jsonl` | JSONL 流式输出 |
| `--csv` | CSV 输出 |
## 测试
```
go test ./... -v
```
## 许可证
BSD 3-Clause License
标签:AWS资产, C2日志可视化, CDN检测, Cloudflare, CPE生成, CVE查询, DNS枚举, Go语言, GraphQL安全矩阵, MITRE ATT&CK, TLS证书, Web爬虫, 二进制发布, 域名枚举, 多线程扫描, 子域名枚举, 子域名突变, 安全扫描器, 开源工具, 技术栈识别, 指纹识别, 数据统计, 日志审计, 服务发现, 程序破解, 端口扫描, 系统安全, 网络安全, 网络安全工具, 网络工具, 请求拦截, 隐私保护