ShadowScan:让AI参与判定的影子端点扫描器"

admin 2026-11-02 15:02:42 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

ShadowScan:让 AI 参与判定的影子端点扫描器

原创

aerfa21
aerfa21

我的安全视界观

2026年11月2日 06:06
北京

去阅读

上一篇《影子端点专项扫描:AI \"用进\"安全的一次实践》讲了背景、定位和整体设计。这篇重点写 AI 怎么参与判定、三次改版,以及被真实目标打出来的工程坑。项目已开源:https://github.com/Aerfa21/shadowscan

一、为什么做这个

做资产排查时一直有个盲区:Druid 监控台、Swagger 文档页、Spring Boot Actuator、.git源码目录、中间件管理台。这些端点不在业务系统设计文档中,资产台账上也查不到,但一旦暴露,往往直接可读配置、密钥、内存转储,或者还原源码。

常规漏扫扫不到它们,原因主要在路径上:只测/admin、/login这类固定路径;不认/portal/V1这样的上下文前缀;靠 200/404 判断,而 Java 应用对任意路径都可能返回 200 或统一错误页;未带 cookie 时返回登录页,容易被判成“不存在”。这类端点需要一套专门的路径和签名,通用漏扫加大字典并不能解决。

二、先试过的两条路

最早试过两个方向:从应用日志里做路径规则,以及收到告警后自动验证。两者都受限于同一个前提 - - 先有日志或告警,才有后面的检测。从SRC漏洞数据分析来看,影子端点又多次出现在没有日志、没有告警的资产上,所以效果一直有限。

三、工具怎么设计

定位很窄:只做影子端点这一类,不做 SQLi/XSS/命令注入,也不做组件 CVE Nday扫描。

核心链路:

资产清单 → 站点发现(域名解析 + 34 个端口 + HTTP/HTTPS 存活)        → 框架指纹 + 上下文前缀收集        → 规则库扫描(81 条规则 × 9 类,内容签名判定)        → AI 自适应扩探(扫描期)        → AI 证据验证(扫描后)        → AI 研判与报告(扫描后)

图 1:规则引擎负责找得到,三层 AI 负责看得准。AI 不可用时自动降级为纯规则扫描。

规则库是“端点路径 × 命中签名”的清单,新增一条只需加一行记录。命中判定用内容签名,不用状态码 - - 这是为了规避 Java 应用统一 404 页带来的假阳性。

AI 部分分三层,但每层都守四条约束:解耦(AI 层不 import 扫描器)、降级(LLM 失败时扫描照跑)、可审计(记录模型、置信度、耗时)、脱敏(不向 LLM 发口令明文)。降级是工程上的容错,不代表 AI 可有可无;AI 不可用时扫描照跑,但降级结果只能算候选集,不能当结论。

给 AI 提议权之后,真正起作用的是方法 + 副作用的约束,路径白名单只是其中一层:只用GET/HEAD、禁止 query string、只取状态码与声明长度、不提交任何凭据、23 个危险动词黑名单。一次自适应运行里,放行 117 条、拒绝 11 条,每条都留了理由。

四、AI 部分的三个版本

4.1 V1:只喂结论

最初的做法很直接:把命中记录(url、status、框架、描述)发给 LLM,让它判真伪、定风险。

