对app的反爬测试之apk逆向分析-frida绕过sslpinning检测
前⾔:
受⼈所托,需要对他们的产品进⾏反爬测试,所以就有了以下内容。
不过,我知道,针对这⽅⾯的⽂章太多了,是真的多,⽽且好早就有了,但是⽬前为⽌,很多app的防护基本也还是⽤的ssl pinning检测证书。
因为,⽬前的app要嘛不⽤ssl,要嘛⽤就是⼀般的ssl,基本就是在⼿机上装个相关软件的代理即可,⽽且这个代理基本就是fiddler,charlels,burpsuite,mitmproxy(Python环境下的)四个抓包软件⾃带的ssl证书,然后即可抓到ssl(https)的请求
以上这些,基本可以解决⼤部分的app(其实很多使⽤ssl的⽹站也是这样处理)
但是因为很多app为了防⽌数据被分析爬取,会做ssl pinning验证
> ssl painning
SSL Pinning是⼀种防⽌中间⼈攻击(MITM)的技术,主要机制是在客户端发起请求–>收到服务器发来的证书进⾏校验,如果收到的证书不被客户端信任,就直接断开连接不继续求情。
所以在遇到对关键请求开启SSL Pinning的APP时,我们抓包就只能看到APP上提⽰⽆法连接⽹络或者请求失败之类的提⽰;⽽在抓包⼯具上⾯,要么就只能看
到⼀排 CONNECT 请求,获取到证书却没有后续了,要么就是⼀些⽆关的请求,不到想要的接⼝
⽐如如下图:
针对这种,如果是web⽹站,我们都知道,在本地装下抓包软件⾃带的ssl证书就⾏了,但是app的话,如此操作之后还是不⾏,⽽且app还会提⽰没⽹(⽐如:⽹络连接失败,⽹络有问题等等的),反正意思就是没⽹的意思,这种就是因为app⾃⾝做了ssl pinning验证处理,验证下当前的ssl证书是否是合法允许的,如果不是就会验证失败
其实使⽤ssl pinning⽬前已经成为了趋势,那么我们的⽬前对象刚好就有这个怎么办呢?
⽬前根据我的经验,最有效的有三个⽅法:
1.使⽤低版本的安卓机抓包
2.使⽤ios端⼿机抓包
3.使⽤frida绕过证书处理
> 使⽤低版本的安卓机抓包
因为app的话,⽬前主流的都是⽤的前后端分离开发,所以越到后期,app更新新版后,越会有不同版本的后端接⼝存在,⽽且新版接⼝和⽼版接⼝其实返回的数据差异性很⼩,并且有个关键点就是,为了兼容性,会依旧留下旧版接⼝,因为每个⽤户使⽤的⼿机不⼀样,安卓或者ios版本不同,系统版本也就会不同,且⽼款⼿机因为内存太⼩,不会更新新版的app包,种种情况下来,结果就是会留下旧版接⼝,⽽且这个旧版接⼝安全性⽐新版低很多,所以可以⽤低版本的饿安卓机来抓包,就正常的抓包流程即可,不出意外的话,可能还⽤的普通的http请求。
为什么⾼版本的安卓就抓不到包呢,因为⾼版本的(安卓7以上)开始,安卓⾃带了⼀些安全机制,本质上就是只信任系统证书,不再信任⽤户⾃⼰安装的证书了,我们装的ssl 代理证书就是⾃⼰装的,所以就会验证不通过了
> 使⽤ios端⼿机抓包
这个情况真的很多,因为,苹果端的appstore管理得很严,不能加些⾃⼰独特的东西,但是加ssl是可以的,但是很多app并没有加我就不知道了,这个情况就很简单,需要⼀台iphone,其他都是正常抓包操作,然后安装证书,把证书信任下就⾏了,详细的操作就不说了,⽹上很多教程
> 使⽤frida绕过证书处理
这个⽅法就是本篇⽂章的重点了,这个放到后⾯再说
> 其他⽅法
其实也有其他的⽅法,这些⽅法并不是通⽤的,可能运⽓好可以⽤,运⽓不好就没⽤:
>> 安卓模拟器
⽤安卓模拟器,模拟低版本安卓然后抓包
>> 对证书信任,修改APP设置
看这个app是否是⾃有app,如果是⾃有的,⾕歌有debug模式,该模式下让app默认可以信任⽤户域的证书(trust-anchors),如果是⾮⾃有,⽤xposed+JustTrustMe即可,但是使⽤Xposed框架需要root,⽹上那些魔改⼩功能,什么⾃动抢红包,防消息撤回之类的就是⽤的xposed框架改的,⽤JustTrustMe来信任⽤户安装的证书
⽬前市⾯上有VitualXposed、太极等虚拟的框架,不⽤root也可以操作,太极这个软件挺好的,有太极-阴(免root)和太极-阳(需要root),两个版本都可以⽤,但是针对有些app的话,太极-阴没戏,只能太极-阳,但是既然我都已经root了,我就没必要整这些了。
>> 强制信任证书
具体步骤:
1.charles导出.pem证书,选择.prm类型保存在pc上
2.修改证书名称
系统证书⽬录:/system/etc/security/cacerts/
其中的每个证书的命名规则如下:
<Certificate_Hash>.
⽂件名是⼀个Hash值,⽽后缀是⼀个数字。
⽂件名可以⽤下⾯的命令计算出来:
openssl x509 -subject_hash_old -in <Certificate_File>
后缀名的数字是为了防⽌⽂件名冲突的,⽐如如果两个证书算出的Hash值是⼀样的话,那么⼀个证书的后缀名数字可以设置成0,⽽另⼀个证书的后缀名数字可以设置成1
3. ⽤adb命令把证书推到⼿机上
adb push xxxxxxx.0 /sdcard/
4.复制到系统⽬录并修改权限(安卓8.1.0 Magisk Root)
mount -o rw,remount /system 【不修改没法写⼊】
mount -o rw,remount /
mv /sdcard/xxxxxxx.0 /etc/security/cacerts/ 移动⽂件到系统
chown root:root /etc/security/cacerts/fc365f9d.0 修改⽤户组
chmod 644 /system/etc/security/cacerts/xxxxxxx.0 修改权限
5. 重启⼿机验证即可
这时你就发现证书已经在系统级别⾥了
6.进⾏抓包
补充:
这个是安卓端的抓包⼯具,⽹上吹得很⽕,根据我(我⼿机是安卓10)亲⾃操作,发现其实没有⽤,也不知道是不是我的姿势错误,或者我⼿机安卓系统版本太⾼了失效
⽤这个可以免root操作,然后正常抓包,但是这个⽅法我没有实际操作过,⽹上的资料不多,⾃⾏查
Xposed 是⼀款 Android 端的 Hook ⼯具,利⽤它我们可以 Hook App ⾥⾯的关键⽅法的执⾏逻辑,绕过 HTTPS 的证书校验过程。JustTrustMe 是基于 Xposed ⼀个插件,它可以将 HTTPS 证书校验的部分进⾏ Hook,改写其中的证书校验逻辑,这种思路是属于第⼆种绕过 HTTPS 证书校验的解决⽅案。
当然基于 Xposed 的类似插件也有很多,如 SSLKiller、sslunpining 等等,可以⾃⾏搜索。
不过 Xposed 的安装必须要 ROOT,如果不想 ROOT 的话,可以使⽤后⽂介绍的 VirtualXposed。
Xposed 的使⽤需要 ROOT,如果不想 ROOT 的话,可以直接使⽤⼀款基于 VirtualApp 开发的 VirtualXposed ⼯具,它提供了⼀个虚拟环境,内置了 Xposed。我们只需要将想要的软件安装到 VirtualXposed ⾥⾯就能使⽤ Xposed 的功能了,然后配合 JustTrustMe 插件也能解决 SSL Pining 的问题,这种思路是属于第⼆种绕过 HTTPS 证书校验的解决⽅案。
>> 特殊改写
其实本质上是对⼀些关键的校验⽅法进⾏了 Hook 和改写,去除了⼀些校验逻辑。但是对于⼀些代码混
淆后的 App 来说,其校验 HTTPS 证书的⽅法名直接变了,那么JustTrustMe 这样的插件就⽆法 Hook 这些⽅法,因此也就⽆效了。
>> 强制全局代理
⼿机root后,使⽤proxy Droid 实现强制全局代理,让ssl代理证书⽣效,proxy Droid可以在UpToDown,ApkHere等的地⽅下载
抓包
免root,在安卓机上安装packet capture,然后抓包,我试了下,我的⼿机(我⼿机是安卓10)没⽤
>> 魔改JustTrustMe
在JustTrustMe插件上增加⼀个可以运⾏时根据实际情况调整ssl检测的功能,对hook增加动态适配,这个⽅法我没试过,我在看雪论坛⾥到⼀个 JustTrustMePlus,
>> 反编译app包
⽤apktools修改配置⽂件⾥的ssl证书检测部分,可利⽤jadx等⼯具分析源码,然后重新打包,再抓包分析,这个⽅法是可⾏的,详细的步骤⾃⾏百度吧,后续有时间的话,我单独发⼀篇对app的脱壳重新打包
java模拟器安卓
处理
这个⼯具的原理就是把⼀个安卓机在本地作为⼀台服务器,然后到数据接⼝,这个⽅法没有亲测过,更多的适⽤于获取app的sign/token时去获取接⼝
以上的⽅法就是我所知道的⽅法,各位朋友⾃⾏操作
接下来进⼊正题,frida hook
什么是frida
Frida是个轻量级别的hook框架,是Python API,⽤JavaScript调试来逻辑
Frida的核⼼是⽤C编写的,并将注⼊到⽬标进程中,在这些进程中,JS可以完全访问内存,挂钩函数甚⾄调⽤进程内的本机函数来执⾏。
使⽤Python和JS可以使⽤⽆风险的API进⾏快速开发。Frida可以帮助您轻松捕获JS中的错误并为您提供异常⽽不是崩溃。
frida是平台原⽣app的Greasemonkey,说的专业⼀点,就是⼀种动态插桩⼯具,可以插⼊⼀些代码到原⽣app的内存空间去,(动态地监视和修改其⾏为),这些原⽣平台可以是Win、Mac、Linux、Android或者iOS。⽽且frida还是开源的。
Greasemonkey可能⼤家不明⽩,它其实就是firefox的⼀套插件体系,使⽤它编写的脚本可以直接改变firefox对⽹页的编排⽅式,实现想要的任何功能。⽽且这套插件还是外挂的,⾮常灵活机动。
frida框架主要分为两部分:
1)⼀部分是运⾏在系统上的交互⼯具frida CLI。
2)另⼀部分是运⾏在⽬标机器上的代码注⼊⼯具 frida-server
注:以下相关操作,终端⾥凡是 C:\Users\Administrator 开头的都是在pc机上操作的,需要在安卓机⽬录⾥操作的我都有说明,不要搞混了
环境准备
> 安装frida
没有python的安装python,然后安装frida:
pip  install frida
pip install frida-tools
安装过程很慢,这个只能耐⼼等待,然后如果你是macbook的话,如果你遇到安装出错,可以看看我这篇⽂章的解决⽅法
然后frida是mac,linux,windows都可以安装使⽤的,这个根据你⾃⼰的条件选择了
> 安装adb
这个就很简单,去然后下载这个⼯具:
如果你下载太慢可以在我这⾥下载:
下载完毕后,解压,然后放到你想放的路径,然后配置下环境变量即可,此电脑(我的电脑)- 属性-⾼级系统设置-环境变量-系统变量的path,新增即可
然后,打开终端:
敲adb,回车,如果有以下提⽰,说明你adb安装成功
以上配置是windows平台,如果是其他平台的话,⾃⾏查,这⾥就不展⽰了
> ⼀个安卓机(已root)
根据现在的⾏情,要到⼀个已root的⼿机,问题不⼤也不⼩,但是很多时候没有必要,所以我这⾥就选择⽤安卓模拟器来辅助操作了
安装夜神模拟器,夜神默认是安卓5,你可以⾃⾏选择安卓版本,在夜神⾥设置已root即可
> 打开开发者选项⾥的USB调试
设置⾥⾯,关于本机,然后狂点系统版本号,开启开发者模式:
返回,会多⼀个开发者选项:
打开调试
> adb连接安卓机(模拟器)
在安装了frida和adb的真机操作系统下,打开终端,⽤ adb connect IP 连接安卓机:
夜神的ip是127.0.0.1:62001,这⾥注意,如果你创建了多个安卓系统的话,那么你待连接的安卓机不⼀定是62001,可能是其他的,可以在安装⽬录⾥⾯
进⼊后,nox.vbox⽂件
⽤⽂本编辑器打开,搜索5555就能看到是哪个端⼝了,为什么必须是5555端⼝呢,因为5555就是模拟器挂载在我们windows真机上的端⼝