APK篡改以及SSL Pinning绕过

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。

  1. 用chrome上github首页,点击地址栏左边的绿色小锁,点击证书信息->详细tab->复制文件->导出为Base 64 encoded X.509 (.CER)(S),导出的文件命名为github.cer。该.cer文件其实与.pem文件的格式是一样的,可以将其直接改名为github.pem。

  2. 从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

  3. 把生成的keystore.bks拷贝到res/raw目录下,覆盖原来的keystore文件。

  4. java -jar apktool_2.1.0.jar b ./SSLPinningExample/ -o ./SSLPinningExample.unsigned.apk

    将修改好的文件打包成APK。

  5. 给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 -nocrypt

    windows上可以在这里下载openssl,安装好后将bin添加到环境变量里即可使用。

    然后下载SignApk,使用命令

    java -jar SignApk.jar ./certificate.pem ./key.pk8 ./SSLPinningExample.unsigned.apk ./SSLPinningExample.signed.apk

    即可。注意,该github上还提供了一个sign.jar,使用该jar的话可以更简单的给APK签名,因为该jar里内置了测试用的证书文件。

  6. 安装APK,发现可以成功请求github首页了。