Android逆向实战:SSLPining处理
今天来逆向一个开启了 SSL Pining 的 APP。
APP4
APP4 地址:https://app4.scrape.center/
APP4 说明:
设置了 SSL Pining,如果设置了非法证书则无法正常请求数据,适合做反 SSL Pining 处理。
先安装 APP 看看:
打开直接会报错,证书校验失败,因为检测到了非法证书,所以报错了。但是我们提前知道了这是由于设置了 SSL Pining,所以直接从这里入手。
证书异常
通过错误日志,一点点的往上找调用链路,我们可以找到请求的位置,可以看到请求的位置和函数基本上没有什么变化。
SSL Pining 位置
现在的问题是如何找到是哪里设置了 SSL Pining 呢?那肯定是从 okhttp 的 client
初始化入手,我们看到数据请求函数的时候,client
肯定已经初始化完成了,那我们顺着请求的位置继续往上找,找 client
初始化的地方,肯定通过某种方式设置了 SSL Pining,我们来找一下。
这里是一个单例的 http 数据源类,通过私有构造器的方式保证单例,并且暴露 getInstance
接口给外界调用,用来初始化当前类的实例,继续找当前类的引用位置。
发现这里引用到了,并且上面的 RetrofitClient
类调用了 getInstance
方法获取实例,大概率 client
就是在这里初始化的,初始化之后调用 create
函数来创建 MovieService
类的实例。
查看 client
类,我们发现了请求的地址,私有化的构造器,还有一个很可疑的地方就是这里通过 new
关键字创建了一个 CertificatePinner
的 Builder
类的实例,并且添加了一个域名的哈希值进去,大概率这里就是我们要找的位置了,哈希值应该是这个域名的证书的公钥的哈希值了。
SSL Pining 原理
原理就是将域名的公钥的哈希值固定在代码中,也就是说如果客户端收到的证书的公钥的哈希值和代码中的哈希值不相等的话,就会报错,也就达到目的了。
找到了对应的哈希值,我们看看 add
函数实际做了哪些事情。
发现它将传入的参数添加到了 pins
这个变量中,那既然它是通过添加证书哈希值的方式来实现的话,应该如何解决呢?
解除 SSL Pining
有两个方案:
- 我们可以不让它生效,让
add
函数不去添加哈希值。 - 让它实际传入的哈希值是我们的抓包软件的哈希值,来一手狸猫换太子。
我们这里使用第一种方案试试,那怎么能不让它生效呢?这就要说到 Hook
大法了,Android 中 Hook
有两种方式,一种是通过 XP
框架的方式,写 Java
代码来实现 Hook
,另一种就是使用 Frida
,写 JS 代码来实现。
Frida 环境准备
我这里使用 Frida
,它和 XP
框架的区别就是 Frida
是动态的,我可以随时修改 Hook
代码,而不用重新编译。
使用 Frida
需要先配置环境,首先 Android 手机需要安装 Magisk
框架,并且安装 MagiskFrida
模块,它可以在开机之后自动启动 Frida
客户端,不用我们在使用命令行启动了。还有这里推荐一个好用的模块,MoveCertificate
,它可以自动将我们安装的用户凭证自动复制到系统凭证中去,无需我们手动将证书安装到系统信任区了。因为 Android7
以后安装到用户凭证中的证书已经不会被系统信任了,所以要想正常抓包,只能将证书安装到系统的信任区。
当然了,以上的一些前提都是:手机需要有 root
权限。
手机环境搞定了,再来配置 Python
和 nodejs
环境。这里我们需要安装两个 Python
依赖包:frida
和 frida-tools
,还有一个 nodejs
依赖包:@types/frida-gum
。
Python
的两个依赖是为了通过 Python
连接手机上的 Frida
服务端,并且将 JS
代码注入到 APP 中去运行。nodejs
的依赖包是为了能更好的编写 Frida
的 JS
代码,它能提供类型提示,不用我们再记那么多函数了。
好了,到了这里环境基本上准备好了,接下来开始见证奇迹!
开始调试
新建一个 code
文件,写入以下代码:
1 | Java.perform(function () { |
然后再找到 APP4 的包名,可以从反编译工具中找到,位置在这里:
接下来,运行以下命令:
1 | frida -U -f com.goldze.mvvmhabit -l code.js |
上面的命令含义是:使用 Frida
启动 APP4,并且将 code.js
的代码注入到 APP 中并且运行,JS
代码含义是获取到 okhttp
中的 CertificatePinner$Builder
这个类,覆盖掉它的 add
方法,并且在打印日志后就直接返回,不调用原有的 add
方法,这样就可以将 add
方法置空,也就是说调用 add
方法实际没有任何作用,也就解除了 SSL Pining,或者说相当于没有设置 SSL Pining。
运行以后,控制台应该会输出以下日志:
可以看到,我们成功的输出了 add
方法的参数值,并且手机上的 APP4 会被自动打开,这个时候我们再看看,已经不会提示证书异常了,而是可以正常返回请求的数据了,大功告成!
如果想要更改 add
方法的参数,也可以在这里做手脚,在实际调用 add
函数的时候动态的将传入的哈希值换成我们自己的就可以了,大家感兴趣的可以自己试一下。
最终代码详见:https://github.com/libra146/learnscrapy/tree/main/Android/APP4
总结
SSL Pining 就这样被我们解决了,是不是很神奇,这里面涉及到了很多其他的知识,一篇文章是写不完的,如果有问题,欢迎大家在评论区留言,最好是自己动手操作一遍,可以加深自己的 Frida
使用的理解。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!