AutoHunter 拆解:24 小时挖洞机的真本事,是劝 AI 别乱提交

先说结论:这个项目值得看,但它最值钱的部分不是”能挖洞”,是”能让 AI 闭嘴”。

我把 StanleyNull/AutoHunter 的仓库整个过了一遍:186 个文件、24 个 agent 模块、46 个测试文件(约 260KB 测试代码)、12 个贡献者、206 次提交。其中最大的单个文件是 app/agents/prompts.py,130KB 纯提示词。

一个”自动化挖洞”的项目,代码量最大的地方是在教模型怎么说话、什么时候不许说话。这不是巧合,这是这类工具真正的护城河所在。

配图

一、它到底怎么跑

配图

一句话:Collector 找目标 → Worker 一对一挖 → Reviewer 初审 → 你点头。

它的分工是这样的:

  • Collector:从 FOFA 持续产出目标,探活、机械预筛、评分、归属标注后入队
  • Worker:每个目标一个 Worker,LLM 自主侦察 + 调真实工具链,出洞即提交
  • Reviewer:独立 AI 初审,不看 Worker 的挖掘过程、只看证据,过滤半成品和误报
  • 通杀 Hunter:某个洞被采纳后,去圈定同款系统、实打验证”能不能一打一片”
  • 控制台:实时看板、复审队列、情报库

作者给的定位很精确:“你只当人工复审员,醒来几分钟完成裁决。”

这里有个设计细节我很喜欢,在 scorer.py 的模块注释里:

评分只决定【先打谁】,绝不代表放弃——低分目标仍入队,只是排后面。

大部分自动化工具死在”提前放弃”上。这个选择说明作者想过:排序是优化,过滤是风险,两件事不能混。

二、真正的工程量:五道闸门

配图

这是我看完最想讲的部分。这套系统里有一整层”拦截器”,专门用来把 AI 的过度热情按下去。

① 敏感目标机械跳过(prefilter.py)

不耗 LLM 的硬规则:.gov / .mil / 军政公安关键词一律跳过,永不攻击;回环地址一律跳过,永不打本机;CDN / 对象存储 / 云 WAF 域名跳过;死链、纯静态 SPA 跳过。

判断原则写得很清楚:“拿不准就放行”——但敏感域名和回环地址无例外。

② 短信轰炸不收(edu_scope.py)

EduSRC 明确不收短信/邮箱轰炸,但这是 AI 最容易刷出来的”洞”——任何没做频率限制的发验证码接口都会被判成漏洞。所以作者把它做成了代码闸门,不单靠提示词:

若同一接口把短信/手机 OTP 明文写在 HTTP 响应里,并能打通任意用户登录或改密,按 OTP 回显提交,不要写成轰炸。

前半句拦住 90% 的噪音,后半句保住真正值钱的那一类。

③ 图床不算被黑(backdoor_proof.py)

这个误报我见过太多次:站点引用了外部图床、CDN、七牛、jsdelivr、Google Fonts,AI 就判”服务器被攻陷、植入暗链”。

作者的解法是加一道证据门槛:只有本站自身的 HTML 标题或正文被替换成赌博/色情/彩票,出现 hacked by / deface,或 webshell 可执行命令,才算。 引用第三方资源不算。

④ 越权删除怎么给”无害证据”(write_proof.py)

这个模块我觉得是全项目最巧的一个。它解决的是一个三方死结:

  • 安全上:不许改真实/他人数据
  • 审核上:只返回 200 / success 不算洞
  • 旧闸门:把”不存在 / data:0″和 URL 里的 delete 一律当失败

三条各自正确,叠起来的结果是:真正的高危删除漏洞,被自己的安全设计拦掉了。

所以作者定了一套”写操作无害证据”的分类:sentinel(哨兵值)、idempotent(幂等验证)、side_read(旁路读取)、authz_diff(授权差异对比)。用同一套分类同时约束 Worker 的提交闸门和 Reviewer 的改判。

翻成人话:证明你有权删,但没真删。

⑤ 跨任务去重(dedup.py)

指纹是 系统(host) + 端点(path/参数名/method) + 漏洞类型,且 key 不含 task_id / target_id,所以能跨任务复用。

这里有个很实际的工程细节:LLM 自由填写的漏洞类型五花八门——”水平越权”、”横向越权”、”IDOR”、”BOLA”、”平行越权”是同一个东西。作者建了一张同义词折叠表,把它们归并到一个规范类别,否则同一个洞换个写法就重复入库了。

这五道闸门加起来,才是”你几分钟能复审完”的原因。 不是因为它挖得准,是因为它交得少。

三、工具链是真的,不是纸上谈兵

容器里装的是:nmap · nuclei · sqlmap · httpx · whatweb · curl/wget/jq。

