apk是对一个安卓应用程序所需要的文件进行打包,本质上是一个被签名的压缩包。
通常情况下,apk会含有以下文件:
jadx/jeb:均为Android程序Java层反编译软件,相对来说jeb反编译能力相对较强,可以看到smali层的代码,而且也有一些混淆对抗的能力
frida:Android程序二进制动态插桩工具,用来动态调试Android程序
xposed:动态调试插件,相对于frida更加稳定
mitmproxy:中间人工具,用来监控并解密app端TLS流量
wireshark:对网卡进行抓包,配合mitmproxy使用可以获取tls解密后的流量信息
ida:用来反编译Android native层代码
iptables:配合mitmproxy透明模式,避免app端流量不经过代理导致tls流量无法被解密
手机:已ROOT
adb:用来连接手机的shell
本次使用的手机是一台Pixel 6,首先需要在电脑上安装adb,过程省略
进入手机开发者模式,打开USB调试开关,连接电脑adb,可以使用adb devices查看是否连接成功,连接成功后开始解BL,输入
1 | |
将手机进入Bootloader界面,此时手机处于fastboot模式下,输入fastboot devices查看是否可以正常连接。输入
1 | |
成功解锁BL。
注:Pixel手机如果发现进入fastboot模式adb断开的情况,请检查是否是数据线的原因,可以换个数据线试试,这个坑卡了我好久-_-
解锁BL后,一般都会向手机中安装Magisk,它是用来管理Root权限的工具。来源:topjohnwu/Magisk: The Magic Mask for Android (github.com)
下载好安装包后,可以使用adb install命令来安装Magisk,装好Magisk后,接下来进行镜像修补。
在Nexus 和 Pixel 设备的出厂映像 | Google Play services | Google for Developers中下载手机对应的镜像文件,在手机设置 - 关于手机页面的最底端可以看到当前的版本号,在页面中找到对应的镜像下载,下载后将其中的boot.img用adb传输到手机,最后使用Magisk软件进行镜像修补,最后将修补完的镜像文件adb pull出来。
接下来进入最后的刷机步骤,使用adb reboot bootloader再次进入fastboot模式中,使用fastboot boot img地址指令将手机从修补过的img启动,重启后进入Magisk按照步骤安装好即可。
mitmproxy是一个强大的中间人代理工具,与其他中间人代理工具相比,mitmproxy不仅可以转发http/https流量,还可以转发非http流量,如MQTT等。
在Android设备中抓取https流量,我们需要安装mitmproxy的CA证书,由于Android 7开始,应用会默认忽略用户级别的证书,因此,我们需要将CA证书放入系统级别中。
一般情况下,将证书格式先转化为pem格式,然后通过openssl x509 -subject_hash_old -in certificate.pem|head -1命令读取哈希值,将pem证书名字改为刚刚提取的哈希值加.0,如9a5ba575.0,其中.0是为了防止证书哈希值重复,如果两个证书哈希值重复,那么后面的证书就会被重命名为.1、.2等,最后将/system/etc/security/cacerts/目录可写权限打开,将重命名后的证书放进去即可。
我的手机版本为Android 10以上,无法直接通过更改文件夹写入权限来导入证书(也可能是我没有搞好),我使用了Magisk的Always Trust User Certificates模块,直接将证书装在用户目录下,重启后即可导入到系统证书中。
装好证书后,正常情况下手机端连wifi时配置代理后应该是可以解密https流量了,但是,如果app拒绝代理或想要捕获其他tcp流量时,就需要使用mitmproxy透明模式,透明模式的启动命令为mitmproxy --mode transparent --showhost,开启透明模式后,工作原理如下图:

此时,对于手机来说,mitmproxy相当于一个服务器,对于原服务器来说,mitmproxy相当于设备。
由于透明模式需要对网络层进行转发,因此还需要配置iptables,关于iptables的知识可以看这篇博客iptables-朱双印博客 (zsythink.net),在此贴一张iptables的原理图。