跑 mock 靶标时效果很好。第一次跑真实数据就出了问题:34 条命中,AI 判了 33 条真阳性 + 1 条假阳性。人工逐条抓真实响应复核,发现其中几条是误报:

  • 某站点的/api/jsonws返回{\"msg\":\"…认证失败…\",\"code\":401},AI 判真阳性,还列为高危;
  • 某站点的/druid/login.html302 跳到 Nextcloud 登录页,AI 判真阳性;
  • 某站点的 Harbor:8080/api/systeminfo308 跳到 8443,和 8443 的真实发现重复,AI 没识别。

模型判断力没问题,问题出在喂进去的东西:模型看到的只有“扫描器说这是 Liferay JSONWS 未授权”,它从没见过那个 401。扫描器判错了,它自然跟着错。

4.2 V2:喂真实响应

于是加了验证层:先回抓真实响应构建证据包,再连同证据交给模型。

证据包包含 9 项:状态码、Content-Type、长度、正文片段(脱敏)、重定向链、认证失败特征、catch-all 比对、双视角对照、有界下一跳追问。同一批 34 条,改造后自动排除 3 条误报,和人工逐条复核的结论完全一致。

其中“双视角对照”是做的过程中发现的细节:扫描器为绕开 CDN 会直连解析出的源站 IP,可能报出“公网经 CDN 实际打不到”的端点。验证层同时用两种视角各取一次,不一致就降级为“仅源站可达”。

4.3 V3:给 AI 提议权,但执行权留在代码里

到 V2,AI 已经判得比较准,但角色还是事后复核。接着的问题是:规则库没想到的端点,谁来发现?

做法是让 AI 提议,但执行权留在代码里。所谓“提议”,是让模型基于当前证据输出一组“建议继续探测的路径 + 理由”;模型不持有 HTTP 客户端,也不执行请求,只产出候选列表,由代码逐条查白名单、决定放行还是拒绝。

扫描到某站点 → 发现命中 → AI 提议“再探这几个端点”(附理由)                        ↓                  代码查白名单:放行 / 拒绝(逐条留痕)                        ↓                  只执行放行的 → 结果回填 → AI 决定“还要再探吗” → 收敛

同一批 34 条,V3 自动排除 6 条误报,比 V2 多 3 条;还发现了规则库外的端点 - - 它自己提出要探 Prometheus的/api/v1/status/tsdb、/api/v1/metadata,这些手工白名单里一个都没有。

图 2:同一批 34 条命中,误报排除从 0 到 3 再到 6。V3 的关键,是让 AI 只提议、执行权留在代码里。

五、踩过的坑

5.1 AI 侧

推理模型“想太多”。报告里塞满思考过程,正文为空。原因是max\_tokens约束的是content + reasoning\_content之和;预算不足时,模型先把额度花在推理上,正文就没了。改法是给足预算(6000/8000),并且 content 为空一律判失败,绝不拿reasoning\_content冒充答案。

并发一高就被限流。并发 8 路触发网关限流,大量超时。后来做模型分工:逐条研判用轻量模型,报告用强模型;并发降到 3~4。

审计字段和实际不符。审计里写的是强模型,实际调用的是轻量模型。安全工具的审计准确性不能含糊,改成记录实际调用的模型。

5.2 工程侧

这几个都是被真实目标打出来的,没有一个和模型有关。

重试导致请求翻倍。最初“有响应但未命中”也重试,后来改成只在无响应时重试,请求量减半。

端口探测被限速拖慢。限速误约束了 TCP 探测;改成端口探测不受--rate-limit约束,限速只压 HTTP。

catch-all 站点误报。任意路径都返回首页,内容签名会被首页命中。加了四层防护:前缀堆叠去重、JSON 端点校验、self\_path校验、catch-all 守卫(随机路径探一次,与首页同正文就判否)。

302 型兜底。随机路径跳/login,Druid 登录页被误命中。改法是签名加组件独有端点,并识别 302 型兜底。

认证失败页回显路径。错误页把/jsonws回显进正文,命中 Liferay 规则。新增认证失败特征判定,正文含 401/403/认证失败/unauthorized 一律判否。

http/https 重复上报。80 端口 301 跳 443,同一发现报两次。加了跨站点 http/https 去重,42 → 34 条。

还有一个性能优化值得说:猜测的兜底前缀(/app/web/manage/admin)先用 3 个探针判断是否存在,不存在就整组跳过。每站点探测数从 372 降到 96,3.9 倍。原来 78% 的探测都花在猜前缀上。

图 3:catch-all、302 兜底、认证失败页回显,都在这里被挡掉。

六、实测结果

6.1 内网第一轮(30 个域名)

命中 16 条,去重后 10 个“站点 + 端点”;误报治理 103 → 22 → 16;逐条抓真实响应复核,未发现高危,真实暴露均为低危,主要是 Actuator 信息暴露(3 个站点)和 Nacos 命名空间元数据(1 个站点);xxl-job 控制台需登录,不算漏洞。

6.2 公网域名(725 个可达域名)

2026-10-14 15:05 → 10-15 19:59,29 小时,限速 10 req/s,全流程退出码 0。

图 4:725 个域名、1927 个站点,最后人工确认 27 条,真实率 82%。

人工复核结论:27 真、4 误报、1 重复、1 已修复。

图 5:本地 mock 靶标(16 条命中)的报告首页,仅作界面示意。

这轮跑完,比 27 条命中更值得记的是:33 条里有 6 条需要人工修正。这直接促成了后面的证据验证层。

七、开源地址与适用场景

项目已开源:https://github.com/Aerfa21/shadowscan(Apache-2.0)

仓库只保留最小核心:shadowscan.py、ai\_layer.py、验证层与探测策略、批量编排、自检工具,以及 README、运行指引、AI 层说明。

适合谁用:

  • 做资产排查、影子资产治理的安全团队;
  • 需要在上线前检查 Actuator、Swagger、Druid、.git等端点的研发 / DevSecOps;
  • 想研究“LLM 如何参与安全判定”的同行。

不适合谁用:

  • 想找 SQLi/XSS/命令注入/组件 CVE 的 - - 这个工具不做;
  • 想拿它直接打非授权资产的 - - 命令必须带--authorized,

且只应扫描已获书面授权的资产。

快速开始:

git clone https://github.com/Aerfa21/shadowscan.gitcd shadowscancp env.example.sh env.sh   # 填 LLM 端点与 key;不启用 AI 可跳过python3 shadowscan.py --targets assets.txt --production --authorized -o out

--production等价于--ai --adaptive。AI 不可用时会自动降级为纯规则扫描,不阻塞流程。

八、最后

这个工具最初只是想补上“端点漏扫扫不到”这个盲区。做的过程中发现,扫得到只是第一步,真正难的还有判得准;判得准的关键,是让 AI 看到真实响应,而不是只看扫描器的结论。

另一个体会是:给 AI 自由度的地方,得同时给它边界。自适应扩探能发现规则库外的端点,靠的是让 AI 提议;但真正能上生产,靠的是白名单、只读约束和审计留痕。

ShadowScan:让AI参与判定的影子端点扫描器" 网络安全文章

ShadowScan:让AI参与判定的影子端点扫描器"

ShadowScan是一款专注影子端点扫描的开源工具,针对Druid、Swagger、Actuator等常规漏扫盲区,采用规则库加三层AI验证架构,通过内容签名而非状态码判定命中。AI参与历经三版迭代,从仅喂结论到提供真实响应证据包,再到赋予AI提议权但执行权保留在代码中,有效降低误报。实测725个域名中人工确认27条真实命中,真实率82%。工具强调AI降级容错、审计留痕与授权扫描约束,适合资产排查与DevSecOps场景。
从三季度报告看“AI+安全”业务:“AI+安全”订单尚未从\"结构性亮点\"变成\"规模收入\"" 网络安全文章

从三季度报告看“AI+安全”业务:“AI+安全”订单尚未从\"结构性亮点\"变成\"规模收入\""

2026年三季度网安上市公司AI安全业务分化明显,订单集中在5000万至1亿元量级,占营收比普遍低于5%,尚未形成规模收入。奇安信、深信服、安恒信息等头部厂商路径各异,多数企业仍处产品先行收入后置阶段。建议关注具备AI基础设施或场景入口的公司,AI安全合规需求或成下一轮订单来源。
评论:0   参与:  0