最近写Pixeval的时候部分功能需要抓包,发现现在的Android不好抓了,首要的问题就是Pixiv本身不信任Fiddler的证书,结果就是如果在Fiddler上开启了Decrypt HTTPS Traffics那么Pixiv的流量就只会显示SSL handshake成功,而请求本身则会因为证书校验失败而失败,在Fiddler的Log里可以看到相应的请求失败异常信息:

!SecureClientPipeDirect failed:
System.Security.Authentication.AuthenticationException
A call to SSPI failed, see inner exception.
< An unknown error occurred while processing the certificate for pipe
(CN=<host>, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com).

解决这个问题首先要知道他的来源,这个问题来自Certificate Pinning,是一种安全机制,大意是让应用程序只去接受一个特定的证书或由该证书所颁发的证书,这样的话即便你把Fiddler的证书加入了CA,让系统信任了,但是由于应用使用Certificate Pinning,因此依然不会信任该证书。
  面对该问题,我所知道的解决方法有两种,第一种是在Fiddler的设置里取消勾选Decrypt HTTPS Traffics,但是这样显然是属于“解决提出问题的那个人”这种类型的方式,因为取消勾选之后也就完全起不到抓包的作用了。第二种方法就是把apk拆开,然后通过修改一些文件来达到这个目的
  在介绍第二种方法以前,需要知道Android的应用清单文件AndroidManifest.xml中的<application>项有一个叫做android:networkSecurityConfig的属性,这个属性指向文件res/xml/network_security_config.xml,而这个文件里配置了该Android项目的网络安全相关信息,其中有一栏叫做<debug-overrides>1,我们可以在这一栏里指定调试模式下应用信任的证书库,也就是说,我们可以在这下面把FiddlerRoot.cer所属的user证书库加入到应用的信任证书库中。
  当然,在上述描述中有一个很明显的问题就是调试模式,默认状态下应用是不会处于调试模式的,我们需要回到AndroidManifest.xml文件中,在<application>一栏添加属性android:debuggable="true"2,才可以开启调试模式。

解决方法:

  1. 首先获取Pixiv最新的apk文件,可以前往apkmirror或者自行把手机上的应用分享给电脑
  2. 下载apktool,打开控制台并且cdapktool所在的目录,输入命令
    .\apktool.bat d pixiv.apk
    

    这会在同目录下生成一个`pixiv`文件夹,里面包含了解包后的内容,接着删除掉这个`pixiv.apk`,我们已经用不到它了

  3. 定位到pixiv/res/xml文件夹,打开network_security_config.xml文件,在<network-security-config>一栏,加上如下内容
    <debug-overrides>
          <trust-anchors>
              <certificates src="system"/>
              <certificates src="user"/>
          </trust-anchors>
      </debug-overrides>
      
  4. 回到pixiv文件夹,打开AndroidManifest.xml文件,在<application>一栏加入android:debuggable="true"
  5. 此时要做的修改都完成了,键入命令
    .\apktool.bat b pixiv -o pixiv.apk
    

    这会把`pixiv`文件夹中的内容重新打包到`pixiv.apk`中,接着需要对该压缩包进行签名,输入命令

    keytool -genkey -v -keystore my-pixiv.keystore -alias pixiv-key -keyalg RSA -keysize 2048 -validity 10000
    

    来生成一个`keystore`,注意该命令使用到了JDK的`bin`目录下的工具`keytool.jar`,使用该命令之前需要先安装JDK

  6. 以上的命令会在同目录下生成keystore文件,接着使用Android SDK提供的工具apksigner对apk签名(apksigner就在Android SDK目录下,需要先下载Android SDK):
    apksigner.bat -ks my-pixiv.keystore pixiv.apk
    

到此为止,对apk的重打包大功告成,可以正常的使用Fiddler对其抓包了

Reference

  • [1] redice.(2015).How to capture HTTPS(TLS 1.0) communications from Android App with Fiddler4?[Online] answer. Available: https://stackoverflow.com/a/33390831 [2015, Oct 28].

  1. https://developer.android.com/training/articles/security-config#debug-overrides ↩︎
  2. https://developer.android.com/guide/topics/manifest/application-element#debug ↩︎

乱我心者,今日之日多烦忧