我的iptables规则参考了fwx学长的博客基于mitmproxy+iptables+SSL pinning绕过技术+wireshark的安卓APP流量(包括HTTP、HTTPS和非HTTP)捕获 | 代码鬼才的Blog (fwx2233.github.io),如下:
1 | |
最开始我一直想要拿win+mitmproxy透明模式进行抓包,想要通过netsh来代替iptables进行流量转发,然而一直没有成功,如果读者有配置成功的经历麻烦评论区分享一下
接下来配置wireshark,通过捕获mitmproxy密钥交换过程中生成的随机数来进行TLS解密,操作方式也可以直接看官方文档Wireshark and SSL/TLS (mitmproxy.org)
如果时间过长或多次抓包导致生成的随机数文件过大,可能会导致wireshark解密失败,可以定时清空生成的随机数文件。
至此基本环境配置完毕,给出我的最终网络拓扑图。

frida安装过程省略,网上有很多教程可以参考。
frida中有两种操作模式,分别是CLI模式和RPC模式
frida有两种注入模式,分别是Spawn和Attach
-f,可以对从启动就开始对App进行监控。相关的api可以在官网上查看官方文档Welcome | Frida • A world-class dynamic instrumentation toolkit
给出一个python的框架代码:
1 | |
Java层hook示例代码:
1 | |
hook重载参数:
1 | |
hook字段修改:
1 | |
对内部类进行hook
1 | |
静态方法主动调用
1 | |
非静态方法主动调用
1 | |
枚举so库
1 | |
hook函数
1 | |
这里有一个偏移值的计算,安卓里一般32 位的 so 中都是thumb指令,64 位的 so 中都是arm指令,通过IDA里的opcode bytes来判断,arm 指令为 4 个字节(options -> general -> Number of opcode bytes (non-graph) 输入4)
ida的话就是纯看代码环节了,说几个小技巧吧。
首先就是尽量不要从导出表中反过来找函数,因为有一部分导出表对应的函数是fastcall类型,只观察函数内部有时ida无法将参数识别出来,导致后来再去找函数的调用处时代码都是乱的。
ida有一键生成frida的插件,P4nda0s/IDAFrida: IDA Frida Plugin for tracing something interesting. (github.com)和AnxiangLemon/MyIdaFrida: Generate Frida Script (github.com),可以直接从ida中生成frida的hook脚本,比较方便(虽然我没用过几次)
关于漏洞细节就不发出来了。历时2个多月的零基础从入门到入土,确实学到了不少东西,也踩了一大堆坑,有的坑也卡的比较久,在此感谢w学长给我一步步梳理思路。
apk是对一个安卓应用程序所需要的文件进行打包,本质上是一个被签名的压缩包。
通常情况下,apk会含有以下文件:
jadx/jeb:均为Android程序Java层反编译软件,相对来说jeb反编译能力相对较强,可以看到smali层的代码,而且也有一些混淆对抗的能力
frida:Android程序二进制动态插桩工具,用来动态调试Android程序
xposed:动态调试插件,相对于frida更加稳定
mitmproxy:中间人工具,用来监控并解密app端TLS流量
wireshark:对网卡进行抓包,配合mitmproxy使用可以获取tls解密后的流量信息
ida:用来反编译Android native层代码
iptables:配合mitmproxy透明模式,避免app端流量不经过代理导致tls流量无法被解密
手机:已ROOT
adb:用来连接手机的shell
本次使用的手机是一台Pixel 6,首先需要在电脑上安装adb,过程省略
进入手机开发者模式,打开USB调试开关,连接电脑adb,可以使用adb devices查看是否连接成功,连接成功后开始解BL,输入
1 | |
将手机进入Bootloader界面,此时手机处于fastboot模式下,输入fastboot devices查看是否可以正常连接。输入
1 | |
成功解锁BL。
注:Pixel手机如果发现进入fastboot模式adb断开的情况,请检查是否是数据线的原因,可以换个数据线试试,这个坑卡了我好久-_-
解锁BL后,一般都会向手机中安装Magisk,它是用来管理Root权限的工具。来源:topjohnwu/Magisk: The Magic Mask for Android (github.com)
下载好安装包后,可以使用adb install命令来安装Magisk,装好Magisk后,接下来进行镜像修补。
在Nexus 和 Pixel 设备的出厂映像 | Google Play services | Google for Developers中下载手机对应的镜像文件,在手机设置 - 关于手机页面的最底端可以看到当前的版本号,在页面中找到对应的镜像下载,下载后将其中的boot.img用adb传输到手机,最后使用Magisk软件进行镜像修补,最后将修补完的镜像文件adb pull出来。
接下来进入最后的刷机步骤,使用adb reboot bootloader再次进入fastboot模式中,使用fastboot boot img地址指令将手机从修补过的img启动,重启后进入Magisk按照步骤安装好即可。
mitmproxy是一个强大的中间人代理工具,与其他中间人代理工具相比,mitmproxy不仅可以转发http/https流量,还可以转发非http流量,如MQTT等。
在Android设备中抓取https流量,我们需要安装mitmproxy的CA证书,由于Android 7开始,应用会默认忽略用户级别的证书,因此,我们需要将CA证书放入系统级别中。
一般情况下,将证书格式先转化为pem格式,然后通过openssl x509 -subject_hash_old -in certificate.pem|head -1命令读取哈希值,将pem证书名字改为刚刚提取的哈希值加.0,如9a5ba575.0,其中.0是为了防止证书哈希值重复,如果两个证书哈希值重复,那么后面的证书就会被重命名为.1、.2等,最后将/system/etc/security/cacerts/目录可写权限打开,将重命名后的证书放进去即可。
我的手机版本为Android 10以上,无法直接通过更改文件夹写入权限来导入证书(也可能是我没有搞好),我使用了Magisk的Always Trust User Certificates模块,直接将证书装在用户目录下,重启后即可导入到系统证书中。
装好证书后,正常情况下手机端连wifi时配置代理后应该是可以解密https流量了,但是,如果app拒绝代理或想要捕获其他tcp流量时,就需要使用mitmproxy透明模式,透明模式的启动命令为mitmproxy --mode transparent --showhost,开启透明模式后,工作原理如下图:

