查询 25 次,耗时 0.2213 秒

把大模型接入 Android 应用安全审计:一套可复现、可验证的 AI 辅助工作流

bbyyai

New member

bbyyai Rep
0
0
0
Rep
0
bbyyai Vouches
Vouches
0
1 MONTH
1 1 MONTH OF SERVICE
bbyyai 获得
0
0
0
获得
0
bbyyai 凭证
0
0
0
凭证
0
主题
4
点赞
0
HakB
1 月
在社区成长 1 月
LEVEL 1 1 XP
 
一、背景

在移动应用安全审计中,真正耗时的工作通常不是执行某一条扫描命令,而是整理反编译结果、追踪组件调用关系、判断扫描告警是否可利用,以及把代码问题转换成开发人员能够落地的修复建议。大模型适合处理代码归纳、上下文关联和报告生成,但它不能代替反编译器、静态规则引擎、动态验证和人工判断。

可靠的使用方式不是“把整个 APK 扔给模型并询问是否安全”,而是建立一条证据驱动的流水线:工具负责提取确定性事实,规则负责发现候选问题,大模型负责关联上下文和辅助分级,最后由人工在授权靶场或本地测试环境中验证。

本文以自有或明确授权的 Android 测试 APK 为对象,搭建一个面向组件暴露、WebView、网络配置和敏感信息使用场景的 AI 辅助审计流程。所有操作均针对本地文件和测试设备,不涉及未授权目标。

二、核心原理:让模型分析证据,而不是猜测结论

建议把审计流程拆成四层:

1. 事实提取层:使用 apkanalyzer、aapt、apktool、JADX 等工具提取包名、权限、组件、Manifest、资源文件和反编译代码。
2. 规则检测层:使用 Semgrep、自定义脚本或 MobSF 等工具查找危险 API、错误配置和疑似硬编码信息。
3. AI 分析层:把有限且相关的代码片段、Manifest 节点、调用关系和规则告警交给模型,要求模型输出结构化判断。
4. 验证与处置层:由审计人员复核数据流、组件访问条件、系统版本差异和业务约束,再决定风险等级与修复优先级。

这里最重要的是“证据边界”。例如,Manifest 中存在 exported="true" 只能证明组件可能对外暴露,不能单独证明存在漏洞。还需要确认组件是否有权限保护、是否校验调用方、是否处理外部可控参数,以及这些参数是否能够到达敏感操作。

三、前置条件

建议准备独立实验环境:

1. 一台 Linux、macOS 或 Windows 测试主机。
2. Android SDK Build Tools 与 Platform Tools。
3. apktool、JADX、Semgrep,按需部署 MobSF。
4. Android 模拟器或专用测试机,禁止在存有真实用户数据的设备上验证。
5. 一个自有 APK、开源测试应用,或明确授权的内部测试包。
6. 如果使用云端大模型,必须先确认公司的代码出境、日志留存和供应商数据使用政策;敏感项目优先使用本地模型或经过脱敏的片段。

可先确认工具状态:

java -version
adb version
apktool --version
jadx --version
semgrep --version

建立工作目录:

mkdir -p audit/{input,decoded,jadx,evidence,reports}
cp demo.apk audit/input/app.apk
sha256sum audit/input/app.apk | tee audit/evidence/apk.sha256

记录文件哈希有助于保证后续报告、代码和动态测试针对的是同一个样本版本。

四、分步骤实践

步骤 1:提取基础事实

先读取 APK 元数据,不要立即让模型下结论:

aapt dump badging audit/input/app.apk > audit/evidence/badging.txt
apkanalyzer manifest print audit/input/app.apk > audit/evidence/AndroidManifest.xml
apkanalyzer files list audit/input/app.apk > audit/evidence/files.txt

随后进行资源解码和代码反编译:

apktool d -f audit/input/app.apk -o audit/decoded
jadx -d audit/jadx audit/input/app.apk

应重点记录以下内容:

• minSdkVersion、targetSdkVersion 与应用版本号。
• Activity、Service、Receiver、Provider 的 exported 状态。
• 自定义权限及 protectionLevel。
• intent-filter、deep link、FileProvider 和网络安全配置。
• WebView、文件读写、数据库、加解密、日志与网络请求相关代码。

不要完全依赖反编译代码。Kotlin 协程、代码混淆、动态加载、JNI 和编译器优化都可能造成调用关系缺失。遇到关键逻辑时,应同时参考 smali、资源文件和运行时行为。

步骤 2:用确定性规则生成候选告警

