突破 FOFA API 搜索的单次一万条返回上限,通过智能查询拆分实现低成本获取尽可能全面的搜索结果。
众所周知,FOFA 非 F 点付费的请求有单次一万条的返回上限,而 F 点付费非常昂贵。
fofaMAX 的核心思路是:用更精准的语法拆分查询,将一个大查询拆分成多个小查询,每个小查询的结果都在 1 万条以内,最后聚合去重。
程序构建一棵虚拟的查询树,通过 DFS(深度优先搜索)逐层拆分:
Root: title="bing" (50,000 results)
├── country="US" (15,000 → 继续拆分)
│ ├── region="California" (4,000 → 直接获取 ✅)
│ ├── region="Virginia" (3,500 → 直接获取 ✅)
│ ├── region="Texas" (2,000 → 直接获取 ✅)
│ └── [REMAINDER] country="US" && region!="California" && ... (5,500 → 直接获取 ✅)
├── country="CN" (12,000 → 继续拆分)
│ ├── region="Beijing" (3,000 → 直接获取 ✅)
│ ├── region="Guangdong" (2,500 → 直接获取 ✅)
│ └── [REMAINDER] ... (6,500 → 直接获取 ✅)
├── country="DE" (5,000 → 直接获取 ✅)
├── country="JP" (3,000 → 直接获取 ✅)
└── [REMAINDER] country!="US" && country!="CN" && ... (8,000 → 直接获取 ✅)
| 层级 | 维度 | 说明 |
|---|---|---|
| 1 | 国家 (country) |
按国家代码拆分,从云服务/互联网热门国家到冷门排序 |
| 2 | 省份 (region) |
对中国、美国等有省/州概念的国家,按省份继续拆分 |
| 3 | 时间 (after/before) |
按月份时间段拆分 |
| 4 | 域名 (is_domain) |
按 is_domain=true/false 拆分 |
智能余量收集:在每一层拆分中,当 剩余量 = 预期总量 - 已获取量 ≤ 10000 时,使用 != 排除已查询的值,一次性获取剩余结果,避免不必要的请求。
git clone https://github.com/yourname/fofaMAX.git
cd fofaMAX
pip install -r requirements.txt设置 FOFA API Key:
export FOFA_API_KEY="your_fofa_api_key_here"或在命令行中通过 --key 参数传入。
# 基本查询,结果导出为 CSV
python -m src -q 'title="bing"' -o results.csv
# 指定返回字段
python -m src -q 'app="Microsoft-Exchange"' -o results.json -f ip,port,host,title
# 仅查看数量(不获取数据)
python -m src -q 'server="nginx"' --count-only
# 详细日志模式
python -m src -q 'body="admin"' -o results.txt --verbose
# 使用指定 API Key
python -m src -q 'title="test"' -o results.csv --key YOUR_KEY| 参数 | 说明 | 默认值 |
|---|---|---|
-q, --query |
FOFA 查询语句(必填) | - |
-o, --output |
输出文件路径,支持 .csv/.json/.txt | results.csv |
-f, --fields |
返回字段,逗号分隔 | ip,port,host,domain,protocol,country,region,city |
--key |
FOFA API Key | 环境变量 FOFA_API_KEY |
--url |
FOFA API 地址 | https://fofa.info/api/v1 |
--no-full |
仅搜索最近一年数据 | 搜索全部数据 |
--count-only |
仅显示总数 | - |
--show-tree |
显示 DFS 树统计 | 默认开启 |
-v, --verbose |
详细日志 | - |
from src import FofaClient, Orchestrator
client = FofaClient(api_key="your_key")
orch = Orchestrator(client, fields="ip,port,host,title")
result = orch.search('title="bing"')
print(f"预期: {result.total_expected}")
print(f"获取: {result.total_fetched}")
print(f"覆盖率: {result.coverage_ratio:.2%}")
# 结果在 result.results 中,每条是一个 list
for row in result.results[:5]:
print(row) ____ __ __ ______ _ __
/ __/____ / /_ ___ / |/ / || \/ /
/ /_ / __ \ / __ `__ / /|_/ / /| | \ /
/ __// /_/ // / / / // / / / ___ | / /
/_/ \____//_/ /_/ //_/ /_/_/ |_|/_/
Break FOFA's 10K limit
============================================================
📊 Search Summary
============================================================
Query: title="bing"
Expected total: 52,341
Fetched: 48,892
Coverage: 93.41%
Time elapsed: 127.3s
API requests: 156
Quota used: 48,892
============================================================
📂 DFS Tree Statistics:
------------------------------------------------------------
📂 ROOT: expected=52341, got=48892, coverage=93.4% [split by: country]
📂 country=US: expected=15234, got=14890, coverage=97.7% [split by: region]
🍃 region=California: expected=4012, got=4012, coverage=100.0%
🍃 region=Virginia: expected=3521, got=3521, coverage=100.0%
...
📂 country=CN: expected=12045, got=11823, coverage=98.2% [split by: region]
🍃 region=Beijing: expected=3001, got=3001, coverage=100.0%
...
------------------------------------------------------------
✅ Results exported to: results.csv
fofaMAX/
├── src/
│ ├── __init__.py # 包入口,导出公共 API
│ ├── __main__.py # python -m src 入口
│ ├── cli.py # 命令行界面
│ ├── client.py # FOFA API 客户端
│ ├── config.py # 配置常量(国家列表、省份列表等)
│ ├── orchestrator.py # DFS 编排器(核心引擎)
│ ├── output.py # 结果导出(CSV/JSON/TXT)
│ └── strategies.py # 拆分策略(国家/省份/时间/布尔)
├── fofa-api文档.md # FOFA API 参考文档
├── fofa规则.md # FOFA 查询语法参考
├── requirements.txt
├── LICENSE
└── README.md
策略系统设计为可插拔的:
- 每个拆分策略实现
split()/can_exclude()/build_exclusion_query()接口 - 可以轻松添加新的拆分维度(如按端口、按协议、按 ASN 等)
- 策略链的顺序可以自定义调整
- 每一层都有独立的统计和覆盖率追踪
MIT