Worker 是真实发包、真实执行命令,不是让模型描述”我假设这里有 SQL 注入”。

但”真实执行”也带来了真实的风险,作者在 worker.py 里做了约束——比如一条正则专门拦宽范围 nmap:

_BROAD_NMAP_RE = re.compile(r"\bnmap\b[\s\S]*(?:-p\s*(?:-|1-10000|1-65535|0-65535)|--top-ports\s+\d{3,})", re.I)

同时还拦 sleep、拦 for 循环,防止模型自己写脚本刷请求。这些约束都是有代价的——它限制了模型的能力上限,但换来的是不会因为一个幻觉把 6 万个端口扫出去。

四、测绘引擎:六个,但语法不翻译

支持 FOFA / 360 Quake / Hunter / ZoomEye / Shodan / Censys,设置页配 Key 就能切。

有一个坑作者写在 README 里、也写在提交信息里(”明确写明测绘语法按所选引擎原样发送”):语法不会自动改写。

  • FOFA:body="管理" && org="China Education and Research Network Center"
  • Quake:title:"登录" AND domain:"edu.cn"
  • Hunter:web.title="登录" && domain.suffix="edu.cn"
  • Censys:host.dns.names: edu.cn

把 FOFA 的 body= 贴到 Quake 上,请求会直接失败——不会报”语法不兼容”,只会给你零结果。 这是最容易浪费一晚上的地方。

另外它支持自然语言意图:写”找全国高校的统一身份认证登录系统”,搜集模型会把它翻译成 FOFA 语法并逐轮演化。但注意——只对 FOFA 有效,换别的引擎必须自己写语法。

五、钱和时间:两个被低估的数

配图

有两个默认值,动手前必须知道。

① WORKER_MAX_ROUNDS=90,WORKER_SOFT_ROUNDS=45

每个 Worker 最多 90 轮 LLM 工具调用,到 45 轮时开始软收尾。每个目标一个 Worker,每个 Worker 90 轮——这是按目标数线性放大的账单。

② 四个 budget cap 默认全是 0

WORKER_ROUND_BUDGET_CAP=0
WORKER_SOFT_ROUND_BUDGET_CAP=0
ENTERPRISE_WORKER_ROUND_BUDGET_CAP=0
ENTERPRISE_WORKER_SOFT_ROUND_BUDGET_CAP=0

0 在这套配置里的意思是不限。默认给的是”能力最大化”,不是”成本最小化”。

并发是按 CPU/内存自动定的:1C1G → 3,2C4G → 8,大机器顶到 32。所以真正决定你花多少钱的是三个乘数:目标数 × 并发 × 90 轮。

作者的建议是拿 cap 收紧,我的建议更直接:先跑 20 个目标看单目标实际轮数和 token 消耗,再决定要不要开几百个。 这套系统不会替你省钱,它只会诚实反映你开了多大的口子。

六、天花板在哪:SQLite 那 372 个目标

配图

这是我读完 issue 区最想说的部分,因为它是作者自己记录在案的、诚实的失败。

Issue #83 和 #84(均为 2026-09-30 提交,至今 open):一个用户跑了 3 个任务、每个 concurrency=32、实际各 14 个 worker,合计 40+ 并发,1.5 天后日志累计 503 次 database is locked。

后果不是慢一点,是:

SELECT COUNT(*) FROM targets WHERE verdict='error' AND last_error LIKE '%database is locked%';
-- 372

372 个目标被写成终态 status='dead', verdict='error',不重试、不回队、不再被挖掘。 其中包含已经跑了大半流程的目标,全部损失。

根因很清楚:WAL 模式仍然是单写者。40+ 个 worker 的心跳、落库,加上 reviewer、killsweep、escalate 和 API 写入,全挤在同一个 SQLite 文件上,busy_timeout=5000 的 5 秒窗口在突发写入面前不够用。

而且这里有个更深的设计问题,报告者说得比我好:

database is locked 是瞬时基础设施故障,不是目标的安全结论。但写失败路径把它与真实挖掘结论同等对待。

把”我暂时写不进数据库”记成”这个目标没有漏洞”,这个错误比锁竞争本身严重得多。

结论也就明确了:这是一台单机工具,不是一个集群。 如果你想同时开三个任务、每个 32 并发,你得先接受它会划掉几百个目标——或者等作者把写路径的容错补上。

顺带说,issue #86 那个”不支持本地模型”的问题也值得看:用户填 192.168.254.164 想接 Ollama/vLLM,被 base_url 不被允许:目标解析到私有/保留地址 拦了。

这个拦截是对的(防 SSRF),但代价是自建模型的人得另想办法。安全和便利在这里没有两全。

