文章总结: 本文通过AI+Skill+BurpMCP协同实战案例,展示了从匿名入口到记录读取的完整移动端代码审计闭环。案例基于某校内业务系统移动端,通过AI辅助源码整理与调用链追踪,结合BurpMCP进行最小化验证,确认了匿名参数可建立有效会话并穿透权限校验,最终读取来访登记业务敏感数据。文档提出了分层阻断的修复建议,并强调协同工具在收敛线索与验证闭环中的价值。 综合评分: 82 文章分类: 代码审计,移动安全,漏洞分析,安全工具,应用安全
AI + Skill + Burp MCP 协同实战:从匿名入口到记录读取的一次移动端代码审计闭环
arar arar
只会看监控的实习生
2026年5月30日 08:00 广东
在小说阅读器读本章
去阅读
0x01 前言
过去一段时间,AI 在安全测试场景中的讨论很多,但真正落到实战时,问题往往不在于“AI能不能一键挖洞”,而在于它能不能稳定参与一次真实的审计闭环。对代码审计类项目来说,最耗时的通常不是最后几次验证请求,而是前期对系统结构的理解、关键入口的识别、调用链的收敛,以及把零散线索组织成可验证结论的过程。
这次案例来自 eduSRC 场景,目标对象是某校内业务系统移动端。我没有直接从黑盒接口测试开始,而是将 AI、Skill、Burp MCP 与浏览器自动化放进同一条受约束的工作流:先借助 AI 完成源码整理、入口识别和调用链追踪,再由 Skill 约束分析边界与验证范围,随后通过 Burp MCP 承接最小化差异验证,最后由浏览器自动化补齐页面态证据。验证结果显示,这条流程从匿名访问入口出发,一路追踪到初始化接口、权限校验逻辑与表单读数流程,最终确认了一条真实成立的未授权访问链路,并触达教育场景下的真实敏感业务数据读取风险。
本文案例基于合法授权场景开展,文中目标信息、标识符与关键参数均已做脱敏处理;动态验证严格遵循最小化原则,不涉及批量枚举、写入或破坏性操作。
从案例性质上看,这是一条典型的未授权访问与业务数据读取链路;在方法上,本次审计以代码审计为主、动态验证为辅,最终将问题收敛为“匿名入口 → 建立会话 → 页面放行 → 记录读取”的完整访问链,并确认该链路最终落到了校内来访登记业务数据中的敏感字段可读风险上。
0x02 审计思路设计:为什么这次采用 AI + Skill + MCP 的协同方式
这类移动端项目的认证、授权和数据读取逻辑,往往分散在页面配置、初始化 HTML、框架加载器和组件脚本中。如果直接黑盒测试,很容易在大量页面和接口里失焦;但如果先从代码审计入手,很多看似零散的线索就能被快速串成一条可验证路径。
为了避免 AI 在证据不足时过度推断,我将整条流程拆成了几个职责清晰的环节:AI 负责源码整理、入口识别、参数流转追踪与调用链收敛;Skill 负责约束分析边界,要求先有代码证据、再做最小化验证;Burp MCP 负责把代码中的疑点转化为单点、可对照的验证动作;浏览器自动化负责补齐页面可达性与用户可见性证据;而最终的边界控制、停止点判断和结论定性,仍由人工完成。
整个过程中,我始终坚持四条原则:代码证据优先,动态验证只做最小化,不扩大战果、不进行高风险写入操作,且只有当代码证据、接口证据与页面证据能够相互闭环时,才将其认定为真实问题。
0x03 源码整理:先把陌生项目还原成可分析的结构
项目拿到手后,第一步不是找 payload,而是先还原结构。整体看,这份内容更像一份已部署站点的静态资源导出。顶层主要分成 api 和 mobilemode 两部分,其中真正有价值的内容集中在 mobilemode/mobile。
继续拆分后,核心内容大致可以分为三类:page 目录主要用于定位页面入口和字段定义,dist/js 更适合继续追踪框架逻辑、组件行为与统一请求封装,view.html 则是页面初始化入口,用来确认 URL 参数如何进入运行上下文。
从审计角度看,这个结构最重要的特点在于,认证、权限与数据读取逻辑并不集中在某个后端文件里,而是分散在页面配置、入口 HTML、加载器脚本和表单组件之中。因此,我没有先围绕接口做黑盒验证,而是优先追入口、初始化与页面数据之间是否存在同一条调用链,这也是我首先关注 page1.js、view.html 和 loader.js 的原因。在这一步,我先借助 AI 完成源码整理,把项目结构还原成一张可分析的地图,再将关注点收敛到匿名认证链路,并快速锁定第一条高价值线索:一个带有匿名认证语义的移动端入口。
0x04 第一条关键线索:从匿名页面入口发现异常参数
第一条高价值线索出现在 page1.js。在页面配置中,可以直接看到某个入口地址携带了 mTokenFrom=anonymous 和 mToken 这组参数。这里的问题并不在于参数“看起来有些异常”,而在于它们明显带有认证语义:其中 mTokenFrom=anonymous 直接表明这是匿名来源,mToken 则更像是一段会参与后续身份判断的凭据,而这组参数又直接暴露在前端页面入口中,意味着它们不仅可见,而且可携带、可复用。
继续往下看
view.html,可以确认页面在初始化时会从 URL 中读取这些参数,并将其写入 window.\_\_meta\_\_。这说明问题并不只停留在页面跳转层,而是这些值会继续进入运行上下文。
再往下追 loader.js 可以看到,window.__meta__ 中的值会被继续拼入一条 meta 初始化请求,请求中包含 invoker、action=meta、appid、mTokenFrom、mToken、_ec_ismobile=true 以及 timeZoneOffset 等关键参数。也就是说,前端暴露出来的匿名参数并没有停留在页面跳转层,而是被正式带入了后端初始化流程。到这里,这条线索已经从“可疑参数”升级成了“可疑认证链”。
0x05 从代码线索到接口验证:Burp MCP 如何验证 meta 建立了有效会话
在这个阶段,验证目标非常明确:匿名参数是否真实参与了会话建立。
因此,这一步没有做大范围测试,而是只围绕同一条 meta 请求进行最小化差异验证:先去掉 mTokenFrom 和 mToken 发起一次请求,再在保持其余条件不变的前提下恢复这组匿名参数重新请求,以此对比它们是否真实参与了会话建立。
验证结果显示:不携带匿名参数时,无法建立有效会话。恢复匿名参数后,接口返回了有效 sessionkey 和相应身份上下文。
这说明前端暴露出来的匿名参数并不是无效残留,而是确实被后端接受,并参与了会话建立。
到这里,第一层闭环已经成立:匿名入口里的参数,最终可以在后端换回有效 sessionkey。
0x06 会话建立之后,权限是否真正被放行
能拿到 sessionkey,并不自动等于能进业务页面。沿着调用链继续往下看,可以定位到页面权限判断逻辑,对应会调用 checkPagePermission 一类接口来判断当前会话是否具备访问资格。
到这一步,验证目标也非常单一:前面建立的会话,究竟是不是一个真实可用的业务访问会话。继续通过 Burp MCP 做最小化重放后可以看到,携带前面返回的 sessionkey 时,权限接口会返回可访问结果;换句话说,这个会话并不是空壳,也不只是初始化上下文,而是能够继续穿透页面权限层。
这一步非常关键,因为到这里,问题已经不再是“匿名态拿到了一个会话”,而是“匿名态拿到的会话还能通过业务页面权限校验”。
0x07 从页面可达走向数据可读:继续追踪到真实读数逻辑
在确认页面可进之后,下一步就要判断这个页面到底承载了什么数据。对应的页面配置文件是 page501.js。
在该页面配置中,可以直接看到来访人姓名、证件号、联系电话、来访时间、来访事由等真实业务字段。
这说明目标页面不是普通展示页,而是一张承载真实校内来访登记业务数据的页面。
page501.js 中定义了来访登记表单及姓名、证件号、联系电话等字段
继续顺着表单逻辑往下追,关键代码出现在 Form\_wev8.js。这里的核心点是:表单初始化时会先读取页面参数中的 billid;只要 billid存在,框架就会进入“查看已有记录”模式,并在fillFormData逻辑里自动拼出一条getData请求:
D.getActionUrl(i.type,{action:"getData",key:F.table.key,billid:F.billid,modelid:F.relate.modeid,mec\_id:this.id},i.pageid)
这条代码非常关键,因为它说明getData不是测试阶段“猜出来的接口”,而是页面在加载已有记录时会自动调用的标准读数动作。
需要注意的是,请求参数层面表现为 modelid ,而该取值在前端配置中来源于 modeid 。也就是说,页面内部以 modeid 字段保存模型标识,再由表单读数逻辑将其拼接为 modelid 参数带入后端请求。
0x08 最小化验证:匿名链路不只开页面,还能读到真实记录
既然代码里已经明确存在 getData 读数逻辑,下一步验证就只剩一个问题:匿名链路建立的会话,是否真的能够读取业务记录。到这一步,我没有继续扩大验证范围,而是只围绕单条记录确认“业务数据是否真实可读”这一件事。整个过程仍然坚持最小化原则,只针对单条记录做读取验证,不做批量枚举。结合代码与请求对照可以确认,这条读数请求以 action=getData 指定读取动作,通过 key 与 billid 标识目标记录,以 modelid 指定所属模型,其中该值来源于前端配置中的 modeid,同时再结合 mec_id 与前面匿名参数换回的有效 sessionkey 完成已有记录的读取。
最小化验证结果表明,这条请求能够返回对应记录内容,而返回字段又与页面中定义的“姓名、证件号、联系电话”等字段一一对应。也就是说,问题已经从“页面可达”进一步落到了“数据可读”。
通过 Burp MCP 对 getData 接口执行最小化验证,并确认响应中返回目标来访登记记录字段
很多场景里,“能打开页面”和“能读取真实数据”并不是同一个问题,而这次案例中,这两点都被代码与验证结果共同确认了。
0x09 页面态补证:为什么还需要浏览器自动化
做到这里,从接口层面其实已经足够认定问题成立了。但为了让整条证据链更完整,还需要补上一层页面态证据:这条问题到底是不是只存在于抓包视角里,还是已经真实落到了前端业务界面。这也是浏览器自动化在这次流程中的意义。它不是为了炫技,而是为了补齐“用户可见”这一层证据。
实际验证时,我沿着前面代码中暴露的匿名入口进入页面,等待初始化完成后,确认目标页面是否能够被打开,以及表单字段是否真实渲染。验证结果显示,来访登记页面能够正常进入,姓名、证件号、联系电话等字段也处于真实可见状态。
到这里,这条问题已经同时具备代码证据、接口证据与页面证据,整条链路也不再只是抓包层面的异常,而是已经能够在真实前端页面中被观察和验证。
0x0A 漏洞成因分析:问题为什么会形成完整链路
回头看这条链,问题并不是单点失误,而是多个环节叠加形成的结果。
第一,前端 URL 中携带的匿名参数被纳入认证链。匿名访问语义直接暴露在页面入口中,本身就意味着认证上下文部分前置到了前端。
第二,初始化接口对匿名态参数缺乏足够限制。view.html 和 loader.js 会将这组参数一路送入 meta 请求,而后端又接受了这组参数并建立了有效 sessionkey。
第三,页面权限判断建立在错误的会话上下文之上。本应通过正常认证流程建立的访问身份,被匿名链路替代后,仍然可以通过页面权限校验。
第四,表单读数接口缺乏足够严格的服务端授权收敛。getData 本身是正常业务读数动作,但它依赖的会话已经来自错误的匿名入口,而服务端没有在这一层重新进行足够严格的授权校验。
最终,这几个环节拼成了一条完整链: 匿名入口暴露 → 匿名参数参与会话建立 → 页面权限放行 → 表单读数接口返回真实记录
这也是为什么它不是单纯的“前端参数泄露”,而是一条跨越入口、会话、权限和数据读取的组合型访问控制缺陷。
0x0B 修复建议:如何阻断这类匿名访问链
这类问题的修复不能只停留在“删掉某个前端参数”这一层,而应沿着整条访问链逐段收敛与阻断:首先,禁止前端 URL 参数直接参与会话建立,初始化接口也不得依据匿名参数生成业务访问 sessionkey;其次,页面权限与数据权限应在服务端分层校验,避免错误会话上下文继续穿透业务访问链;同时,表单读数接口需要严格绑定真实用户态与数据访问范围,防止匿名链路落到具体记录读取;最后,还应同步排查历史匿名 token、访问日志及受影响数据范围,并对移动端匿名访问场景开展专项梳理,避免类似问题再次出现。
结合最小化验证结果,可以确认该问题最终触达了教育场景下的真实敏感业务数据读取风险。受影响数据为校内来访登记记录,涉及姓名、证件号、联系电话等敏感字段;结合样本验证结果与记录规模判断,潜在影响范围约为 1000 条。
0x0C 复盘:这次协同流程真正帮到的是什么
回看整次过程,这套协同流程真正带来的价值,并不在于“自动替人挖洞”,而在于它能够在人工判断边界下,把原本分散在目录结构、页面配置、初始化逻辑、请求参数和前端渲染中的线索更快整理出来,并进一步收敛为一条可验证的调用链。有了代码证据之后,Burp MCP 的动作也被压缩为少量、明确且可复核的验证步骤,而不是脱离上下文的盲目测试;最终被确认的也不只是某个孤立异常点,而是代码证据、接口证据、页面证据与风险证据相互印证后形成的一条完整闭环。
原文链接:https://forum.butian.net/AISecurity/loudong/hottest
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:只会看监控的实习生 arar arar《AI + Skill + Burp MCP 协同实战:从匿名入口到记录读取的一次移动端代码审计闭环》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论