综合实战:完整App安全测试流程——从扫描到渗透到报告

说实话,做了这么多年移动安全,我最怕听到的一句话就是:“你帮我测一下这个App安不安全。” 因为安全测试从来不是一键扫描就能搞定的事。它是一套完整的流程,从信息收集、自动化扫描,到手动渗透,最后落到一份能指导修复的报告上。

今天这一章,我就带你走一遍完整的实战流程。咱们拿一个虚构的“企业办公助手”App做靶子,把从零到一的测试过程拆开揉碎了讲。

核心思路:自动化扫描负责“广覆盖”,手动渗透负责“深挖掘”。两者缺一不可。

第一阶段:信息收集与预处理

拿到一个App,我习惯先做三件事:

  • 反编译APK:用jadx或GDA打开,看看有没有硬编码的密钥、API地址、第三方SDK。
  • 抓包配置:设置Burp Suite或Charles的代理,安装用户证书。注意Android 7以上有证书锁定,得用Xposed或Frida绕过。
  • 了解业务逻辑:注册个账号,跑一遍核心功能。比如这个办公App,有登录、审批、文件上传、即时通讯。

嗯,这里有个坑。我曾经遇到一个App,反编译后发现所有API都走的HTTPS,但抓包却全是明文。后来发现是客户端做了双向认证,但服务端没校验——说白了,就是个摆设。所以别光看代码,一定要动手验证。

第二阶段:自动化漏洞扫描

自动化扫描是效率利器。我一般分两层扫:

2.1 静态扫描

用MobSF(Mobile Security Framework)跑一遍。它能自动检测:

  • WebView远程代码执行风险
  • 不安全的文件存储(比如SharedPreferences存密码)
  • Intent劫持风险
  • 证书锁定缺失

跑完后,MobSF会生成一份报告。但别全信——它经常报假阳性。比如它说“WebView启用了JavaScript接口”,但实际那个接口只加载了本地HTML,风险很低。这时候就需要人工判断。

2.2 动态扫描

我习惯用Drozer做自动化组件测试。它会枚举所有暴露的Activity、Service、BroadcastReceiver,然后尝试越权调用。

# 枚举所有可导出的Activity
dz> run app.activity.info -a com.example.office

# 尝试直接拉起一个需要登录的Activity
dz> run app.activity.start --component com.example.office com.example.office.ui.AdminPanelActivity

你猜怎么着?这个办公App的AdminPanelActivity居然是可导出的,而且没做权限校验。直接拉起就能看到所有员工的审批记录。这就是典型的“组件暴露”漏洞。

我的经验:自动化扫描能帮你发现80%的“低垂果实”,但剩下20%的严重漏洞,往往藏在业务逻辑里。比如越权访问、支付篡改、密码重置逻辑缺陷——这些自动化工具很难抓到。

第三阶段:手动渗透测试

手动渗透才是真正考验功力的地方。我一般按这个顺序来:

3.1 认证与会话管理

先测登录。这个App用的是JWT做身份认证。我截获了Token后,尝试:

  • 修改alg为none(经典攻击,但大部分服务端已经防了)
  • 修改sub字段为其他用户ID
  • 重放旧Token(看有没有过期机制)

结果发现,把Token里的userId改成1001,就能直接以管理员身份登录。这就是“越权访问”——服务端只信任客户端传来的用户标识,没做二次校验。

3.2 数据存储安全

检查App的本地存储。用adb连上设备,进到/data/data/com.example.office/目录:

adb shell
run-as com.example.office
cat databases/office.db

好家伙,数据库里明文存了用户的手机号和通讯录。更离谱的是,SharedPreferences里有个isProUser=true的键值对。改成false?不,改成true就能解锁付费功能。这就是典型的“客户端信任”问题。

3.3 网络通信安全

抓包看API请求。我发现文件上传接口是HTTP的,而且没做任何校验。直接上传一个包含恶意代码的HTML文件,然后通过另一个接口访问它——XSS攻击就这么成了。

为什么会这样?因为开发只关注了主业务的HTTPS,忽略了文件存储域名的安全配置。说白了,就是“木桶效应”——最短的那块板决定了整体安全水位。

3.4 业务逻辑漏洞

这个最考验脑洞。我测试了审批流程:

  • 提交一个审批请求,金额1000元
  • 抓包修改金额为-1000元
  • 服务端没校验负数,直接扣了别人的额度

这就是“整数溢出/负数绕过”。开发只做了前端校验,后端完全信任。我见过不少App,前端校验做得花里胡哨,后端却形同虚设。

注意:手动渗透时一定要控制风险。别在生产环境搞破坏,也别修改别人的真实数据。我一般用测试账号,在测试环境操作。如果必须用生产环境,只做只读测试,比如信息泄露验证,绝不写数据。

第四阶段:漏洞报告与修复建议

测试完了,最后一步是写报告。一份好的安全报告,应该让开发看得懂、修得了、排得了优先级。

我习惯用这个模板:

漏洞编号 漏洞名称 风险等级 影响范围 修复建议
VULN-001 JWT越权访问 严重 所有用户数据 服务端校验Token中的userId与当前会话是否一致
VULN-002 本地数据库明文存储 高危 用户隐私数据 使用Android Keystore加密敏感字段
VULN-003 文件上传XSS 中危 文件存储域名 上传文件做Content-Type校验,存储域名启用HTTPS
VULN-004 负数金额绕过 高危 财务系统 后端校验金额必须大于0

每个漏洞我还会附上:

  • 复现步骤(截图+请求报文)
  • 影响分析(比如“攻击者可查看任意员工工资”)
  • 修复代码示例(如果可能)

一个小技巧:报告里别只写“修复建议:加强校验”。要写具体,比如“在UserController.java第45行,增加userId与sessionId的比对逻辑”。开发拿到报告就能直接改,不用再问“你说的加强校验是改哪里?”

知识体系总览

下面这张图,是我自己总结的完整测试流程。每次做项目前,我都会对着它过一遍,确保没有遗漏。

App安全测试完整流程 信息收集 反编译 / 抓包 / 业务了解 自动化扫描 MobSF / Drozer 手动渗透 认证 / 存储 / 通信 / 逻辑 报告 修复建议 认证与会话管理 数据存储安全 网络通信安全 业务逻辑漏洞 常见漏洞类型 JWT越权 明文存储 XSS / 文件上传 负数金额绕过 自动化扫描 → 手动渗透 → 报告输出 广覆盖 + 深挖掘 + 可落地修复建议

写在最后

这一套流程走下来,你会发现安全测试其实是个“体力活+脑力活”的结合。自动化工具帮你省时间,但真正决定漏洞发现深度的,还是你对业务逻辑的理解和对细节的敏感度。

我记得刚入行时,总觉得手动渗透很酷,恨不得每个接口都测一遍越权。后来发现,真正高效的测试是“带着问题去测”——先想清楚这个App最值钱的数据是什么,攻击者最可能从哪里下手,然后集中火力打那几个点。

嗯,今天就聊到这儿。希望这套流程能帮你建立起自己的测试框架。下次拿到一个App,别急着扫,先花10分钟想清楚:我要测什么?从哪里开始?报告写给谁看?想清楚了,效率翻倍。

公众号:蓝海资料掘金营,微信deep3321