ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Inspeckage实战:安卓动态分析Xposed模块抓包逆向运动App

Inspeckage实战:安卓动态分析Xposed模块抓包逆向运动App 我第一次正式用 Inspeckage是在给一个运动打卡类 App 做上线前自查的时候。那会儿我需要确认三件事本地存储有没有泄露用户字段、网络请求有没有做加密与签名、以及系统版本升级之后这些接口行为会不会变。传统抓包工具只能回答“流量侧”的问题但我想知道某个请求的数据到底从哪段代码、哪个配置里拼出来这就需要动态分析工具介入。Inspeckage 是一个基于 Xposed 框架的安卓动态分析模块特点是能让你在浏览器里看一个 App 运行时的网络请求、文件读写、数据库操作和加解密调用。和 Burp Suite 这类中间人代理配合起来基本能描出一张很完整的“App 行为地图”。这篇实录我会以“某运动打卡类应用”作为分析案例完整走一遍从环境搭建、抓包取数、到定位关键逻辑的过程。适合刚入门安卓逆向的测试人员也适合想对自己 App 做安全自查的开发者。我们不讨论任何恶意破解和作弊改数据重点是把“看懂一个 App 怎么工作”这件事讲明白。1. 先从需求说起这类分析到底要解决什么问题1.1 抓包、逆向和动态调试边界怎么画很多人把“抓包”和“逆向”混成一个概念但实际上它们解决的是不同层的问题。抓包解决的是“客户端和服务端之间发生了什么”它站在网络链路的角度能看到请求头、请求体、返回数据、状态码这些信息。逆向工程则更底层它要解决的是“客户端内部是怎么实现的”比如某个字段是从哪一段逻辑里生成的某个加密密钥又是写在哪里的。动态调试则介于两者之间。它通过 Hook 或者断点的方式在程序运行过程中去观察内存、篡改函数返回值、或者记录调用栈。Inspeckage 本质上就是把 Hook 的输出整理成了可视化面板虽然不叫调试器但思路是一脉相承的。在一个完整的分析项目里最好是抓包先定性再用代码定位来验证。我在实际工作中经常碰到这样的情况请求里的某个参数加密了抓包只能看到一串密文这时候你就得反编译出来看加密逻辑、找密钥位置再把动态 Hook 的结果和静态代码互相印证。所以标题里“抓包”和“逆向”是顺序关系不是并列关系。1.2 为什么拿打卡类应用当案例选“运动打卡类应用”作为案例一是因为它涉及定位、轨迹、时间上报这类典型敏感数据拿来讲隐私合规问题很有代表性二是因为这类应用通常会做签名校验和参数防篡改分析的过程能覆盖比较多的常见技术点。这类 App 的通信模型中有几个几乎必然出现的接口登录鉴权接口、用户信息查询接口、打卡或者运动记录上报接口。上报接口一般会携带经纬度、运动速度、路线点集、时间戳这类字段。当我们看到这类字段以明文或者可辨识形式出现在流量里时就要思考是否合理是否过度采集这是合规审计中很重要的一步。当然我说的是在你有授权的前提下进行分析。本文所有操作都应该在自己拥有或者已获得明确授权的 App 上完成不要用于绕过业务规则、虚假打卡这类行为。2. 认识 Inspeckage功能拆解与分工边界2.1 它到底能看什么Inspeckage 本质上是 Xposed 模块。Xposed 的工作原理是在应用进程启动时把一段代码插入到系统进程的入口里这样 App 在运行过程中调用一些关键函数时就会被“钩住”被钩住的函数可以在调用前、调用后插入我们自己的逻辑。Inspeckage 利用这个机制自动在很多关键的系统函数上布了监控点。启动后它会在手机本地开一个 Web 服务默认端口是 8008你通过浏览器打开http://localhost:8008如果是模拟器则通过 adb 把端口映射到宿主机就能看到下面的信息模块。Network网络模块记录 Hook 到的 HTTP 请求和响应包括 URL、Header、请求体和返回的 JSON 结构。这块和代理抓包有部分重合但优势在于它能看到一些通过非标准网络库发出的流量以及混淆 App 中自定义网络层的请求内容。SharedPreferences偏好设置实时展示应用写入的键值对配置。很多 App 会把登录 Token、用户信息、设备标识临时存到这里分析这个模块能快速定位鉴权信息是如何缓存与刷新的。你在界面上点几次按钮这里可能就多出几条新记录对应关系非常直观。Files文件模块列出应用内部存储中正在被读取或者写入的文件并提供文件内容查看。这里常常能找到数据库文件、日志文件、或者缓存的配置 JSON。有一次我在这个模块里直接看到一个应用的加密密钥被写进了调试日志这种问题靠纯黑盒测试很难发现。Databases数据库模块监控 SQLite 的打开、查询和写入操作。当 App 做了本地数据缓冲时可以在这里直接查看表结构和记录省去了把数据库文件 pull 出来再查的流程效率会明显高一些。IPC进程间通信展示 App 与其他组件之间通过 Binder、Intent 等机制传递的数据可以用来评估组件暴露风险比如有没有可以被外部任意调用的 Activity 或 Service。运动类应用经常要接收系统广播、后台切换消息这里很容易看出组件间的数据流向。Crypto加密模块Hook 常见的 MD5、SHA、AES、RSA 等加密接口调用记录输入的明文字符串、算法参数和输出的密文。对分析带加密的通信非常关键能直接看到密钥和 IV 在调用时的具体值。简单说代理抓包看到的是“加密后的结果”Crypto 模块看到的是“加密前的原料和钥匙”。这些模块叠加起来已经覆盖了一个 App 在运行时大部分的敏感操作面。相比单独去看数据库文件、单独抓包Inspeckage 是把“运行中的事实”整合到了一起这是它的核心价值。2.2 和 Charles、Burp Suite 这类工具怎么分工有一类非常典型的误区装了 Inspeckage 就不再需要代理抓包只用它一个工具就够。这不现实原因有三个。第一Inspeckage 的 Network 模块依赖 Hook 成功率。如果目标 App 自己实现了加密通道或者用了 WebSocket、TCP 私有协议它的记录可能不完整。而 Burp Suite 这类代理工具处在网络层它看到的是真实离开设备的字节流不受应用内部实现的干扰。第二TLS 解密能力不同。代理工具可以在安装 CA 证书之后解密大部分 HTTPS 流量但没法处理那些不走系统证书链的请求。而 Inspeckage 能拿到请求组装阶段的明文天然不受证书信任策略影响。两者配合正好互补。第三使用场景不同。日常调试的时候我更常用 Charles因为它轻量、够用。但是当我需要看“某个请求是由哪段代码发起的”“某个加密函数的输入到底是什么”的时候就会切到 Inspeckage。如果你只想知道接口长什么样代理就够了如果你想从本地行为倒推代码逻辑就得靠 Inspeckage。最理想的状态是让代理工具负责“全量流量证据”Inspeckage 负责“本地动态行为证据”两边一对照整个分析画面基本就闭环了。3. 实验环境搭建从模拟器到证书信任链3.1 设备与系统选型Inspeckage 需要 Xposed 框架支持经典的原版 Xposed 只支持到 Android 7 左右这就直接影响了实验环境的选择。如果你的目标主要围绕低版本兼容性分析那选一台 Android 6.0 或者 7.0 的模拟器是最省事的。Xposed 安装包在模拟器上很容易找而且很多 x86 镜像自带 root 权限省去刷机步骤。如果被分析的应用要求高版本系统才能运行越来越常见你可以考虑 Android 8.0 以上的环境配合 LSPosed。LSPosed 是 Xposed 的社区分支支持新版 Android对 Inspeckage 的兼容性也维护得不错。安装方式一般是通过 Magisk 刷模块宿主环境只要提供 root就能跑起来。模拟器选择上我比较推荐 Genymotion 直接跑低版本系统或者自己用官方镜像创建一个 Android 7 x86 的模拟器。如果你更喜欢命令行风格用 Level 23 的 AVD 镜像也行不过需要额外手动装相关组件。真机如果需要使用可以找一台可以自由刷机的旧机型成本和门槛会高一些。真机和模拟器的区别主要在两点。一是传感器模拟运动打卡类 App 常常会检查定位和传感器模拟器上往往需要手动注入 GPS 坐标真机直接具备 GPS 与环境传感器。二是架构差异模拟器大多是 x86 架构一些只编译了 arm 库的 App 运行起来会有兼容性问题遇到这种情况也只能切到真机。3.2 安装 Xposed/LSPosed 与 Inspeckage以 Android 7 模拟器上安装原版 Xposed 的流程为例启动模拟器确认 root 权限可用。Genymotion 自带AVD 需要先刷入 userdebug 镜像再执行adb root。下载对应架构的安装器 APK 并安装安装器会自动检测系统版本。打开安装器点击“Install”重启模拟器。安装 Inspeckage APK再次进入 Xposed 的“模块”界面勾选 Inspeckage然后重启系统让模块真正加载。需要注意Xposed 安装失败最常见的原因是系统镜像的 ramdisk 没有解锁。很多模拟器镜像默认的分区校验会阻止修改系统分区所以先确认能不能正常把文件写入再执行安装流程。如果使用 LSPosed流程逻辑类似先装 Magisk再刷入 LSPosed然后在 LSPosed 列表里启用 Inspeckage。启用后同样需要重启应用或整个系统Hook 才能生效。区别只在于新版系统的分区结构更复杂刷模块时要留意 Magisk 版本和系统架构是否匹配。3.3 配置 HTTP 代理与 CA 证书有了 Inspeckage代理抓包依然值得配好因为它是我们拿到网络传输原始内容的第一视角。这里以 Burp Suite 为例把电脑上的代理监听地址设为0.0.0.0:8080允许来自局域网的连接。在模拟器里打开 WiFi 设置修改当前网络的代理为电脑 IP 加端口。更省事的做法是用 adbadb shell settings put global http_proxy 电脑IP:8080这样所有走系统代理的应用都会经过 Burp。接下来是证书信任的问题。Burp 默认生成一个自己的 CA 证书应用在 HTTPS 握手时会对它做签名校验。Android 7 之前把证书装进“用户凭据”就可以被信任Android 7 之后系统默认不信任用户证书只有装到系统证书目录才算数。这就是很多人对高版本系统抓包失败的根本原因。把 Burp 的证书转成系统证书的基本流程是openssl x509 -inform der -in cacert.der -out cacert.pem mv cacert.pem $(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1).0 adb root adb remount adb push hash.0 /system/etc/security/cacerts/ adb shell chmod 644 /system/etc/security/cacerts/hash.0执行完这几步之后再重启模拟器HTTPS 流量就应该能被 Burp 解密查看。如果遇到重启后证书被复位的情况多半是系统分区没有真正可写需要先关闭动态校验或者以读写方式重新挂载。3.4 高版本 Android 的证书适配如果必须分析的是 Android 9 以上的 App除了证书问题还有另一个很常见的阻碍目标应用在targetSdk 28及以上时默认不信任明文 HTTP 流量甚至部分带安全配置的版本还会限制信任的 CA。此时你的代理抓包经常能看到连接被断开的情况这就是系统层面的兼容性策略所致。解决思路上有几个选择如果 App 自带网络安全配置可以在其中增加信任 CA但这只对你自己维护的测试包有效。对第三方分析的场景更多是用动态 Hook 的方式去注入证书信任逻辑。这条路需要一定的脚本开发知识适合熟悉动态调试后进阶本文不展开具体代码。如果是自己公司的应用最省事的方案是在构建配置里临时去掉网络限制用 debug 包做分析基本零成本。我个人的经验是生产环境 App 的证书锁定逻辑千奇百怪靠加装证书一种方式解决不了所有问题把“系统证书配置”和“动态 Hook”两条路线都掌握是比较稳妥的状态。4. 实操全记录Inspeckage 抓包分析打卡类 App4.1 启动服务并选定目标应用环境搭建好之后打开 Inspeckage 的应用界面。第一次启动会列出设备里的应用列表你直接找到要分析的应用包名。如果是一个第三方 App可以通过adb shell pm list packages | grep 关键词先找到包名再在 Inspeckage 里选中它。选中后点击“Start”按钮Inspeckage 会在本地 8008 端口启动服务。然后执行adb forward tcp:8008 tcp:8008把端口映射到宿主机电脑浏览器打开http://localhost:8008就能看到控制台面板。面板右上角会显示当前分析的包名下方是按模块分类的页签。启动观察之后再去手动操作一遍 App 的核心功能让 App 跑一遍真实的业务流程同时盯住面板上的日志变化。这一步的操作顺序很重要先启动监控再操作 App否则关键请求很容易被漏掉。4.2 网络模块把请求参数和行为对上号以打卡类 App 的日常流程为例正常应该是登录进入首页拉取任务信息开始某项运动时上报轨迹点结束后提交整段记录。每一步都会产生流量但网络模块里最值得关注的不是那些图片加载、广告请求而是和业务强相关的接口。在一次完整记录里你大概率会看到类似下面的请求结构POST/api/v1/user/login参数里有account、pass、device_id、app_version。GET/api/v1/task/list返回当天可参与的任务列表。POST/api/v1/track/upload请求体是一大段 JSON包含track_points数组每个点有lon、lat、timestamp、speed。POST/api/v1/track/report最终提交运动里程、总时长、平均速度。看到这些字段之后建议把每个参数和一个数据来源对应上。比如speed来自定位模块计算出的瞬时速度timestamp来自系统时钟device_id来自持久化存储或硬件信息合成。这样你才能判断哪些数据是客户端本地合成的哪些依赖服务端下发。有一点要提醒参数加密很常见。如果pass在请求里是密文先别慌切到 Inspeckage 的 Crypto 模块往往能直接看到对应的加密输入与密钥。这也是我为什么强调它是网络分析的关键补充代理看明文Inspeckage 看生成明文的地方。4.3 本地存储模块从配置到数据库的信息拼图请求参数来源问题实际上就是本地存储来源问题。在 Inspeckage 的 SharedPreferences 里你能看到类似user_info、device_info这类键值文件数据库模块里则能看到用户表、缓存表、轨迹表的写入记录。实际分析时我通常用下面这个顺序先看 SharedPreferences 里存了什么。如果token和user_id直接以明文形式躺在配置里说明 App 在鉴权信息本地化处理上比较简单若要评估风险需要考虑是否能被其他应用读取以及有没有做加密。再看数据库表结构。数据库往往存储着最近几十条历史记录可以进一步观察服务端下发的数据结构。最后看文件读取列表。结合文件内容可以知道有没有把缓存 JSON 写到磁盘日志文件是否携带敏感参数。这个过程最大的好处是你不需要反复反编译代码去猜逻辑所有现场都有记录。比如你看到数据库模块里有一条轨迹插入记录那你大概就能猜出前端保存数据是以什么形式和粒度存的后续代码分析时心里就有底了。4.4 静态分析配合用 jadx 从代码层面去印证动态看到的东西最终还是要落到代码上去印证。比如你在流量里发现pass参数是加密值但具体密钥是怎么来的是硬编码、配置文件还是服务端下发这一步靠动态工具看不全需要把 APK 解包看。我常用的流程是jadx -d out com.example.testapk.apk反编译之后先在代码目录里搜关键词比如api_key、secret、AES、encrypt再用grep去搜索前一步抓到的接口路径比如track/upload然后顺着调用链往回找。以 track/upload 为例反编译后看到的代码轮廓大概是这样public void uploadReport(ListTrackPoint points) { String data gson.toJson(points); String encrypted CryptoUtil.aesEncrypt(data, getSecret()); OkHttpClient client new OkHttpClient(); Request req new Request.Builder() .url(https://api.example.com/v1/track/upload) .addHeader(sign, md5(data getSecret())) .post(RequestBody.create(encrypted)) .build(); }这个片段里可以看到两层信息一是数据做了 AES 加密二是还加了一个sign头做参数校验。如果你在抓包时习惯只看返回 JSON很容易忽略这类请求头里的签名字段但它在整个安全评估里恰恰是最值得关注的一环。静态分析真正的价值是能回答这样的问题这个参数是怎么生成的这个加密用的什么算法这个接口调用由什么触发只要你能把这三件事说清楚整个分析基本就完整了。反过来如果静态代码里看到的行为和动态抓到的行为不一致那就要警惕 App 是不是做了多重逻辑替换把关键请求伪装成了普通流量。5. 常见问题与排查技巧5.1 快速排查表症状常见原因排查思路Inspeckage 面板打开没有数据Xposed 模块未启用或未重启回 Xposed 检查模块勾选状态重启后重试代理下所有 HTTPS 流量都无法解密用户证书在 Android 7 上不被信任将 CA 装入系统证书目录并确认没有证书固定逻辑只有部分接口能看到其他看不到App 使用自定义网络库或私有协议以本地存储分析为主重点关注请求组装阶段的日志记录请求能看到明文接口但关键参数是密文应用在客户端做了加密去 Crypto 模块查看算法与密钥使用模拟器运行 App 闪退只支持 arm 原生库或检测模拟器更换 arm 镜像或改用真机安装 Xposed 后开机卡循环系统分区校验未解锁用解锁补丁重新挂载再重装模块表格里的每一种情况我都实际遇到过尤其是前两种占了至少六成的问题。如果你刚搭好环境就遇到连不上代理的情况先从证书信任查起往往能省掉一大半折腾时间。5.2 三个容易忽略的细节第一个细节一定要把系统时钟校准。App 在做签名校验的时候经常会把当前时间和服务端时间做对比如果模拟器的时区不对请求会出现在签名计算上失败进而返回 401。很多人排查了半天请求逻辑最后发现是时间戳的问题。第二个细节区分“应用自己发的请求”和“第三方 SDK 发的请求”。现在绝大多数 App 都集成了推送、统计、地图等第三方 SDK网络模块里的大体量流量其实来自这些 SDK。如果一开始就对着所有域名挨个看很容易晕。我建议先只关注主业务域名再做下一步精细分析。第三个细节使用 Inspeckage 时尽量做到“最小操作”。每次只操作一个核心业务动作然后立刻去面板看日志避免多个线程同时发起大量请求不然 Hook 日志会刷得非常快关键信息反而被淹没。5.3 一次最典型的排查过程我拿一次实际适配过程讲讲。当时我们在 Android 14 真机上跑 LSPosed代理也配好了证书也装进系统目录了可是代理上看到的全是连接记录完全没有应用层的明文。反复折腾半小时后才发现目标 App 的targetSdk比较高并且在网络安全配置里只信任指定证书把系统证书目录整个排除了。代理不可能在握手阶段取得它信任。这种情况只能用动态 Hook 绕不展开具体脚本。但排查思路很关键先确认是不是“系统证书不信任”的问题。方法很简单抓一个该手机上浏览器的 HTTPS如果能解密说明证书链路没问题如果只有目标 App 失败说明它自己做了一层限制要么是证书固定要么是网络安全配置的信任规则。把边界判断清楚方向就对了。实操心得这类问题最忌讳一上来就怀疑工具出了问题。我见过太多人反复重装 Xposed、反复清缓存最后才发现只是目标 App 的证书策略特殊。先做横向对比测试永远比反复折腾单一变量要快。6. 踩了这么多坑之后说说我的体会我常对刚入行的朋友说抓包工具安装起来不难但对分析尺度的把握需要积累。第一先学会看完整闭环再做细致拆解。切忌上来就反编译全部代码应该先从一次完整的业务请求入手把“从打开 App 到产生一次行为”的整个链路看明白。很多新人一上来就对着某个加密函数猛冲结果问他在哪个业务场景触发、请求前后依赖是什么完全答不上来这就本末倒置了。第二动态和静态互相印证。动态分析告诉你“发生了什么”静态分析告诉你“为什么会发生”两者缺一不可。没有动态依据的代码分析容易停留在想象没有静态依据的动态日志容易沦为现象堆砌。我在实战中最爽快的时刻基本都是先在 Inspeckage 里看到一条加密调用记录然后在反编译代码里找到同一处逻辑两边严丝合缝对上。第三高版本兼容是常态。还在把 Android 7 当标配的人会越来越吃力早点熟悉 LSPosed 和动态 Hook 这一类新框架比反复折腾老系统更划算。技术栈会过时但分析思路不会永远从“数据从哪里来、到哪里去、经过了什么变换”这条主线出发就不会被工具版本牵着走。最后再分享一个小技巧。很多 App 的敏感逻辑分布在多个代码分支里装好工具后最省心的方式是先整体跑一遍核心场景再通过 Inspeckage 按模块分组导出日志再切到 jadx 里逐层下钻。这样你既能保证不遗漏外层流量也不会被大量日志干扰。长期下来你会慢慢建立一套属于自己的“App 行为分析地图”遇到再陌生的目标也会知道自己第一步该看哪里第二步该查什么。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表