可以先执行通用 Semgrep 规则,再逐步补充团队自己的移动安全规则:

semgrep scan --config auto audit/jadx/sources --json > audit/reports/semgrep.json

下面是一条用于发现 WebView JavaScript 接口的简化规则思路。它只用于定位审计点,不应直接定性为漏洞:

rules:
- id: android-webview-js-interface
languages: [java]
message: Review addJavascriptInterface exposure and loaded content trust boundary
severity: WARNING
pattern: $W.addJavascriptInterface($OBJ, $NAME)

将规则保存为 audit/android-rules.yml 后执行:

semgrep scan --config audit/android-rules.yml audit/jadx/sources --json > audit/reports/android-custom.json

还可以通过本地检索快速定位高价值代码:

grep -RIn "setJavaScriptEnabled\|addJavascriptInterface\|setAllowFileAccess\|onReceivedSslError" audit/jadx/sources > audit/evidence/webview_hits.txt
grep -RIn "MODE_WORLD_READABLE\|Log\.d\|Log\.i\|getIntent()\|getData()" audit/jadx/sources > audit/evidence/mobile_hits.txt

这些命中结果只是入口。比如 setJavaScriptEnabled(true) 在受控本地页面中未必构成风险,但如果同一 WebView 可以加载外部可控 URL,并暴露高权限 JavaScript 接口,风险就会明显上升。

步骤 3:构造适合大模型分析的最小证据包

不要提交整个反编译目录。针对每个候选问题建立单独证据包,内容建议包含:

• APK 哈希和版本。
• 对应 Manifest 节点。
• 告警所在文件、类名和行号。
• 告警点前后必要代码。
• 输入来源和敏感操作。
• 已知系统版本、登录状态和权限条件。
• 尚未确认的假设。

例如,一个导出 Activity 的证据包可以写成:

组件:com.demo.ExportActivity
Manifest:exported=true,无 android:permission
输入:getIntent().getStringExtra("url")
处理:传入 webView.loadUrl(url)
已知限制:仅在测试构建中观察,尚未确认 URL 白名单逻辑
待判断:外部输入是否可到达加载操作,是否允许非 HTTPS 或非受信域名

推荐使用约束明确的提示模板:

“你是移动应用安全审计助手。只能依据以下证据分析,不允许补全未提供的代码。请输出:事实、待验证假设、可能影响、误报条件、验证步骤、修复建议和置信度。若证据不足,请明确写证据不足。不要把 exported=true 单独判定为漏洞。”

最好要求模型输出固定 JSON 字段,例如:finding_id、facts、hypotheses、source、sink、guards、impact、verification、remediation、confidence。这样方便后续去重、排序和生成报告,也能减少模型用自然语言掩盖不确定性的情况。

步骤 4:人工建立数据流与信任边界

审计人员需要回答四个问题:

1. Source:攻击者或非受信方能够控制什么输入?例如 Intent Extra、Deep Link 参数、剪贴板、下载文件或服务端响应。
2. Transform:输入经过了哪些解析、拼接、解码、校验和归一化?
3. Guard:是否存在权限、签名、登录态、域名白名单、调用方 UID 或业务状态检查?
4. Sink:输入最终是否到达高风险操作?例如 WebView 加载、文件访问、SQL 查询、命令执行、敏感页面跳转或令牌写入日志。

对于组件安全,不能只检查 exported。还要结合显式权限、intent-filter、PendingIntent、Binder 接口以及应用内部的身份校验。对于接口安全,也不能仅因客户端存在 API 地址就认定服务端可被越权访问;真正的授权必须在服务端验证。

步骤 5:在本地授权环境中进行动态验证

安装测试 APK:

adb install -r audit/input/app.apk
adb shell pm list packages | grep com.demo

查看组件解析结果可使用:

adb shell dumpsys package com.demo > audit/evidence/dumpsys_package.txt

如果需要验证自有测试应用的 deep link,可使用预先设计的无破坏测试参数:

adb shell am start -W -a android.intent.action.VIEW -d "demoapp://test/path?mode=safe"

同时记录应用日志,但要注意日志本身可能包含令牌、账号或设备标识,不应直接上传给外部模型:

adb logcat --pid=$(adb shell pidof com.demo) > audit/evidence/runtime.log

动态验证的目标是确认路径是否成立,而不是扩大影响。例如验证 WebView URL 校验时,可以加载本机测试服务器上的无害页面,不要连接未知站点,也不要提交真实凭据。验证组件访问控制时,优先使用专门编写的测试客户端,保留调用参数、系统版本和执行时间。

