Android应用的攻击面往往隐藏在包结构、导出组件、文件权限和后台服务中。开展一次有效的侦察测试,需要在安装前后分别收集设备状态、应用元数据和运行时行为。本文将按照从外到内的顺序,逐一说明每个阶段的常用命令与分析思路,帮助安全测试人员快速建立信息基线。

一、侦察测试的目标与信息分类
侦察测试的核心目标是回答三个问题:应用暴露了哪些可被外部调用的组件?应用申请了哪些敏感权限?应用在运行时会将哪些数据写入本地或发送到网络?围绕这三个问题,收集的信息可以划分为静态元数据、设备状态、运行行为和网络流量四大类。静态元数据包括APK包名、版本号、签名信息、Manifest中的组件声明和权限列表;设备状态包括系统版本、SDK级别、已安装包列表和USB调试状态;运行行为包括应用启动后的进程、服务、文件访问和数据库操作;网络流量则涵盖HTTP/HTTPS请求、DNS查询和Socket连接。
很多测试人员在拿到APK后直接上动态分析工具,结果经常漏掉导出组件或弱权限配置这类低垂果实。实际上,先做全面的静态枚举,再结合动态验证,能够大幅提升后续渗透测试的效率。下面将按照从基础命令到专业工具的路径,逐步展示每个维度的具体操作方法。
二、使用ADB与系统命令进行基础侦察
ADB(Android Debug Bridge)是所有Android安全测试的起点。通过ADB可以获取设备信息、安装应用、转发端口以及执行Shell命令。首先确认设备连接状态,然后查看系统属性。系统属性中的ro.build.version.release表示Android版本,ro.build.version.sdk表示API级别,这些信息决定了后续可以使用的权限模型和绕过手段。例如,Android 6.0以下版本在安装时授予所有权限,而高版本则采用运行时权限机制,攻击者可以利用不同版本的差异设计钓鱼或权限提升路径。
包管理命令pm是侦察中的高频工具。列出所有已安装的第三方包,可以快速定位目标应用是否已存在于设备上,以及是否存在同开发者的其他应用。通过dumpsys package可以查看应用申请的权限、签名信息和安装时间。下面的命令组合展示了如何获取目标应用的基础信息并过滤出与网络相关的权限。
# 查看已连接设备 adb devices # 获取Android版本和SDK级别 adb shell getprop ro.build.version.release adb shell getprop ro.build.version.sdk # 列出第三方包并过滤目标应用 adb shell pm list packages -3 | grep target # 查看目标应用申请的权限 adb shell dumpsys package com.target.app | grep permission
除了pm,dumpsys还能查看活动服务、通知、电池状态等信息。例如adb shell dumpsys activity activities可以显示当前前台Activity,adb shell dumpsys meminfo可以查看内存中的敏感字符串。这些系统级信息虽然不能直接构成漏洞,但能够为后续的运行时分析和内存抓取提供上下文。
三、应用层静态侦察:Manifest与资源分析
APK本质上是一个压缩包,解压后可以得到classes.dex、resources.arsc和AndroidManifest.xml等文件。直接查看Manifest文件需要先进行反编译,因为二进制XML无法用文本编辑器阅读。常用的静态分析工具有aapt、apktool和jadx。其中aapt dump badging可以快速输出包名、版本、启动Activity、权限和SDK版本等关键信息,适合作为自动化流程的第一步。
Manifest中的<activity>、<service>、<receiver>和<provider>组件声明是攻击面分析的重点。如果某个组件的android:exported属性被设置为true,就意味着其他应用可以通过Intent显式调用它,即使没有权限保护也可能被利用。例如,一个导出的<provider>可能允许外部应用读取或修改内部数据库。下面的XML片段展示了一个带有导出Activity的典型配置。
<activity android:name=".LoginActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:name=".DataProvider" android:exported="true" android:authorities="com.target.app.provider" />
分析完组件导出情况后,需要核对权限列表。过度申请权限不仅增加隐私风险,还可能被恶意应用利用进行权限重委派攻击。重点关注READ_CONTACTS、RECORD_AUDIO、ACCESS_FINE_LOCATION等高危权限,并检查是否有android:protectionLevel为normal的自定义权限可被第三方声明绕过。同时,资源文件中的硬编码字符串、URL和API密钥也属于静态侦察的重要输出,可以通过strings命令或jadx的全局搜索功能快速提取。
四、运行时动态侦察:Drozer与Frida初探
静态分析能够定位潜在的攻击面,但无法确认这些攻击面在实际运行中是否真的可被利用。Drozer是一款专为Android安全评估设计的框架,它通过安装一个代理APK与目标应用交互。运行run app.package.attacksurface命令可以自动列出目标应用的所有导出组件、权限和可访问的Content Provider,并按风险等级排序。对于导出的Content Provider,还可以使用run scanner.provider.finduris枚举可访问的URI,尝试读取敏感数据。
Drozer的安装过程稍微繁琐,但其模块化的命令设计非常适合重复测试。下面演示如何启动Drozer控制台并针对目标包执行攻击面扫描。
# 在电脑端启动Drozer控制台 drozer console connect # 列出目标包的攻击面 dz> run app.package.attacksurface com.target.app # 枚举内容提供者的URI dz> run scanner.provider.finduris -a com.target.app
当Drozer无法覆盖某些深度场景时,Frida提供了更底层的动态插桩能力。通过Frida可以Hook特定函数、修改返回值、枚举类和方法,甚至绕过SSL Pinning。一个简单的Frida脚本可以打印目标应用加载的所有类,帮助理解运行时结构。与Drozer相比,Frida需要root权限或可调试应用,但在真机和模拟器上都能获得极细粒度的控制。下面的JavaScript代码展示了如何枚举已加载的类并过滤出包含特定关键词的类名。
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (className) {
if (className.indexOf("target") !== -1) {
console.log(className);
}
},
onComplete: function () {}
});
});
动态侦察的关键在于验证静态发现的可疑点。例如,如果Manifest中某个<activity>被导出且没有权限保护,可以尝试用am start命令直接启动它,观察是否出现敏感界面或功能绕过。同理,使用content query命令可以对导出的Content Provider进行真实的读取操作,进一步扩大攻击面。
五、网络与存储数据侦察
移动应用的大多数业务逻辑都依赖网络通信,因此抓取和分析流量是侦察测试中不可忽略的一环。Android设备默认使用HTTPS进行加密传输,直接抓包只能看到域名和IP。要解密HTTPS流量,需要将代理工具的CA证书安装到设备受信任的根证书存储中,或者使用Frida绕过SSL Pinning。常用的抓包方案包括tcpdump命令行抓包配合Wireshark分析,以及mitmproxy或Burp Suite作为中间人代理。抓包时要重点关注登录接口、支付回调、API密钥、用户令牌和任何包含敏感参数的请求。
除了网络数据,应用在本地存储中留下的痕迹同样具有侦察价值。通过adb shell run-as命令可以访问可调试应用的私有目录。查看shared_prefs文件夹中的XML文件、databases中的SQLite数据库以及files目录下的缓存文件,经常能发现明文密码、会话令牌和调试日志。下面的命令演示了如何进入目标应用的沙箱并提取数据库内容。
# 进入可调试应用的沙箱 adb shell run-as com.target.app # 查看内部存储结构 ls -la # 列出shared_prefs中的XML文件 cat shared_prefs/*.xml # 查看SQLite数据库中的表 sqlite3 databases/app.db ".tables"
需要特别注意的是,Android从7.0开始限制了run-as对非可调试应用的使用,此时可以借助备份功能或root权限获取数据。另外,存储在外部存储(如SD卡)中的文件通常对所有应用可读,测试时应检查目标应用是否将敏感数据写入/sdcard/Android/data以外的公共目录。对网络和存储的联合分析能够揭示数据在传输和静态存储两个环节的保护强度,为后续的漏洞利用提供明确方向。
完成上述四个维度的侦察后,测试人员应当输出一份结构化的信息清单,包含导出组件列表、权限风险项、可疑URL、敏感文件路径和可用的动态Hook点。这份清单不仅是渗透测试的作战地图,也能帮助开发团队理解应用暴露在外的攻击面,从而在发布前进行针对性加固。