如何使用AI辅助构建最合适渗透的爬虫系统?"

admin 2026-10-22 14:24:51 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

如何使用AI辅助构建最合适渗透的爬虫系统?

原创

Yak
Yak

Yak Project

2026年10月16日 17:06
四川

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

一、背景

即使 AI 技术持续演进,经典的漏洞挖掘与渗透测试方法仍然有效。实际工作通常仍围绕 Recon(信息收集)、分析规划和验证测试展开。其中,信息收集阶段能够覆盖的资产与接口范围,会直接影响后续分析和验证的完整性。

AI 可以用于增强传统工作流中的具体环节。本文以渗透测试场景中的 Web 爬虫为切入点,讨论如何利用 AI 分析页面、JavaScript 与构建产物,从已有材料中恢复更多接口、路由及关联资产。

二、爬虫基础演进

为了说明 AI 适合介入的位置,下面按照爬虫的主要观测对象和执行方式,对其能力演进进行划分。

YAK

2.1 爬虫1.0:以 HTTP 和 HTML 为中心

爬虫 1.0 主要面向传统的多页面 Web 应用。在这类应用中,服务端返回的 HTML 通常已经包含主要页面结构和导航信息。爬虫可以从 ` 中提取页面链接,从

` 中识别表单提交地址,再按照设定的作用域和深度递归访问。

这一阶段的 JavaScript 多用于表单校验、局部交互或页面效果,通常不会决定主要页面和接口的发现过程。因此,仅使用 HTTP 客户端和 HTML 链接提取器,就可以完成基础的网站路径遍历。

一个最小可复现的实现

下面的 webtree 函数使用 GNU Wget 实现了一个基础爬虫。它将访问范围限制在起始域名内,按照指定深度递归跟随页面链接,并排除 JavaScript、样式表、图片、字体、压缩包等非 HTML 资源。随后,脚本从 Wget 的访问记录中提取 URL,去重后按照路径层级输出网站树。

该示例适用于 macOS 环境或者常见 Linux 发行版。

