Android平台HTTPS抓包全方案( 三 )


案例1:

https://github.com/PAGalaxyLab/VirtualHook
案例2:
https://github.com/rk700/CertUnpinning
不过,这里CertUnpinning插件的代码有点问题,要改改 。
导入真正的公钥证书和私钥如果Client固定了公钥证书,那么MITM Server必须持有真正的公钥证书和匹配的私钥 。如果开发者具有真正服务端的公钥证书和私钥,(比如百度的公钥证书和私钥百度的后端开发肯定有),如果真有的话,可以将其导入HttpCanary中,也可以完成正常抓包 。
在设置 -> SSL证书设置 -> 管理SSL导入证书 中,切换到服务端,然后导入公钥证书+私钥,支持.p12和.bks格式文件 。
/ 双向认证 /
SSL/TLS协议提供了双向认证的功能,即除了Client需要校验Server的真实性,Server也需要校验Client的真实性 。这种情况,一般比较少,但是还是有部分应用是开启了双向认证的 。比如匿名社交应用Soul部分接口就使用了双向认证 。使用了双向认证的HTTPS请求,同样无法直接抓包 。
关于双向认证的原理
首先,双向认证需要Server支持,Client必须内置一套公钥证书 + 私钥 。在SSL/TLS握手过程中,Server端会向Client端请求证书,Client端必须将内置的公钥证书发给Server,Server验证公钥证书的真实性 。
注意,这里的内置的公钥证书有区别于前面第5点的公钥证书固定,双向认证内置的公钥证书+私钥是额外的一套,不同于证书固定内置的公钥证书 。
如果一个Client既使用证书固定,又使用双向认证,那么Client端应该内置一套公钥证书 + 一套公钥证书和私钥 。第一套与Server端的公钥证书相同,用于Client端系统校验与Server发来的证书是否相同,即证书固定;第二套SSL/TLS握手时公钥证书发给Server端,Server端进行签名校验,即双向认证 。
用于双向认证的公钥证书和私钥代表了Client端身份,所以其是隐秘的,一般都是用.p12或者.bks文件+密钥进行存放 。由于是内置在Client中,存储的密钥一般也是写死在Client代码中,有些App为了防反编译会将密钥写到so库中,比如S匿名社交App,但是只要存在于Client端中都是有办法提取出来的 。
双向认证抓包这里以S匿名社交App为例,讲解下如何抓取使用了双向认证的App的HTTPS包 。如果服务器使用了Nginx且开启了双向认证,抓包时会出现400 Bad Request的错误,如下:
Android平台HTTPS抓包全方案

文章插图
 

Android平台HTTPS抓包全方案

文章插图
 
有些服务器可能不会返回404,直接请求失败 。接下来看,如何使用HttpCanary配置双向认证抓包 。
首先,解压APK,提取出.p12或者.bks文件,二进制的文件一般存放都在raw或者assets目录 。
Android平台HTTPS抓包全方案

文章插图
 
将client.p12文件导入手机,然后在HttpCanary的设置 -> SSL证书设置 -> 管理SSL导入证书中,切换到客户端(因为需要配给MITM Client),然后导入.p12文件 。
由于双向认证的公钥证书和私钥是受密钥保护的,所以需要输入密码:
Android平台HTTPS抓包全方案

文章插图
 
一般通过逆向可以从APK中提取出密钥,具体操作这里略过 。输入密钥后,需要输入映射域名,这里使用通配符*映射所有相关域名:
Android平台HTTPS抓包全方案

文章插图
 
导入完成后如下:
Android平台HTTPS抓包全方案

文章插图
 
可以点进证书详情查看细节,这个client.p12文件包含公钥证书和私钥,是用于双向认证的 。
Android平台HTTPS抓包全方案

文章插图
 
配置完成后,重新进行抓包,看看效果 。
Android平台HTTPS抓包全方案

文章插图
 
可以看到,之前400 Bad Request的两个要求双向认证的请求成功了!
/ SSL重协商 /
有些服务器可能会开启SSL重协商,即SSL/TLS握手成功后发送请求时服务器会要求重新握手 。这种情况一般比较少,但是也不排除,已知的应用比如 10000社区 就使用了SSL重协商 。
由于Android系统对SSL重协商是有限支持,所以部分系统版本抓包会失败,表现为网络异常 。在Android 8.1以下,SslSocket是完全支持SSL重协商的,但是SSLEngine却是不支持SSL重协商的,而HttpCanary解析SSL/TLS使用的是SSLEngine 。在Android 8.1及以上,SSLEngine和SslSocket统一了实现,故是支持SSL重协商的 。


推荐阅读