应用从未被打开
智能体运行框架(agentic harness)改变了大语言模型在移动应用安全测试中所能完成的工作。单靠模型本身,它可以列举出可能的风险,例如不安全的存储、暴露的密钥、高风险权限、存在漏洞的 SDK、后端问题和隐私泄露,但应用本身可能始终未被触碰。当模型周围配备了合适的工具、上下文、记忆、提示词、执行循环和运行时反馈时,它就能检查应用包、观察行为、跟踪流量、关联信号,并留下安全团队可以审查的证据。从权限分析到借助 GEF 的原生漏洞利用,差异在执行轨迹中清晰可见:留下的是应用证据、工具输出、运行时证明和可复现的步骤,而不是貌似报告的文字。
为什么智能体运行框架正成为真正的移动安全测试的关键
把一个移动应用交给语言模型,让它测试安全性。
得到的答案可能似曾相识:不安全的存储、弱加密、暴露的密钥、过多的权限、存在漏洞的 SDK、后端问题、身份验证缺陷、隐私风险。
它可能像报告一样结构清晰,可能引用了正确的类别,读起来可能像是安全团队可以拿去分发的东西。
而应用仍然从未被打开。
没有检查任何应用包。没有对照运行时行为检查任何权限。没有观察任何 SDK 流量。没有审查任何存储位置。没有跟踪任何后端调用。没有捕获任何崩溃状态。没有任何证据被交付。
报告已经存在,目标的状态却从未改变。
一个没有双手的推理引擎
大多数关于 AI 在安全领域应用的讨论仍然从模型开始:哪个模型更聪明、哪个推理能力更强、哪个上下文窗口更长、哪个在基准测试中表现最好。
在真实的安全工作流中,模型只是整个系统的一部分。
原始模型可以理解指令、提出假设、描述攻击路径,并决定下一步该做什么。但测试一个目标需要与目标真正接触。应用必须被解包。权限必须被审查。SDK 必须被识别。存储必须被检查。流量必须被观察。身份验证流程必须被测试。后端调用必须被跟踪。噪声线索必须被剔除。最终留存下来的发现,必须有比一段文字更可靠的东西作为支撑。
围绕在模型周围的,是让这些步骤得以发生的工具、上下文、提示词、技能、记忆、执行循环和反馈。
当模型能够触及应用时
模型看到“敏感数据存储”,就能描述应该检查什么:Shared Preferences、本地数据库、缓存文件、钥匙串的使用、加密、日志。这些说法都没错,但应用仍然是一个黑盒。
在配备运行框架的工作流中,应用会被解包,存储位置会被检查,配置文件会被打开,运行时行为会被观察。某个值要么出现在磁盘上,要么没有。一个疑点要么获得证据支撑,要么逐渐消失。
SDK 的情况也一样。
模型可以警告第三方 SDK 可能带来隐私泄露。这种警告足够常见,听起来很有用。但 SDK 尚未被识别,其网络目的地尚未被观察,其权限尚未与实际流量进行比对,也没有检查任何载荷。
然后问题就变了。它不再是“这可能有风险吗?”,而是:存在什么、运行了什么、什么离开了应用,以及有什么证据与之关联?
Anthropic 在长时间运行的智能体工作中也展示了同样的模式:模型并不是孤立地变强的,它周围的工作流也发生了变化——提示词、工具、上下文管理、反馈循环。OpenAI 关于运行框架工程(harness engineering)的文章也指向了围绕智能体的同类工作:验收标准、验证、缺失的工具、护栏、文档。
这些例子讲的是软件工程。在移动安全领域,同样的模式出现在制品、运行时、工具输出以及模型能够运行的下一项测试周围。
一个精心打磨的答案,仍然可能根本没有触碰应用。
工具箱并不等于运行框架
智能体式安全有一种偷懒的版本:给模型一堆工具,然后称之为智能体。
过多的原始输出涌入上下文。过早地提供了过多的工具。扫描器结果到来时缺乏足够的解读。微弱的信号变成了言之凿凿的发现。一个可疑的字符串变成了密钥。一项权限变成了隐私违规。一个不寻常的端点变成了可被利用的后端问题。
一个有用的运行框架则更为克制。它决定模型首先看到什么、哪些工具属于下一步、应该记住什么,以及某个问题在成为发现之前需要达到什么程度的证据。
在移动安全中,几乎每一个信号都需要这样的上下文。一项权限并不自动构成隐私问题。一个第三方 SDK 并不自动就是恶意的。一个存储的值并不自动就是敏感的。一个可疑的请求并不自动就是可被利用的。
一项权限并不是一个发现
以位置访问为例。
模型可以解释为什么位置访问可能带来隐私风险。这是有用的背景知识,但它不是一个发现。
必须在运行时检查该权限。必须识别相关 SDK。必须观察流量。必须审查目的域名。必须检查载荷。必须将应用声明的用途与其实际发送的内容进行比较。
只有到那时,问题才变得有意义。
位置是在什么时候被收集的?由哪个组件收集?它被发送到了哪里?是否与标识符一起发送?它与某个分析 SDK、广告 SDK、后端端点,还是用户实际触发的某项功能相关联?
从外部看,应用是一个整体。深入检查后,它变成了多个层次:代码、权限、SDK、存储、流量、后端调用和平台行为。
类别从一开始就显而易见。只有在证据推进之后,发现才会浮现。
GEF 让运行框架变得具体
在原生漏洞利用中,同样的模式更容易看清。
通用大语言模型可以描述这些步骤:逆向原生库、检查不安全的算术运算、构造崩溃触发条件、查看寄存器、完善利用原语。方法论可能是正确的,而目标却始终未被触碰。
在一个 Android JNI 案例中,模型连接到了 GEF——一个基于 GDB 构建的漏洞利用工具。
智能体逆向了原生库,在一处图像尺寸计算中发现了 64 位到 32 位的整数截断。截断后的值控制了堆分配的大小,而原始的 64 位值控制了复制的长度。
分配的空间小于复制的数据量。
输入被精心构造,崩溃得以复现。一个间接函数指针被一个可识别的 64 位标记值覆盖,该标记值出现在崩溃状态中。
该原语被进一步完善为一次受控的原生函数调用,其第一个参数由攻击者控制。执行流被重定向到 Android 的原生库加载器。一个专门构建的共享库在应用进程内运行。
日志显示了执行情况。该库的初始化例程生成了证明制品。
这条路径并没有止步于“可能存在堆溢出”。它贯穿了整个目标:计算、分配、崩溃、控制、调用原语、加载器、执行、证明。
模型提供了推理,而 GEF 让推理始终与正在运行的进程紧密相连。
工作必须可供审查
一旦智能体能够采取行动,另一个问题就出现了。
它检查了什么?哪个工具输出改变了结论?收集了哪些证据?做出了哪些假设?调查在哪里停止?
在攻击性安全和移动测试中,只有当有人能够理解系统是如何得出某个发现的,这个发现才有用。如果智能体报告了敏感数据泄露,审查者需要看到完整路径:应用行为、存储位置或请求、载荷、受影响的数据,以及将证据与发现联系起来的推理。
如果智能体决定不报告某个问题,这个决定同样需要有路径可循。也许该权限被声明了但从未被使用。也许该 SDK 存在但处于非活动状态。也许该端点看起来不寻常,但并未暴露敏感行为。
漏洞利用也是如此。如果智能体声称实现了代码执行,审查者不应该只看到一句“漏洞利用成功”。证据链应当清晰可见,从存在漏洞的计算一直到运行时证明。
缺少这种可见性,输出就难以站得住脚。它可能是正确的,但团队无迹可循。它也可能是错误的,却依然表达得足够流畅,看起来令人信服。
运行框架会记录所发生的一切:权限、工具边界、审批节点、证据日志、可复现的步骤以及停止条件。
智能体负责调查,而团队仍然需要看到调查过程。
从貌似报告的文字到站得住脚的测试
模型不再只是列出应该检查什么。它在处理应用证据、工具输出、运行时行为、流量、依赖信号、漏洞利用轨迹和可复现的步骤。每一步的结果都会改变下一步。
输出的形态也随之改变。取代一份更整洁的检查清单的,是一条贯穿目标的路径。取代一段看似合理的文字的,是审查者可以检查的制品。取代“这可能有风险”的,是一条经得起质疑的证据链。
安全团队可以打开制品、跟踪执行轨迹、重放步骤、检查运行时证明。
不是一个听起来像渗透测试人员的模型。
而是一条经得起渗透测试人员检验的轨迹。