0x00 示例文件
本文部分参考该文章:Bypassing SSL Pinning on Android via Reverse Engineering,以SSLPinningExample为例讲解如何篡改APK以及绕过SSL Pinning。关于SSL Pinning可以参见Your app shouldn't suffer SSL's problems。
首先,作为准备工作,我们要下载本次的实验对象:SSLPinningExample。该APK是一个简单的请求github首页的app,但是在它内部对证书进行了测试,如果发现请求目标网站提供的证书不是github的官方证书,则无法获取github首页。
0x01 修复示例文件
刚开始我们直接安装这个APK试试,结果发现竟然无法获取github首页,看一下logcat打的log:javax.net.ssl.SSLPeerUnverifiedException: No peer certificate,是证书出了问题。仔细想了一下,应该是因为这个APK发布的时间太早了,github的证书应该已经变动过了,APK内藏的证书pin不管用了。所以我们第一步是要把这个APK给修复了。
解压APK,发现证书的pin(keystore)在res/raw目录下的keystore.bks里,该keystore.bks失效了,我们要重新生成一个bks类型的keystore。
- 用chrome上github首页,点击地址栏左边的绿色小锁,点击证书信息->详细tab->复制文件->导出为Base 64 encoded X.509 (.CER)(S),导出的文件命名为github.cer。该.cer文件其实与.pem文件的格式是一样的,可以将其直接改名为github.pem。
-
从pem文件制作bks文件:我们需要两个工具,keytool和Bouncy Castle。keytool本身在jdk的bin目录自带,把jdk的bin目录加入到环境变量里即可使用。而bcprov-jdk15on-1.54.jar需要下载。之后就可以输入命令了:
keytool -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath ./bcprov-jdk15on-1.54.jar -storetype BKS -keystore keystore.bks -importcert -v -trustcacerts -file ./github.pem -alias hax
- 把生成的keystore.bks拷贝到res/raw目录下,覆盖原来的keystore文件。
-
用
java -jar apktool_2.1.0.jar b ./SSLPinningExample/ -o ./SSLPinningExample.unsigned.apk
将修改好的文件打包成APK。
-
给APK签名:
首先用openssl生成一个自我声明的证书:
openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -out request.pem
openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocryptwindows上可以在这里下载openssl,安装好后将bin添加到环境变量里即可使用。
然后下载SignApk,使用命令
java -jar SignApk.jar ./certificate.pem ./key.pk8 ./SSLPinningExample.unsigned.apk ./SSLPinningExample.signed.apk
即可。注意,该github上还提供了一个sign.jar,使用该jar的话可以更简单的给APK签名,因为该jar里内置了测试用的证书文件。
-
安装APK,发现可以成功请求github首页了。