
简介《Android APP 渗透测试方法》是一份面向移动安全测试人员、渗透测试学习者与移动应用开发者的 PDF 技术手册系统梳理 Android 客户端安全测试的完整流程与方法论。文档从测试环境 SDK/工具准备讲起内容覆盖数字签名检测、反编译检测、APK 解包与资源解码、smali 代码分析、odex 转换、so 库静态分析、XML 处理及应用完整性校验等关键环节并针对代码混淆、加壳等场景给出风险判断和处理思路。资源为单文件 PDF共 1 个文件大小 15.27MB合计 137 页便于整体阅读和按章节索引。已有 727 人学习/下载适合安全工程师和移动端开发者在应用安全评估、渗透测试及漏洞自查时作为对照手册使用。1. 拿到 APK 先别急着装这份 137 页的 Android 渗透测试笔记讲了什么做 Android APP 渗透测试这行最怕的不是目标加固得密不透风而是拿到一个 APK 后不知道从哪下手。我自己早期的项目里就吃过亏客户丢过来一个 APK 让我测我打开就跑了个 drozer结果连导出组件都没看全更别说签名证书和自校验逻辑了。后来把整套动作梳理成固定流程效率才上来。这份 137 页的 PDF《Android APP 渗透测试方法》就是干这个用的——它不是泛泛讲概念而是把测试环境、签名检测、反编译、完整性校验、组件安全、drozer 利用整条链路按步骤写清楚了每一步都有命令、有判定标准、有风险结论。适合三类人一是刚入行的安全测试工程师照着命令能跑完一个标准检测二是做 App 开发的想看看自家应用在测试者眼里会暴露哪些问题三是甲方安全岗需要一份可执行的核查清单来评估外包团队交付的 App。2. 环境与签名验证先从 jarsigner 一行命令看发布者是谁2.1 测试环境的取舍JDK 版本和工具链怎么配这份 PDF 的环境清单很直白Java JDK、Android SDK、7zip、dex2jar、jd-gui、apktool、IDA Pro、010 editor、SQLite Studio、ApkIDE。我实际搭环境时有一些调整但核心里面没变。JDK 用 1.8 就够了原文里的命令路径就是C:\Program Files\Java\jdk1.8.0_111\bin\jarsigner.exe这是 Windows 环境如果你在 Linux 上测改成对应路径或者直接加入 PATH 即可。Android SDK 主要是为了拿 adb、aapt 和 android.jar这三样后面都会用到。工具安装有个先后顺序先保证 JDK 和 Android SDK 能用再装 apktool 和 dex2jar。因为 apktool 依赖 JAVA_HOME 环境变量dex2jar 也是个批处理脚本环境变量不对会直接报找不到命令。还有一个容易忽略的点apktool 需要下载 wrapper jar 包而不是直接用源码否则apktool d命令根本不会生效。我一般把 apktool.jar、dex2jar、jd-gui、signapk.jar 放在同一个工具目录里后面跑反编译和重打包流程时不用来回切路径。# 验证 Java 环境 java -version # 验证 Android SDK 里的 adb adb version # 验证 apktool 可执行 apktool --version这段命令逻辑很简单三步确认三个基础组件可用任何一个输出版本信息失败先解决环境问题再做后续测试省得后面所有命令都连环报错。PDF 里还提到了 ApkAnalyser 和 ApkIDE这类图形化工具适合快速看结果但自动化测试时我还是优先用命令行方便把输出重定向到日志里留痕。2.2 jarsigner 验签与证书风险分级签名检测是整个渗透测试里最先做的一步也是很多测试者会跳过去的一步。PDF 里给的命令是jarsigner -verify APK文件路径 -verbose -certs输出“jar 已验证”表示签名正常。但通过验证只是第一步更要紧的是看证书的 CN 字段。CN 是证书里的 Common Name代表发布者身份一份正常的商业 App 应该用公司主体证书签名证书里 CN 和公司注册名能对上。jarsigner -verify CQRCBank.apk -verbose -certs输出里会出现CNBeijing XXX Technology Co., Ltd.这样的字段这时需要和客户确认这是不是他们的正式证书。PDF 里给了很清晰的风险分级逻辑用直接客户的证书签名才算安全Debug 证书、第三方开发方证书一律视为风险。这个判断标准很实用因为很多内测包用的是androiddebugkey签的名这种证书任何人都能拿到APK 可以被随意重打包再签名毫无防篡改能力。证书类型判定结果风险说明客户公司正式证书安全CN 与发布者身份一致Debug 证书风险常见于开发阶段可被任意重签第三方/开发方证书风险发布者身份不明需与客户确认自签名证书视情况需结合业务场景评估2.3 debuggable 与 allowBackup两个容易被放过的 Manifest 开关PDF 里专门列了 debug 模式和应用程序数据可备份两个检测项这两个问题在真实项目里出现频率非常高而且都是 AndroidManifest.xml 里一行属性的事。android:debuggabletrue意味着应用可以被 jdb 直接调试测试者能附加到进程上读写内存、修改业务逻辑这种应用发布出去基本等于裸奔。检查方法有两个一是用 MobSF 这类静态扫描工具二是直接打开反编译出来的 AndroidManifest.xml 看属性。我一般两个都做MobSF 跑全量扫描手检做二次确认。MobSF 部署用 Docker 一条命令就能跑起来扫描结果里会把 debuggable、allowBackup、exported 组件这些高危项都列出来。android:allowBackup这个属性默认值是 true这是个非常隐蔽的坑。很多开发根本没意识到要显式关掉它。allowBackup 开启时攻击者可以用 adb backup 把应用数据导出数据库、SharedPreferences、本地缓存全都能拉走如果里面有明文 token 或敏感配置直接翻车。application android:allowBackupfalse android:debuggablefalse ... /application这是修复后的标准配置。allowBackup 设为 false 能防止 adb backup 和 adb restoredebuggable 设为 false 能防止调试器附加。注意设置了 debuggable 为 true 的应用即使测试结束后改成 false也要确认是重新签名发布而不是直接用旧包否则签名不一致会导致安装失败。PDF 里强调 stop testing 的条件之一就是发现 allowBackup 开启可见这个问题在甲方评审里的份量。3. 反编译与改包把 APK 拆到能看到源代码为止3.1 dex2jar jd-gui不混淆就没秘密反编译是 Android 渗透测试的核心动作几乎所有后续分析都建立在能看到代码的基础上。最经典的路径是把 APK 后缀改成 zip 解压拿到 classes.dex然后用 dex2jar 把它转成 jar最后用 jd-gui 打开 jar 看 Java 代码。# 改后缀解压 mv target.apk target.zip unzip target.zip -d apk_src # dex2jar 转换 dex2jar.bat apk_src/classes.dex # 输出 classes-dex2jar.jar 后用 jd-gui 打开命令背后的逻辑是APK 本质是 zip 包classes.dex 是 Dalvik 字节码JVM 不直接认识这种格式所以要先转成标准 class 文件再反编译。dex2jar 参数里不需要额外配置默认输出文件名就是 classes-dex2jar.jar。如果 APK 有多个 dex比如 multidex 的 classes2.dex要对每个文件单独执行一次转换。PDF 里有个很重要的提示有时候 apktool 能解出 smali但 dex2jar 会失败。这个我遇到过很多次多半是某些加固壳或特殊混淆手段导致 DEX 结构异常。遇到这种情况不要死磕 dex2jar退回 smali 分析反而更有效。反编译结果的判定逻辑是如果完整恢复了可读的 Java 代码且没有混淆不安全如果代码被混淆或加壳字段名变成 a、b、c 这类无意义名字或者核心逻辑被抽到 so 库里算安全。注意这里说的“安全”是相对的指的是代码抵抗逆向的能力。3.2 apktool 拆包smali、资源和 Manifest 同时到手apktool 是反编译工具里最能打的一个它能把 APK 拆成四部分smali 汇编代码、解码后的 AndroidManifest.xml、res 资源目录、以及原始签名信息。拆包命令格式是apktool d[ecode] [OPTS] file.apk [dir]。# 标准拆包 apktool d CQRCBank_2.1.1.1121.apk -o output_dir # 只拆资源不反编译 dex速度快很多 apktool d CQRCBank_2.1.1.1121.apk -s -o res_only # 只反编译 dex 不处理资源避免重打包时资源报错 apktool d CQRCBank_2.1.1.1121.apk -r -o smali_only三个命令对应三种场景。标准拆包用在完整分析时-s适合只要资源文件和 Manifest 的场景-r适合只改 smali 代码的场景。PDF 特别强调了一个经验如果只需要改 smali 代码尽量加-r不解码资源因为解码后的资源在回编时经常出问题aapt 报各种错这是无数人踩过的坑。拆包完成后smali 文件夹里就是 Dalvik VM 汇编代码。smali 虽然比 Java 代码难读但逻辑结构直观变量类型、方法调用、权限判定都能看出来。我在分析恶意逻辑时反而经常用 smali因为有些混淆只对 Java 层有效smali 层的信息伪造难度更大。3.3 odex 与 so 库真机厂商包怎么啃从手机里直接拉出来的 APK 往往没有 classes.dex而是 odex 文件——这是系统对 dex 优化后的产物主要出现在 /system/app 和 /system/framework 里。直接拿 baksmali 反编译会说格式不对必须先转回 dex。# 第一步baksmali 把 odex 解析为 smali java -jar baksmali.jar -x /path/to/classes.odex -d /path/to/framework/ # 第二步smali 重新打包成 dex java -jar smali.jar out/ -o classes.dex这里有个关键细节-d参数指定的 framework 路径不能随便填。odex 是在特定 Android 版本上生成的对应的 /system/framework/ 目录下有一堆 jar 文件baksmali 需要它们来解析系统 API 引用。如果 odex 是 Android 4.4 真机生成的就复制那台真机的 framework 文件如果是模拟器生成的就对应模拟器的版本。版本不匹配会直接抛异常后面避坑章节我会具体说。so 库的处理相对简单。APK 解压后进 lib/armeabi/ 目录把 .so 文件拖进 IDA Pro 就能静态分析。so 库通常是加密算法、核心校验逻辑的藏身处PDF 里说能看到导入导出函数和 ARM 汇编。我的一般做法是先看导出函数名如果出现check_signature、native_validate这类名字基本就能锁定自校验逻辑的位置。3.4 xml 解码与 aapt 资源重编改资源文件时的关键动作APK 里的 xml 大多数是二进制格式直接打开是乱码需要解码才能查看和修改。有两条路一条是用 apktool 整体解包另一条是用 AXMLPrinter 或 APKParser 单独处理某个 xml。# 用 AXMLPrinter 解码 AndroidManifest.xml java -jar AXMLPrinter.jar AndroidManifest.xml manifest_readable.txt # 用 aapt 重新编译资源 aapt.exe package -f \ -M apk-src/AndroidManifest.xml \ -I ANDROID-SDK/platforms/android-19/android.jar \ -S apk-src/res \ -F output.zipaapt 这步是重打包流程里的核心。-M指定 Manifest-I指定对应版本的 android.jar 以解析资源引用-S指定 res 目录-F指定输出 zip。PDF 里特意标注了这些路径对应 build-tools rev.20 和 android-19 platform如果你装了更高版本的 SDK路径要改。通常较新版本的 SDK 出错概率更小我一般直接用最新 build-tools但要注意 android.jar 版本和 targetSdkVersion 尽量接近否则有些资源 ID 解析不出来。关于单独编译单个 xml 这个问题PDF 里明确说了目前没有发现可行方法。想改 xml 里的内容再塞回 APK要么走 apktool 全量重打包要么就手动调 aapt 编整个 res。4. 完整性校验与组件安全自校验测的是同一件事4.1 重打包重签名三步判定应用有没有自校验应用完整性校验测试说人话就是把 APK 解开随手改点东西再重新打包签名看应用还能不能正常运行。能跑说明没有自校验攻击者可以植入任何代码不能跑或者弹警告说明有自校验篡改会被发现。PDF 给的标准流程分四步我做个小改动把资源文件修改放在最前面# 第一步拆包 java -jar apktool.jar d -f target.apk -o unpacked/ # 第二步随便改一个资源文件推荐改 logo容易肉眼确认 # 把 res/drawable-hdpi/ic_launcher.png 换成另一张图 # 第三步重新打包成未签名 APK java -jar apktool.jar b -f unpacked/ -o repack_unsigned.apk # 第四步用 testkey 签名 java -jar signapk.jar testkey.x509.pem testkey.pk8 repack_unsigned.apk repack_signed.apk这套流程的逻辑核心是验证「改包后的安装运行状态」。改 logo 是最优选择因为不用改代码不会引入编译错误而且一旦应用启动后显示的是自己换的图结果一目了然。-d和-f参数分别指定输入和输出-o指定输出路径。安装时要注意一个坑如果原 APK 签名和重打包后的签名不一致无法覆盖安装。# 先卸载再安装 adb uninstall com.example.target adb install repack_signed.apkPDF 里特别提醒APK 必须签名才能安装即使开启了“允许未知来源”不签名也无法安装。Debug 证书、自签名证书、过期证书在允许未知来源下都能装上但完全没签名的包不行。这与前面签名检测那章是呼应的——一个人可以随便生成 testkey 签名你的应用所以签名保护本身只防君子不防小人真正的防线是代码里的自校验逻辑。4.2 组件可导出判断规则三条就够了组件安全测试是渗透测试的重点章节PDF 把 Android 四大组件的导出规则浓缩成了三条判断逻辑非常实用1. 显式声明 android:exportedtrue → 可导出 2. 显式声明 android:exportedfalse → 不可导出 3. 未显式声明 exported a. 非 Content Provider 组件有 intent-filter → 可导出无 → 不可导出 b. Content ProviderSDK 版本 17 → 可导出≥ 17 → 不可导出这条判断规则的来历是 Android 官方的组件默认行为调整低版本系统里 Content Provider 默认对任何应用开放这是个历史遗留坑。判断组件是否可导出只是第一步能不能构成危害要结合源码分析。PDF 里的态度很中肯测试时把所有导出组件列全交客户开发侧确认哪些确实需要导出而不是一看到 exportedtrue 就报漏洞。组件安全测试工具可以辅助检测 exported 属性但 PDF 明确指出代码里动态注册的组件这种工具测不出来必须读代码。这也是为什么前面反编译分析那么重要——静态工具扫完最终还是要靠人肉跟代码。4.3 drozer 联动Activity、Service、BroadcastReceiver 逐个试drozer 是组件安全测试里的重型武器PDF 附录里给了大量命令。它的思路是从测试机向目标应用的导出组件发起调用观察能否产生越权动作。# 查看目标应用的 Activity 列表 run app.activity.info -a com.example.package # 直接启动某个 Activity run app.activity.start --component com.example.package com.example.package.welcome # 查看 Service 信息 run app.service.info -a com.example.package # 启动 Service run app.service.start --component com.example.package com.example.package.SomeService # 查看 BroadcastReceiver run app.broadcast.info -a com.example.package # 发送广播 run app.broadcast.send --component com.example.package --action android.intent.action.XXXActivity 测试的核心是「未授权访问」如果某个导出 Activity 含有页面跳转逻辑直接 am start 或 drozer start 拉起看它是否跳过了登录态校验。Service 测试关注的是 onStartCommand 和 onHandleIntent 里有没有处理不当的数据——比如接收外部 Intent 后直接拼接 SQL 或写文件。BroadcastReceiver 测试除了看导出还要重点看 onReceive 方法里是否对传入数据做了校验很多 App 一收广播就崩溃形成拒绝服务。drozer 模块对应命令风险关注点Activityrun app.activity.start未授权页面、越权跳转Servicerun app.service.start数据泄露、后台启动异常BroadcastReceiverrun app.broadcast.send拒绝服务、信息泄露Content Providerrun app.provider.info数据读取、SQL 注入PDF 里还提供了一个关键补充动态注册的 BroadcastReceiver 不在 Manifest 里需要反编译后检索registerReceiver()方法同时留意setPackage和receiverPermission参数——这两个参数是防止广播被外部应用截获的关键。5. 避坑与常见问题签名、打包、odex 和抓包的五个现场5.1 签名与安装环节的两个典型翻车现象一用 signapk 签完名的 APKadb install 时报INSTALL_FAILED_UPDATE_INCOMPATIBLE或者提示“应用未安装”。原因原 APK 用的是应用商店签名或客户正式证书signapk 默认的 testkey 签名和它不一致Android 不允许覆盖安装不同签名的应用。解决先adb uninstall卸载原应用再安装测试包或者从系统里提取原签名证书用 apkksigner 配合原证书重新签一遍修改后的包。注意做完整性校验测试时一定要保留原包备份卸载后万一测试环境被破坏还能恢复。现象二重打包安装后一启动就闪退Logcat 里报Signature check failed或Unable to get system security。原因应用内置了签名校验逻辑常见做法是在启动时调用getPackageManager().getPackageInfo()对比签名哈希或者通过 so 库里的 native 方法校验。解决这种情况说明自校验存在安全测试可以直接判定篡改会被拦截。如果甲方要求更深入的验证则需进一步定位校验点——IDA 打开 so 库搜signature、verify相关导出函数或者用 Frida hook 掉校验函数再重打包。5.2 反编译与打包环节的经典报错现象三apktool 重打包时报aapt: brut.common.BrutException错误信息长且带 resource 相关字样比如invalid resource reference。原因拆包时解码了资源回编时资源 ID 与当前 framework 版本对不上。常见于 targetSdkVersion 较高的 APK 用了较老版本的 apktool。解决两条路一是拆包时用-r参数不解码资源直接改 smali 不回编资源二是用apktool if framework.apk安装对应版本的 framework再重新拆包。PDF 原文的解决思路就是这个——添加 Android 4.4.2 framework 文件后重试现在的新版本 apktool 对高版本 SDK 兼容性好很多但原理没变。现象四dex2jar 反编译直接报格式错误或者生成的 jar 里大量方法显示为null。原因多为加固壳或特殊混淆导致的 DEX 结构异常也可能是 dex2jar 版本太旧不支持最新的 dex 格式。解决先更新 dex2jar 到最新版如果还不行回到 apktool 解 smali 的路线。smali 虽然不好读但信息完整度往往比硬解出来的 Java 代码高。一句话血泪经验反编译工具是黑匣子一个工具不行就换路线不要在一棵树上吊死。5.3 数据提取与抓包环节容易被忽略的坑现象五adb backup 明明执行了输出文件也有但用dd ifbackup.ab | openssl zlib -d解出来是一堆不完整的数据或者 Android 7.0 以上设备直接报Backup失败。原因allowBackup 为 true 时备份接口仍然受设备锁屏密码保护高版本系统又加强了备份数据的加密和完整性校验。解决root 设备上绕过备份接口直接从/data/data/com.example.package/目录拉取对应文件夹这是更直接的路径。非 root 设备就老老实实看 allowBackup 是否显式关闭关闭了证明测试点不成立。代理抓包还有另一层坑Android 7.0 默认不信任用户安装的 CA 证书Burp 或 Charles 的证书装上去HTTPS 流量照样解不开。这在 PDF 写的时候还不是普遍问题但现在已经成为每个代理测试者必踩的门槛。常见做法是adb shell settings put global http_proxy host:port配置全局代理再用adb reverse tcp:8080 tcp:8080做端口映射同时把抓包工具 CA 证书装进系统证书目录需要 root或者用 objection 这类工具做 SSL Pinning 绕过。6. 进阶技巧一次完整的静态到动态核查路径6.1 拿新包后的标准动作这章我把 PDF 里的散点收拢成一条可复用的路径。先说结论静态分析解决“有什么问题”动态验证解决“问题能不能打透”两者缺一不可。我处理陌生 APK 的日常动作是这样的。# 第一步静态信息采集 jarsigner -verify target.apk -verbose -certs # 签名信息 apktool d target.apk -o unpacked/ # 全量拆包 grep -E exported|debuggable|allowBackup unpacked/AndroidManifest.xml # 第二步组件与代码分析 dex2jar.bat unpacked/classes.dex # jd-gui 打开 jar重点看 exported 组件的入口类 # 第三步动态验证 adb install target.apk adb shell am start -n com.example.package/.WelcomeActivity # 直连导出 Activity drozer run app.activity.start --component com.example.package这套动作的核心逻辑是每一步的结果决定下一步的方向。签名有问题优先补测重打包exported 组件集中在某个 Activity 上就把 drozer 的重点放在那个组件反编译出来没混淆那么加固和自校验大概率不存在完整性问题可以快速跳过。验证方法本身也很直接所有动态操作的结论都要在设备上确认现象——Activity 要看到页面跳转Service 要在adb shell dumpsys activity services里看到进程启动广播测试要看 Logcat 里有没有 setPackage 相关提示。最后一个习惯强制执行的程序每个新包我都先跑一遍静态采集再定动态测试计划不跳过任何一步也不允许自己“猜”某个组件安不安全。文档里的规则是死的但人的判断会漂流程能兜住判断的偏差。这份 PDF 对我最大的价值就是它把这些流程拆成了可复现的步骤让我拿到手就能照着跑跑完再根据结果纵深。希望帮到你。本文还有配套的精品资源点击获取