此时,对于手机来说,mitmproxy相当于一个服务器,对于原服务器来说,mitmproxy相当于设备。
由于透明模式需要对网络层进行转发,因此还需要配置iptables,关于iptables的知识可以看这篇博客iptables-朱双印博客 (zsythink.net),在此贴一张iptables的原理图。

我的iptables规则参考了fwx学长的博客基于mitmproxy+iptables+SSL pinning绕过技术+wireshark的安卓APP流量(包括HTTP、HTTPS和非HTTP)捕获 | 代码鬼才的Blog (fwx2233.github.io),如下:
1 | |
最开始我一直想要拿win+mitmproxy透明模式进行抓包,想要通过netsh来代替iptables进行流量转发,然而一直没有成功,如果读者有配置成功的经历麻烦评论区分享一下
接下来配置wireshark,通过捕获mitmproxy密钥交换过程中生成的随机数来进行TLS解密,操作方式也可以直接看官方文档Wireshark and SSL/TLS (mitmproxy.org)
如果时间过长或多次抓包导致生成的随机数文件过大,可能会导致wireshark解密失败,可以定时清空生成的随机数文件。
至此基本环境配置完毕,给出我的最终网络拓扑图。

frida安装过程省略,网上有很多教程可以参考。
frida中有两种操作模式,分别是CLI模式和RPC模式
frida有两种注入模式,分别是Spawn和Attach
-f,可以对从启动就开始对App进行监控。相关的api可以在官网上查看官方文档Welcome | Frida • A world-class dynamic instrumentation toolkit
给出一个python的框架代码:
1 | |
Java层hook示例代码:
1 | |
hook重载参数:
1 | |
hook字段修改:
1 | |
对内部类进行hook
1 | |
静态方法主动调用
1 | |
非静态方法主动调用
1 | |
枚举so库
1 | |
hook函数
1 | |
这里有一个偏移值的计算,安卓里一般32 位的 so 中都是thumb指令,64 位的 so 中都是arm指令,通过IDA里的opcode bytes来判断,arm 指令为 4 个字节(options -> general -> Number of opcode bytes (non-graph) 输入4)
ida的话就是纯看代码环节了,说几个小技巧吧。
首先就是尽量不要从导出表中反过来找函数,因为有一部分导出表对应的函数是fastcall类型,只观察函数内部有时ida无法将参数识别出来,导致后来再去找函数的调用处时代码都是乱的。
ida有一键生成frida的插件,P4nda0s/IDAFrida: IDA Frida Plugin for tracing something interesting. (github.com)和AnxiangLemon/MyIdaFrida: Generate Frida Script (github.com),可以直接从ida中生成frida的hook脚本,比较方便(虽然我没用过几次)
关于漏洞细节就不发出来了。历时2个多月的零基础从入门到入土,确实学到了不少东西,也踩了一大堆坑,有的坑也卡的比较久,在此感谢w学长给我一步步梳理思路。