七、两个必须自己盯住的地方

① 令牌默认是空的

README 里自己写得最狠:

AUTOHUNTER_API_TOKEN ⭐ 强烈建议 —— 控制台全权限令牌,不设则任何人可访问。

这句话的重量,你对照前几天的新闻就懂了:Censys 数出 1,465 台 ARTEX 控制台裸在公网上,其中 32 个还开着 .ssh 和 MITM 根证书私钥的目录。

AutoHunter 是同一个形状:默认端口 18800、默认 0.0.0.0 监听、令牌为空就等于全网可用。 区别在于作者已经把这层想进去了——内置应用层 WAF 默认开启、三档令牌(全权 / 只读 / 观摩)、install.sh 自动生成随机串。

但第一道门还是那把令牌。WAF 挡的是扫描器,挡不住知道你 IP 的人。

② 通杀会让它去打你没圈定的站

“通杀分析”是这个项目最有商业价值的功能:一个洞被采纳后,它按指纹去测绘引擎圈定同款系统,实打 1 个同款站点验证能否一打一片。

killsweep.py 里有一行很关键:

_EDU_FILTER = '(domain=".edu.cn" || cert="edu" || org="edu")'

它在查询上叠了教育行业限定。但这是一层”尽量收窄”,不是”保证不越界”——同款系统可能部署在你没有授权的单位。

好消息是作者给了开关:提交记录里有 “任务可关闭复审通过后的自动通杀”。

我的建议:第一次跑一定关掉。 等你确认它的圈定逻辑符合你的授权边界,再打开。

八、这个项目值不值得用

值得,但它挑人。

值得的地方:

  • 五道闸门是真下过功夫的,不是包装。130KB 提示词 + 260KB 测试代码,这个比例说明作者在认真对付误报
  • 真实工具链 + 独立 Reviewer + 跨任务去重,这三件事凑齐了才叫”流水线”,否则只是”批量脚本”
  • 归属证明那段(按 IP/域名查 ip138 得出归属单位 + 直接生成 EduSRC 提交 JSON)是真的省事,那是 SRC 提交里最烦的一步
  • Apache-2.0,随便改

挑人的地方:

  • SQLite 单写者天花板明确,别当集群用,三个任务 32 并发就会开始丢目标
  • 90 轮 × 并发 × 目标数,成本是你自己控制的,默认值不省钱
  • 通杀功能有边界风险,第一次跑先关
  • 测绘语法按引擎原样发送,换引擎不换语法会静默零结果

一句话:它是给”已经知道自己在干什么”的人用的工具。 你越清楚授权边界、越会控制预算,它越好用;你要是 docker compose up 然后丢着不管,它就是一台会自己花钱、并且可能打到别人家的机器。

最后

回到标题那句话。

这类工具的宣传语通常是”AI 帮你挖洞”。但真跑起来你会发现,决定它能不能用的不是挖掘能力,是噪音控制能力——一个每天交 200 个洞、190 个是误报的系统,你三天就不想用了;一个每天交 15 个、12 个能提交的系统,你能一直用下去。

prompts.py 那 130KB 和五个拦截模块,做的正是这件事。

挖洞这件事,AI 早就”能”了。难的是让它知道什么时候该闭嘴。 这个项目在认真解决后一半,这是我看完最认可的一点。

项目地址:https://github.com/StanleyNull/AutoHunter

暂无介绍....

延伸阅读:

AutoHunter 拆解:24 小时挖洞机的真本事,是劝 AI 别乱提交

StanleyNull/AutoHunter 仓库全量过了一遍:130KB 纯提示词、五道拦截闸门、真实 nmap/nu...

itadol5j
2026年11月8日
超800个Artex实例暴露公网:AI渗透测试工具反成风险入口

Censys 11月5日报告:1,465台主机在公网跑着 ARTEX 控制台,去掉650台同构模板后约815个独立部署—...

itadol5j
2026年11月8日
最强的矛也成了最强的盾:GPT-6 Cyber 发布,但成绩单里有四栏是往下走的

把 GPT-6 Cyber 的发布稿、11 月 5 日 System Card、Linux 内核研究报告和 Mozill...

itadol5j
2026年11月6日
一个星号吃掉所有密码:OpenSSH「sshole」CVE-2026-123158 排查与止血

musl + 无 PAM + 一个密码字段为 * 的账号 + 一个真 $6$ 哈希,四条凑齐就能用 257 字节以上的任...

itadol5j
2026年11月6日
这个 ARL 二开版确实能打,但二开全藏在一个非默认分支里

把 buddingworld/ARL-Next2 和上游 owl234/ARL-Next 逐个 blob 对完:默认 m...

itadol5j
2026年11月6日