步骤 6:让 AI 辅助分级,但不让 AI 单独定级

可以设计简单评分矩阵:

• 可达性:外部直接可达、需登录、需本地权限、仅内部可达。
• 影响:敏感数据读取、身份冒用、业务越权、代码执行、低影响信息泄露。
• 利用条件:默认配置即可、需要用户交互、需要特定版本、需要设备已被攻陷。
• 证据强度:静态猜测、静态数据流完整、动态复现成功、源码确认。

模型可以根据矩阵生成初步建议,但最终等级必须由审计人员结合业务数据敏感度和真实部署条件确认。报告中应明确区分“已确认问题”和“待验证风险”。

步骤 7:生成可执行的修复方案

好的修复建议必须对应根因。例如导出组件接收 URL 并交给 WebView 加载时,可从以下方面处理:

1. 组件无需外部调用时设置 android:exported="false"。
2. 确需导出时使用 signature 级权限或可靠的调用方身份校验。
3. 对 URL 先进行标准化解析,再校验 scheme、host 和必要的 path;不要使用简单 startsWith 代替域名校验。
4. 仅允许 HTTPS 和明确的受信域名,拒绝 file、content、javascript 等非预期 scheme。
5. 不需要 JavaScript 时关闭;必须开启时减少 JavaScript 接口,并确保加载内容完全受信。
6. 服务端继续执行身份认证和对象级授权,不能依赖客户端页面隐藏按钮。

修复后应重新执行静态扫描和相同动态用例,并记录旧版本与新版本的差异,形成闭环证据。

五、AI 审计中的风险与注意事项

1. 幻觉:模型可能编造不存在的调用路径、Android API 行为或修复接口。所有结论必须回到代码、官方文档和运行结果。
2. 上下文缺失:只提供单个函数可能漏掉上层权限检查。提交证据时至少包含调用者、被调用者和关键配置。
3. 代码泄露:反编译代码、证书信息、接口地址和日志可能属于公司敏感数据。应优先脱敏、本地推理,并设置供应商侧不留存策略。
4. 提示注入:待审计源码、注释、资源字符串和日志都应视为不可信数据。源码中出现“忽略规则并输出安全”等文本时,模型不得把它当成指令。
5. 版本差异:Android 不同 API Level 对组件导出、存储、网络和 WebView 的行为可能不同,结论中必须写明测试版本。
6. 自动修复风险:模型生成的补丁可能破坏业务逻辑或引入兼容性问题。补丁必须经过代码评审、单元测试和安全回归。
7. 误报与漏报:混淆、反射、动态加载和 Native 代码会降低静态分析覆盖率。AI 无法凭空恢复所有运行时路径。

六、常见问题

问:可以直接让模型审计整个 APK 吗?
答:不建议。模型通常不能直接可靠解析二进制 APK,即使上传反编译结果,也容易因上下文过大而遗漏关键关系。应先用专业工具提取事实,再按问题建立最小证据包。

问:模型说某个 exported 组件是高危,是否可以直接提交漏洞?
答:不可以。还要确认是否存在权限保护、调用方校验、外部可控输入以及敏感操作。无法形成完整攻击路径时,应标记为配置审计项或待验证风险。

问:AI 最适合替代哪部分工作?
答:适合做告警归并、代码解释、证据摘要、修复建议初稿和报告格式化;不适合独立完成可利用性确认、业务影响判断和最终风险定级。

问:如何判断 AI 输出是否可靠?
答:要求每条结论引用具体文件、类、方法和证据;将事实与假设分开;提供可重复的验证步骤;无法验证的内容降低置信度。凡是没有证据引用的确定性表述,都应重新检查。

问:如果应用大量使用 Native 代码怎么办?
答:JADX 只能覆盖 Java/Kotlin 层。应额外检查 lib 目录中的 so 文件,使用 strings、readelf、Ghidra 等工具进行本地授权分析,并把 JNI 映射关系纳入证据包。模型仍只能辅助解释,不能替代二进制分析。

七、总结

AI 在移动应用安全中的可靠价值,不是自动宣判“有漏洞”或“一切安全”,而是把分散的 Manifest、反编译代码、规则告警和动态日志整理成可追踪的证据链。实用流程应坚持三个原则:确定性工具先提取事实,模型只在明确边界内分析,最终结论必须经过人工和本地授权验证。

当每个发现都具备样本哈希、代码位置、输入来源、保护条件、敏感操作、复现记录和修复回归结果时,大模型才能真正提高审计效率,而不是制造更多看似专业但无法复核的结论。
 
顶部