记一次零基础IOT设备与app交互0day漏洞挖掘学习经历
基础知识
apk结构
apk是对一个安卓应用程序所需要的文件进行打包,本质上是一个被签名的压缩包。
通常情况下,apk会含有以下文件:
- asset文件夹:是不需编译的原始资源目录,包含各种静态的资源,如各种配置文件、JavaScript、字体文件、图片文件等。
- lib文件夹:动态链接库存放的位置,通常情况下,这个文件夹内部以不同处理器版本还会划分成多个文件夹,如armeabi、armeabi-v7a、x86等,其存放的文件通常为Android Native的代码。
- META-INF文件夹:用来存放签名信息,通常会有CERT.RSA、CERT.SF和MANIFEST.MF三个文件。是用来保护apk的所有权和防止apk被恶意篡改。
- r文件夹/res文件夹:存放编译资源文件,与asset文件夹相似,区别是其存放的文件是编译后的。通常会包含drawable 文件夹(图片资源文件)、layout 文件夹(布局文件)和values 文件夹(值资源文件)等。r文件夹通常是res文件夹进行混淆后的结果。
- AndroidManifest.xml文件:apk的整体配置文件,其中包含了一个apk的各种配置信息,包括包名、应用名、权限、安卓四大组件、版本等重要信息。
- dex文件:存放字节码的文件,其反汇编后为smali语言,可转化为Java代码,通常dex文件包含一个apk的主要逻辑。
- resources.arsc文件:用来存放应用程序的资源表,包含了应用程序的资源 ID 和资源类型的映射关系。
使用工具
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
环境搭建
获取手机Root权限
本次使用的手机是一台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+iptables搭建中间人代理
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进行hook
frida安装过程省略,网上有很多教程可以参考。
frida中有两种操作模式,分别是CLI模式和RPC模式
- CLI(命令行)模式:通过命令行直接将JavaScript脚本注入进程中,对进程进行操作
- RPC模式:使用Python进行JavaScript脚本的注入工作,实际对进程进行操作的还是JavaScript脚本,可以通过RPC传输给Python脚本来进行复杂数据的处理
frida有两种注入模式,分别是Spawn和Attach
- Spawn模式:将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App。在命令行模式中需要加入参数
-f
,可以对从启动就开始对App进行监控。 - Attach模式:在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作。如果只关心一个功能时通常会用这种模式。
相关的api可以在官网上查看官方文档Welcome | Frida • A world-class dynamic instrumentation toolkit
给出一个python的框架代码:
1 |
|
Java层hook
Java层hook示例代码:
1 |
|
hook重载参数:
1 |
|
hook字段修改:
1 |
|
对内部类进行hook
1 |
|
静态方法主动调用
1 |
|
非静态方法主动调用
1 |
|
Native层hook
枚举so库
1 |
|
hook函数
1 |
|
这里有一个偏移值的计算,安卓里一般32 位的 so 中都是thumb
指令,64 位的 so 中都是arm
指令,通过IDA里的opcode bytes来判断,arm 指令为 4 个字节(options -> general -> Number of opcode bytes (non-graph) 输入4)
- thumb 指令,函数地址计算方式: so 基址 + 函数在 so 中的偏移 + 1
- arm 指令,函数地址计算方式: so 基址 + 函数在 so 中的偏移
IDA对so库逆向
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学长给我一步步梳理思路。