Bash

 1  webtree() { 2    local start_url=\"$1\" 3    local depth=\"${2:-3}\" 4    local host=\"${start_url#*://}\" 5    host=\"${host%%/*}\" 6   7    if [[ -z \"$start_url\" ]]; then 8      echo \"用法: webtree <URL> [递归深度]\" 9      return 110    fi11  12    LC_ALL=C wget \\13      --recursive \\14      --level=\"$depth\" \\15      --delete-after \\16      --no-parent \\17      --domains=\"$host\" \\18      --follow-tags=a,area,frame,iframe \\19      --ignore-case \\20      --reject='css,js,mjs,map,jpg,jpeg,png,gif,webp,svg,ico,bmp,avif,woff,woff2,ttf,eot,otf,mp3,wav,ogg,mp4,webm,avi,mov,pdf,zip,tar,gz,7z,rar' \\21      --wait=1 \\22      --timeout=15 \\23      --tries=1 \\24      \"$start_url\" 2>&1 |25    awk '/^--[0-9][0-9][0-9][0-9]-.*--  https?:\\/\\// {print $NF}' |26    sed -E 's/#.*$//; s#^https?://[^/]+##' |27    grep -v '^/robots\\.txt$' |28    sort -u |29    awk -F/ -v root=\"$host\" '30      BEGIN {31        print root32      }33      {34        prefix = \"\"35        level = 036  37        for (i = 2; i <= NF; i++) {38          if ($i == \"\")39            continue40  41          prefix = prefix \"/\" $i42          level++43  44          if (!seen[prefix]++)45            printf \"%*s%s\
\", level * 2, \"\", $i46        }47      }48    '49  }

执行以下命令,对目标进行一层递归:

Bash

1  webtree https://public-firing-range.appspot.com/ 1

示例输出如下:

Bash

 1  public-firing-range.appspot.com 2    address 3      index.html 4    angular 5      index.html 6    badscriptimport 7      index.html 8    clickjacking 9      index.html10    cors11      index.html12    dom13      index.html14    escape15      index.html16    flashinjection17      index.html18    insecurethirdpartyscripts19      index.html20    leakedcookie21      index.html22    mixedcontent23      index.html24    redirect25      index.html26    reflected27      index.html28    remoteinclude29      index.html30    reverseclickjacking31    stricttransportsecurity32      index.html33    tags34      index.html35    urldom36      index.html37    vulnerablelibraries38      index.html

对于服务端直接输出完整导航结构的传统 Web 应用,基于 HTTP 和 HTML 的递归遍历已经能够恢复主要页面路径。这种方法实现简单、资源开销较低,可以作为后续方案的基础能力。

它的能力边界也比较明确:不会执行 JavaScript,也无法观察运行时网络请求、客户端路由和动态加载的模块。当应用逐渐转向 React、Vue、Angular 等单页应用架构时,爬虫的观测对象需要从静态 HTML 进一步扩展到浏览器执行状态。

YAK

2.2 爬虫2.0: 以浏览器执行为中心

随着 React、Vue 和 Angular 等单页应用框架普及,服务端返回的 HTML 往往只包含应用入口和少量静态资源,例如:

XML

1  2  <script src=\"/assets/index-a82f3c.js\"></script>

此时,curl 获取到的通常是一份内容较少的初始 HTML、一个或多个带有内容哈希的 JavaScript Bundle,以及相关静态资源。页面结构、客户端路由和业务数据需要在 JavaScript 执行后,通过 Fetch、XHR 或 GraphQL 等请求进一步加载。

因此,爬虫 2.0 的观测对象从静态 URL 扩展到了浏览器中的应用状态:

Go

1  应用状态 = URL + DOM + Cookie/Storage + 已执行操作2  3  状态转换 = 点击 + 输入 + 提交 + 滚动 + 路由跳转

即使 URL 和初始 HTML 相同,不同的认证信息、浏览器存储和操作序列,也可能产生不同的 DOM、网络请求和页面数据。爬虫的任务由遍历 URL,进一步扩展为对应用状态及其转换关系的探索。

浏览器爬虫的观测面与实现

浏览器执行 JavaScript 后,可以从以下几个观测面补充静态 HTTP 爬虫的结果:

观测面 主要内容 对渗透测试的价值
渲染后 DOM 链接、按钮、表单、iframe、动态文本 发现运行后才出现的入口
路由状态 Hash、History API、前端路由变化 发现 SPA 内部页面
网络请求 XHR、Fetch、GraphQL、WebSocket 握手 获得真实接口、方法和参数
浏览器状态 Cookie、LocalStorage、SessionStorage 保持登录态和业务上下文

浏览器爬虫通常分为两个阶段。首先加载种子 URL,等待页面达到相对稳定状态,收集渲染后的链接、表单、事件元素和网络请求;随后执行点击、输入或提交等动作,观察 URL、DOM 和网络状态的变化,并对已经访问的状态进行规范化和去重。

在现有工具中,ProjectDiscovery Katana 同时提供 Standard 和 Headless 两种模式。Headless 模式能够在浏览器环境中执行 JavaScript,并结合原始响应和渲染后的页面发现端点;启用 XHR 提取后,还可以记录页面运行期间产生的异步请求。Yaklang 的 CrawlerX 则基于 Chromium 浏览器执行页面,通过事件探索和请求拦截收集运行时流量。两者都能处理 SPA,但在动作生成、请求记录和结果组织方式上有所不同。

浏览器爬虫的能力边界

浏览器执行扩大了爬虫的运行时观测面,但发现结果仍然取决于页面是否实际加载了相关资源,以及自动化流程是否触发了对应状态。以下几类资产仍可能被遗漏:

  1. 1.非标准位置中的资源描述:路由和接口可能出现在 routes.json、Runtime Config、Asset Manifest、Source Map 或其他构建文件中。浏览器即使下载了这些文件,也不一定会继续解析其中包含的地址。

  2. 2.未执行或难以执行的 JavaScript:部分接口只存在于尚未加载的 Chunk、未点击按钮、异常分支、历史代码或混淆后的表达式中。由于相关代码没有实际运行,网络监听无法观察到对应请求。

  3. 3.需要专门解析的接口与协议:Service Worker、GraphQL、SSE、Socket.IO、WebSocket,以及泄露的 OpenAPI YAML,具有不同的描述形式和交互方式。仅依赖 DOM 遍历或通用网络捕获,通常不足以还原其完整接口关系。

  4. 4.【最难】依赖外部状态的业务流程:登录、二次核身、扫码确认、移动端支付和跨设备授权等流程需要浏览器之外的状态参与。自动点击和表单填写无法独立完成这类状态转换。

工程实现中通常会结合静态正则、浏览器网络事件或 MITM 代理补充请求记录。这些方法能够观察已经发生的流量,但对未触发代码和非运行时材料的解释能力仍然有限。

这一限制构成了爬虫 3.0 的切入点:在 HTTP 采集和浏览器执行之外,引入一个受限的语义分析层,对已经获得的 JavaScript、配置文件和构建材料继续推导尚未进入请求队列的候选资产。

三、爬虫3.0:AI 驱动的攻击面发现

浏览器爬虫扩展了运行时观测能力,但其发现范围仍然依赖页面实际执行的代码和已经触发的交互。某项资源即使被浏览器加载,也不代表爬虫会继续理解其中描述的接口和关联资产。

例如,浏览器爬虫可能发现 runtime-config.json、Asset Manifest 或动态 JavaScript Chunk,却不会自动将其中的路由、服务目录和实时通信地址继续加入请求队列。此时,限制来自对材料语义的理解,而不仅是资源获取能力。

爬虫 3.0 将 AI 引入分析与调度层,使系统能够围绕现有证据回答三个问题:

  1. 1.当前材料中包含哪些可以确认的技术线索?

  2. 2.哪些高价值线索尚未被展开或验证?

  3. 3.下一步应该访问哪些资源,以获得新的接口和资产信息?

AI 在这里承担的是受约束的语义分析任务。它可以分析 Runtime Config、Asset Manifest、Source Map、OpenAPI 文档和复杂 JavaScript,生成带有来源依据的候选 URL,再由普通爬虫完成范围校验和实际请求。

YAK

3.1 基础 MVP:从配置文件生成候选 URL

先从一个规模较小、结构明确的材料开始。爬虫访问以下地址:

Bash

1  https://coldchain.redhaze.top/assets/coldchain/runtime-config.json

访问获得的 JSON 内容如下:

JSON

 1  { 2    \"api_base\": \"/api/coldchain\", 3    \"asset_manifest\": \"/assets/coldchain/asset-manifest.json\", 4    \"business_unit\": \"hub\", 5    \"environment\": \"production\", 6    \"integration_spec\": \"/files/integration/coldchain-partner-api.yaml\", 7    \"interfaces\": { 8      \"events\": \"/events/v1/shipments/stream\", 9      \"graphql\": \"/gateway/graphql\",10      \"legacy\": \"/api/legacy/v1/regions?callback=ColdChain.regions\",11      \"socket\": \"/realtime/socket.io/?EIO=4&transport=polling\"12    },13    \"release\": \"v0.6.12+6953643\",14    \"route_catalog\": \"/assets/coldchain/routes.json\",15    \"service_catalog\": \"/api/catalog/v2/services\",16    \"service_worker\": \"/service-worker.js\"17  }

仅围绕 HTML 标签和 JavaScript 字面量工作的爬虫,通常不会把 JSON 中的任意字符串都视为可访问资源。这样可以减少误报,但也可能遗漏 asset_manifest、route_catalog、graphql 和 socket 等具有明确技术语义的字段。

浏览器执行同样不能保证这些资源全部被访问。页面可能读取配置文件,但只使用当前业务状态需要的部分字段。其余地址虽然已经存在于响应中,却不会出现在本轮网络请求里。

为了验证 AI 是否能够补充这一过程,可以将当前 URL、响应内容和输出约束一并提交给模型:

SQL

 1  prompt = `作为一个爬虫调度器 2   3  我现在访问 https://coldchain.redhaze.top/assets/coldchain/runtime-config.json 4   5  得到的结果为: 6   7  { 8    \"api_base\": \"/api/coldchain\", 9    \"asset_manifest\": \"/assets/coldchain/asset-manifest.json\",10    \"business_unit\": \"hub\",11    \"environment\": \"production\",12    \"integration_spec\": \"/files/integration/coldchain-partner-api.yaml\",13    \"interfaces\": {14      \"events\": \"/events/v1/shipments/stream\",15      \"graphql\": \"/gateway/graphql\",16      \"legacy\": \"/api/legacy/v1/regions?callback=ColdChain.regions\",17      \"socket\": \"/realtime/socket.io/?EIO=4&transport=polling\"18    },19    \"release\": \"v0.6.12+6953643\",20    \"route_catalog\": \"/assets/coldchain/routes.json\",21    \"service_catalog\": \"/api/catalog/v2/services\",22    \"service_worker\": \"/service-worker.js\"23  }24  25  接下来应该访问什么页面呢?输出完整带协议和域名的URL`26  27  result, err = ai.FunctionCall(prompt, {28      \"urls\": \"为JSON列表,下一步可以访问的URL列表,带上域名\"29  })30  die(err)31  dump(result)

本次运行返回了 10 个候选 URL。为便于阅读,将原始 dump 结果等价整理为 JSON:

Go

 1  { 2    \"urls\": [ 3      \"https://coldchain.redhaze.top/api/coldchain\", 4      \"https://coldchain.redhaze.top/assets/coldchain/asset-manifest.json\", 5      \"https://coldchain.redhaze.top/files/integration/coldchain-partner-api.yaml\", 6      \"https://coldchain.redhaze.top/events/v1/shipments/stream\", 7      \"https://coldchain.redhaze.top/gateway/graphql\", 8      \"https://coldchain.redhaze.top/api/legacy/v1/regions?callback=ColdChain.regions\", 9      \"https://coldchain.redhaze.top/realtime/socket.io/?EIO=4&transport=polling\",10      \"https://coldchain.redhaze.top/assets/coldchain/routes.json\",11      \"https://coldchain.redhaze.top/api/catalog/v2/services\",12      \"https://coldchain.redhaze.top/service-worker.js\"13    ]14  }

这次实验说明,模型能够结合字段语义和当前页面地址,将相对路径恢复为完整 URL。输出仍然只是候选结果:这些地址是否真实存在、允许什么请求方法,以及是否属于当前作用域,仍需由确定性校验器和普通爬虫进一步确认。

对于体积较小、结构清晰的材料,可以在上下文预算允许时直接进行整体分析。是否适合整体提交,应根据模型上下文、分词后的长度、调用成本和数据边界判断。

当然我们这个最小实验实际上是理想情况,实际工作中难度要更高,可以跟随我们后面的解释来探索:

YAK

3.2 工程问题:大体积 JavaScript 如何分析

实际站点中的 JavaScript Bundle 可能达到数 MiB,直接提交完整文件会带来较高的上下文成本,而且大量内容与接口发现无关。

Bash

1  https://coldchain-provider.redhaze.top/static/js/coldchain/runtime/capacity-planning.6e31d9a7.bundle.js

下面使用一个实际大小为 5,242,880 字节,即 5 MiB 的 JavaScript Bundle 进行分析:

我们初步发现,其中有一些内容旧的路由泄漏,例如:

/api/planning/v1/capacity/export等;

该文件的大部分内容由数据定义、构建运行时代码和低价值填充组成。与接口发现直接相关的代码集中在较小的局部区域,其中包含如下调用关系:

JavaScript

1  const __ccRead__ = (order) =>2    atob(order.map((index) => __ccPieces__[index]).join(\"\"));3  4  const __ccRoute__ = () =>5    __ccRead__([5, 8, 11, 14, 17, 20]);6  7  const __ccEndpoint__ = () =>8    __ccRead__([3, 6, 9, 12, 15, 18, 21, 23, 25, 27, 29, 31]);

页面随后使用这些函数构造路由和接口:

Bash

1  '打开分配矩阵'2  3  const response = await fetch(__ccEndpoint__(), {4    // ...5  });

普通正则可以识别 href 和 fetch,但无法直接获得最终 URL,因为参数值需要经过数组索引、字符串拼接和 Base64 解码才能恢复。

处理这类大文件通常有两种策略:

  1. 1.按固定字节数切片,分别提交给模型;

  2. 2.先搜索高价值锚点,再进行局部代码分析,必要时在隔离沙箱中求值。

固定切片实现简单,但会产生两个问题。首先,大量分析预算会消耗在与接口发现无关的代码上;其次,函数定义、变量数据和调用位置可能分布在不同切片中,使模型无法恢复完整的数据依赖关系。

更适合工程实现的方式是“搜索—局部读取—受限求值”。系统先通过确定性规则定位 fetch、href、WebSocket 等调用点,再沿变量和函数定义读取有限上下文。只有静态推导不足时,才在无网络、无文件权限的 JavaScript 沙箱中执行最小代码切片。

这种方法不依赖页面是否实际触发相关功能。尚未点击的按钮、延迟加载的模块和不可达分支仍然可以作为静态材料被分析。浏览器执行与静态分析由此形成两个互补的观测面。

YAK

3.3 技术方案:区分直接地址与待求值表达式

JavaScript 中的请求线索可以先按照参数是否已经确定,划分为两类。:

第一类:参数中包含完整路径

Plain Text

1  fetch(\"/api/v1/orders\")2  axios.post(\"/api/v1/bids\", data)3  xhr.open(\"GET\", \"/api/v1/providers\")

这类代码已经提供了明确路径,有时还能同时获得 HTTP 方法和请求体变量。确定性解析器可以结合当前页面 URL 解析相对路径,不需要调用 AI。

AI 只应处理规则无法完成的部分,以减少调用次数和不确定输出。

第二类:参数需要进一步求值

Plain Text

1  fetch(apiBase + route)2  fetch(buildURL(t, e))3  xhr.open(method, endpoint)4  axios(requestConfig)5  new WebSocket(resolveGateway())

这类代码只能确认存在请求行为,无法直接得到最终地址。分析过程需要继续查找:

•apiBase、route 和 endpoint 的定义;

•buildURL、resolveGateway 等函数的实现;

•配置对象的赋值和覆盖关系;

•编码、解码或字符串表的构造过程;

•当前页面 URL 对相对路径解析的影响。

AI Agent 可以利用局部搜索工具建立调用点与定义之间的关系,再决定是否需要使用 JavaScript 沙箱求值。

寻找 AI 分析的入口锚点

入口锚点的作用不是直接生成 URL,而是判断某份材料是否值得进入 AI 分析流程,并为 Agent 提供初始位置。

网络请求与浏览器能力

Markdown

1  \\bfetch\\s*\\(2  \\.\\s*open\\s*\\(3  \\b(?:axios|ky|got)\\s*(?:\\.\\s*(?:get|post|put|patch|delete|head|options|request))?\\s*\\(4  \\bnew\\s+(?:XMLHttpRequest|Request|WebSocket|EventSource|Worker|SharedWorker)\\b5  \\b(?:navigator\\s*\\.\\s*)?sendBeacon\\s*\\(6  \\bserviceWorker\\s*\\.\\s*register\\s*\\(7  \\bimportScripts\\s*\\(8  \\b(?:client|http|requester|apiClient)\\s*\\.\\s*(?:request|get|post|put|patch|delete)\\s*\\(

这些模式用于定位 HTTP 请求、实时通信、Worker 和 Service Worker 等能力入口。

配置、路由与请求描述

Plain Text

1  \\b(?:baseURL|baseUrl|apiBase|apiHost|endpoint|graphqlEndpoint|wsUrl|socketUrl)\\s*[:=]2  \\b(?:method|url|uri|headers|params|query|body|data)\\s*:3  \\b(?:createBrowserRouter|createHashRouter|useRoutes|createRouter|createWebHistory)\\s*\\(4  \\b(?:path|children|loader|action|component)\\s*:

这组模式适用于 JavaScript、JSON 和 YAML,用于定位接口基址、请求对象和前端路由配置。

构建系统与编码行为

Plain Text

1  \\b(?:webpackChunk[A-Za-z0-9_$]*|__webpack_require__|__vite__mapDeps)\\b2  \\b(?:import|require)\\s*\\(3  \\bsourceMappingURL\\s*=4  \\b(?:asset-manifest\\.json|manifest\\.json|routes\\.json)\\b5  \\b(?:atob|decodeURIComponent|unescape|String\\.fromCharCode|charCodeAt|TextDecoder)\\s*\\(6  \\b(?:eval|Function)\\s*\\(7  (?:\\\\x[0-9A-Fa-f]{2}){8,}8  [A-Za-z0-9+/]{100,}={0,2}

这组模式用于识别动态 Chunk、Source Map、构建清单、字符串解码和可能的代码生成行为。命中这些模式只能说明材料具有进一步分析价值,不能直接证明其中存在有效接口。

完成锚点定位后,系统不需要把完整文件提交给模型。更合理的做法是生成一个包含材料标识、命中位置、有限上下文和作用域策略的分析任务,再交给最小权限 AI Agent 处理。

这就进入下一步的工程落地问题:如何限制 Agent 的工具、权限和迭代次数,同时让其稳定输出能够被爬虫验证的 URL。

四、技术实现与落地:为爬虫增加受限 AI 分析闭环

前面的实验说明,AI 能够从配置文件、构建产物和复杂 JavaScript 中恢复普通爬虫遗漏的 URL。工程实现中没有必要把所有响应都交给模型分析,更合适的方式是在普通爬虫之上增加一个按需触发、权限受限的 AI 分析层。

整个系统可以拆分为常规采集、AI 分析和候选回灌三个阶段:

在这套架构中,普通爬虫始终负责采集和请求执行,AI Agent 只处理确定性规则无法还原的局部材料。Agent 输出的 URL 还需要经过范围校验、去重和证据检查,才能重新进入爬虫队列。

YAK

4.1 核心代码如何工作

现从每一次 HTTP 响应开始。HTML、外部 JavaScript、内联脚本、配置文件和 Source Map 不会被拼成一份来源不明的大文本,而是分别保存正文、来源 URL 与 Content-Type。普通提取器先处理其中明确存在的链接和路径;随后,本地触发器对代码做一次轻量词法规整,屏蔽注释、正则字面量等噪声,再检查动态 fetch、动态 import、字符串拼接、编码片段、路由配置与 Chunk 运行时等信号。

这里的判断原则是:AI 只处理“需要推理”的部分。比如 fetch('/api/orders') 已经可以直接提取,不值得调用模型;而 fetch(base + decode(table[i])) 同时包含请求动作、变量组合和编码行为,才会达到触发阈值。达到阈值后,代码也不会把整份 Bundle 发送给模型,而是围绕命中位置截取有限的证据窗口,并用共享计数器限制整次爬取中的调用轮数、单项资产的窗口数量、证据字节数和单次超时。

模型返回的仍然只是候选 URL。候选需要重新解析为标准 URL,经过域名范围、路径规则和去重检查,最后回到普通爬虫的调度队列。删去日志和错误处理后,关键路径可以压缩为下面这段:

Go

 1  assessment := assessAIJSTrigger(code, sourceURL, contentType) 2  if assessment.score < cfg.TriggerThreshold { 3      return nil 4  } 5   6  windows := extractAdaptiveURLLikeCandidatesBounded( 7      code, cfg.ContextBytes, 8      cfg.MaxCandidateWindows, cfg.MaxCandidateBytes, 9  )10  11  invokeAIJSWithBudget(ctx, cfg, strings.Join(windows, \"\
\"), func(path string) {12      https, raw, err := NewHTTPRequest(baseHTTPS, requestRaw, responseRaw, path)13      if err != nil {14          return15      }16      candidate, err := lowhttp.ExtractURLFromHTTPRequestRaw(raw, https)17      if err == nil && config.CheckShouldBeHandledURL(candidate) {18          submit(https, raw)19      }20  })

这段代码说明了整个原理:本地规则决定是否触发,证据裁剪控制模型输入,调用预算限制迭代,原有调度器控制最终请求。AI 扩大的是候选发现面,并没有取得绕过作用域或任意发起请求的权限。对应实现分别位于 common/crawler/js_ai_trigger.go、common/crawler/js_ai.go 和 common/crawler/core.go。(详细内容文章结尾参考相关实现与复现材料)

YAK

4.2 核心实验

实验使用 ColdChain 供应商系统的运力页面作为唯一入口,并把访问范围严格限制在同一个域名:

Bash

1  https://coldchain-provider.redhaze.top/capacity

对比对象为 Katana 普通模式、Katana Headless,以及上述不启动浏览器的 AI 静态分析模式。每种模式独立运行三次,表中使用中位数。为了让“URL 数量”具有可比性,结果统一按 域名 + 路径 + 查询参数 归一化,忽略 HTTP/HTTPS 差异并去重;再依据目标系统源码和已注册路由逐条核验,建立包含 25 个 URL 的闭集真值。

这里需要特别说明:目标系统中有一部分 URL 和代码片段本来就是人为布置的分析线索。候选没有进入这 25 项闭集真值,并不等于候选错误,因此本文只统计输出候选总量、命中真值数量、漏报、真值覆盖率与耗时,不对真值集合之外的线索作负面分类。覆盖率的计算方式为 命中真值 URL ÷ 25。

模式 输出候选 URL 命中真值 URL 漏报 真值覆盖率 中位耗时
Katana 普通模式 3 3 22 12.0% 11.06 s
Katana Headless 18 16 9 64.0% 32.06 s
受限 AI 静态分析 48 21 4 84.0% 24.42 s

结果首先说明,普通模式虽然最快,但它只命中 3 个真值 URL,25 个真值中漏掉了 22 个。对于构建资产较复杂的 SPA,单靠页面链接和静态字面量并不足以展开主要分析面。

Headless 将真值命中提高到 16 个,覆盖率达到 64%。浏览器执行 JavaScript 后,确实触发了普通模式无法观察到的路由和接口;代价是本轮耗时增加到 32.06 秒。

AI 静态分析最终命中 21 个真值 URL,比 Headless 多 5 个,即真值命中数量增加 31.3%;覆盖率从 64% 提高到 84%,增加 20 个百分点。同时,它不需要启动浏览器,中位耗时为 24.42 秒,比 Headless 少 7.64 秒,缩短约 23.8%。多出来的真值主要来自当前页面没有实际执行的构建分支,例如动态 Chunk、Source Map、Worker 及其后续接口,限篇幅和时间关系,我们就不再赘述了,其实我们还可以继续改在AI爬虫,允许更长时间的运行,机遇启动浏览器,可以获得更高的覆盖率。

AI 模式一共输出了 48 个候选,其中 21 个属于当前闭集真值,其余候选没有被直接判错。原因在于这套系统同时放置了历史接口、构建模板和其他可继续分析的线索,它们不一定是可直接请求的业务路由,但仍可能扩大后续分析面。为了保持对比口径一致,这些额外候选只计入“输出候选 URL”,不参与覆盖率分子,也不作为负面指标。

五、结语:AI 增强爬虫仍有成本与边界

AI 可以提高爬虫对配置文件、构建产物和复杂 JavaScript 的分析能力,但这种能力并非没有成本,也不能覆盖应用的全部状态。

对于工程团队而言,模型 API 已经越来越接近网络流量费:单次调用的成本可能不高,但会随着分析材料、调用轮次和并发任务持续累积。在本文的实验范围内,当任务被限制为局部代码分析、配置解析和候选 URL 提取时,输入单价约为 1~2 元/百万 Token 的模型已经能够满足基本需求。

需要说明的是,这只是本文实验条件下的工程观察,并不代表统一的模型能力标准。实际成本还会受到输出长度、失败重试、上下文重复、缓存策略和服务商计费方式影响。因此,爬虫 3.0 的关键并不是“每份材料都交给 AI”,而是先通过确定性规则筛选,只把普通解析器无法稳定处理的局部材料送入模型。

YAK

5.1 边界一:人机验证与二次核身

验证码、扫码确认、短信验证、动态口令、设备确认和支付授权等机制,本身就要求真实用户或外部设备提供新的状态。AI 可以识别认证流程、定位相关请求并分析回调代码,但通常无法独立获得核验完成后的会话状态及其保护的资产。在这些场景中,AI 更适合承担以下工作:

  • 识别认证边界和状态转换条件;

  • 保存核验前后的请求关系;

  • 提示需要人工参与的操作;

  • 在授权人员完成核验后,继续复用浏览器会话。

因此,更准确的工程表述不是“让 AI 绕过二次核身”,而是由授权人员通过可见浏览器完成核验,再由爬虫通过 CDP 接管或复用已经授权的会话。类似的人机协作设计已经存在于现有工具中,例如 rad 提供了 -wait-login,允许用户先在浏览器中手动登录,再继续爬取。

YAK

5.2 边界二:强依赖运行时的前端加密

对于 JavaScript 实现的请求签名、参数加密和响应解密,AI 通常能够协助定位算法、参数顺序、密钥来源和函数调用关系,也可以尝试恢复能够独立执行的纯函数代码。

但是,理解代码并不等于具备发起请求的全部条件。算法可能依赖以下运行时信息:

  • 服务端临时下发的密钥或随机数;

  • Cookie、Token 和登录会话;

  • 浏览器指纹与设备状态;

  • WebAssembly 或原生扩展提供的能力;

  • 一次性挑战值及时间窗口。

验证这类接口仍然需要浏览器插桩、网络代理、运行时 Hook、密钥观测和请求重放等基础设施。AI 可以降低理解代码的成本,但无法替代这些执行条件。

在实现层面,go-rod 和 chromedp 都提供了基于 Chrome DevTools Protocol 的 Go 浏览器控制能力;Playwright 的网络接口则可以观测 XHR、Fetch、响应和 WebSocket。这些框架不是完整的爬虫系统,但可以作为运行时观测、人工接管和会话复用的底层组件。

YAK

5.3 三类爬虫不是替代关系

爬虫 1.0、2.0 和 3.0 对应三个不同的观测层次:

Bash

1  爬虫 1.0:通过 HTTP 与 HTML 遍历公开路径2  爬虫 2.0:通过浏览器观察 JavaScript 执行后的应用状态3  爬虫 3.0:通过 AI 分析已获得材料中的语义关系

本文讨论的三个阶段,对应三个不同的观测层次:

  • 爬虫 1.0:通过 HTTP、HTML 和确定性规则遍历服务器公开的路径。

  • 爬虫 2.0:通过浏览器执行 JavaScript,观察 DOM、路由、网络请求和会话状态。

  • 爬虫 3.0:通过 AI 分析已经取得的配置、代码和构建材料,恢复其中隐含的语义关系。

三种方式并不互相替代。HTTP 爬虫提供低成本的基础覆盖;浏览器爬虫补充运行时行为;AI 则负责处理确定性规则难以还原的配置和代码关系。

AI 输出的 URL 也不应直接被视为有效接口。候选结果仍需经过范围校验、规范化、去重、在线请求验证和证据记录,才能重新进入爬虫队列。在工程实现中,将 AI 约束为一个按需触发、权限有限、迭代有界且结果可验证的分析组件,通常比让 Agent 直接控制整个爬虫更容易获得稳定收益。

YAK

5.4 相关实现与复现材料

本文参考的材料如下:

包括多种现有爬虫和浏览器自动化方案:

•ProjectDiscovery Katana:同时提供普通 HTTP 与 Headless 模式,并区分 JavaScript 静态解析和运行时 XHR 提取。具体参数可参阅官方运行文档。

•rad:面向安全扫描的浏览器爬虫,支持人工登录、请求输出和代理联动。其公开仓库目前主要提供发行文件与使用文档,并未公开完整实现源码。

•Crawlergo:基于 Headless Chrome 的浏览器爬虫,关注 DOM 事件触发、表单填充、请求收集和去重。

•go-rod:基于 CDP 的 Go 浏览器驱动,可用于页面操作、请求劫持、事件等待和运行时观测。

•chromedp:另一套 Go CDP 客户端,可作为自研浏览器爬虫的控制基础。

•Playwright Network:可用于理解浏览器网络事件、XHR、Fetch、WebSocket 和请求拦截的实现方式。

•Yaklang common/crawler:传统页面抓取、JavaScript 分析和候选请求生成的实现。

•Yaklang CrawlerX:基于 go-rod 构建的浏览器爬虫实现。

•AI 自适应 JavaScript 分析 PR #4973:本文所述按需触发、预算限制和候选回灌机制的工程实现。截至 2026 年 8 月 31 日,该修改仍处于开放 PR 状态,尚不能表述为已经合入主分支。

•实验脚本、原始输出与结果汇总:用于复现普通爬虫、AI 增强爬虫、CrawlerX 与 rad 的对照过程。

•Yaklang Vulinbox 页面实现:公开可运行的本地案例源码。

•ColdChain 在线案例环境:用于观察 SPA、动态 Chunk、运行时接口和构建材料等场景。

END

  • Memfit:是万径安全旗下Yaklang团队研发的面向长程渗透测试、漏洞挖掘、应急响应等全链路攻防任务的生产级安全领域Agent系统
  • Yakit:是万径安全旗下Yaklang 团队开源的一款完全国产的交互式安全测试平台

YAK官方资源

Yakit官网下载地址:
https://yaklang.com/

Github地址:
https://github.com/yaklang/yakit

Yakit 视频教程:
https://space.bilibili.com/437503777

Memfit下载地址:
https://memfit.ai/

IRify下载地址:
https://ssa.to/

YTray下载地址:
https://yaklang.io/ytray/

    如何使用AI辅助构建最合适渗透的爬虫系统?" 网络安全文章

    如何使用AI辅助构建最合适渗透的爬虫系统?"

    本文探讨AI辅助构建渗透测试爬虫系统,将爬虫演进分为基于HTTP与HTML的1.0、基于浏览器执行的2.0及引入AI语义分析的3.0三个阶段。核心观点是AI可分析配置文件、JavaScript等材料,从中恢复接口、路由及关联资产,弥补传统爬虫对未执行代码和非运行时材料解释能力的不足,提升攻击面发现完整性。
    远程代码执行漏洞利用分析" 网络安全文章

    远程代码执行漏洞利用分析"

    本文分析JEECG4.0及之前版本的远程代码执行漏洞,攻击者可通过/api路径遍历绕过鉴权,结合fastjson1.2.31的JNDI注入实现RCE。文章详述了环境搭建、漏洞原理、利用流程及POC,并总结了alwaysUseFullPath绕过鉴权与fastjson漏洞的实战经验。
    数据泄漏情报精选周报2026.10.10-2026.10.16" 网络安全文章

    数据泄漏情报精选周报2026.10.10-2026.10.16"

    本周暗网数据泄露情报周报显示,共采集416条帖子,纳入313条泄露事件,涉及30余国政府、金融、能源、军工等领域。高体量样本包括PeopleDataLabs416M、1win96.5M用户等。具体事件涵盖e-topplus.kr2800万行、日本260万公民数据库、法国Axa800万条等。建议相关机构加强数据安全防护,关注暗网泄露动态。
    AI投入变成糊涂账?中新赛克AI治理网关,让每一次AI调用尽在掌控" 网络安全文章

    AI投入变成糊涂账?中新赛克AI治理网关,让每一次AI调用尽在掌控"

    中新赛克推出AI治理网关产品,针对企业AI规模化应用中的行为失控、成本失焦、数据失守、合规失效四大痛点,提供管人、管Agent、管风险、管钱四类治理能力,实现AI调用的可归属、可观测、可治理。产品支持统一接入、权限管控、敏感数据防护、Token成本核算等功能,宣称可降低30%-60%成本,并满足等保合规要求。
    评论:0   参与:  0