Android应用中https SSL pinning以及绕过的方法介绍
1. SSL简介
SSL(安全套接字层)又被称为TLS(数据层安全协议),是一种为网络通信提供数据完整性的一种安全协议。它位于TCP/IP协议与各种应用协议之间。SSL协议主要分为两个部分: Handshake Protocol 和 Record Protocol 。
Handshake protocol是用来协商加密通信数据的密钥,Record Protocol定义传输内容的格式。想了解handshake Protocol以及Record protocol的具体细节可以自己去查阅资料,这里就不详细介绍了。
2. SSL pinning
首先介绍一下证书相关的概念,以及证书校验的相关知识:
可信CA:
CA(Certificate Authority)是数字证书认证中心的简称,是指发放、管理、废除数字证书的机构。CA的作用是检查证书持有者身份的合法性,并签发证书,以防证书被伪造或篡改,以及对证书和密钥进行管理。
双向锁定 :
在客户端锁定服务端证书的基础上,服务端对客户端的证书也进行锁定,需要客户端再做一次证书预埋。多见于金融业务。
证书链:
证书链就是Root CA签发二级Intermediate CA,二级Intermediate CA可以签发三级Intermediate CA,也可以直接签发用户证书。从Root CA到用户证书之间构成了一个信任链:信任Root CA,就应该信任它所信任的二级Intermediate CA,从而就应该信任三级Intermediate CA直至信任用户证书。
逐级验证 :
客户端对于收到的多级证书,需要从站点证书(leaf certificate)开始逐级验证,直至出现操作系统或浏览器内置的受信任CA 根证书(root certificate)。
SSL Pinning技术指的是在应用程序中只信任固定证书或是公钥。应用程序开发人员在程序中使用SSL pinning技术作为应用流量的附加安全层。实现SSL pinning的方法主要有两种:
证书固定 :开发者将SSL证书的某些字节码硬编码在用程序中。当应用程序与服务器通信时,它将检查证书中是否存在相同的字节码。如果存在,则应用程序将请求发送到服务器。如果字节码不匹配,它将抛出SSL证书错误。此技术可防止攻击者使用自己的自签名证书。
公钥固定 :在客户访问网站时进行公钥固定中,服务器将其公钥固定(通过注入)在客户端(客户)浏览器中。当客户端重新访问同一网站时,服务器将标识其公共密钥以检查连接的完整性。此技术还可以防止攻击者使用他/她的自签名证书。
3. SSL pinning的作用
通常我们在测试一个应用的时候会设置代理,从而获取应用在运行过程中的流量。我们使用代理工具获取流量的话,需要在设备中安装我们自己的证书到可信任的根证书中,这样应用程序才会将我们的证书视为可信任的有效证书,允许代理工具拦截应用的流量。但是使用的SSL pinning技术的应用程序,只信任指定的证书,那么我们就算把我们的证书安装到设备中,应用程序也不会信任我们的证书,这样的话我们就不能通过代理的方式来拦截应用的流量了。
4. SSL pinning的实现
在Android应用中常用的几种https实现方式以及如何进行SSL pinning:
4.1 通过OKhttp来实现
1.使用CertificatePinner来进行证书的锁定,具体代码实现如下图所示:
2. 自定义证书和重写HostnameVerify类中的verify方法,默认的话是信任所有的域名。
4.2 通过Apache的HttpClient来实现
1.通过在 APK 中内置的证书初始化一个KeyStore,然后用这个KeyStore去引导:
2.自定义 SSLSocketFactory实现,在TrustManager校验策略中重写checkClientTrusted和checkServerTrusted方法,如果不进行重写的话,默认就是信任所有证书。实现代码如下:
4.3 通过HttpsURLConnection来实现
HttpsURLConnection的实现和Apache的HttpClient基本相同,所以就不多介绍了,只粘贴两张实现位置的代码图:
4.4 WebView 加载 Https 页面时的证书校验
Android应用中通过WebView加载https页面时,如果出现证书校验错误,则会调用框架层的onReceivedSSLError方法。
5. 常用SSLpinning绕过方法以及原理介绍
在前面我们已经介绍了SSL pinning的原理以及具体的实现,那么我们想要绕过SSL pinning的话,只需要将证书校验的过程绕过就可以。那么我们可以通过hook的方式来修改证书校验过程,这样就能成功的绕过SSL pinning了。
本人常用且比较熟悉的hook工具有两种,分别是 frida 和 Xposed ,这两种工具中都有hook所有https证书校验方法的模块。
其中我使用的比较多的是基于Xposed框架下的Justtrustme模块。该模块对上述所说的https实现证书校验的过程都添加了hook代码,至于具体代码细节我这里就不详细说明了,感兴趣的话可以自己去查看源码,源码地址: https:// github.com/Fuzion24/Jus tTrustMe
6. JustTrustMe模块的局限性
虽然说我们可以使用HOOK的方式去修改证书校验的结果,但是开发人员也可以使用代码混淆的办法来对抗hook。开发人员只需要将书校验的那部分代码混淆,就能够防止通用的SSL unpinning方法。这时候我们就只能反编译代码,自己去寻找代码中进行证书校验的位置,然后自己编写hook代码去进行SSL pinning的绕过。
参考资料
· 《justtrustme原理分析》- 看雪论坛
https:// bbs.pediy.com/thread-21 4012.htm
· 《SSL Pinning Practice》- 先知社区
https:// xz.aliyun.com/t/2440
·《 JustTrustme》- github
https:// github.com/Fuzion24/Jus tTrustMe