Android APP SSLPinning证书绑定绕过

 现在测试过程中有没有感觉遇到能直接抓包的APP,简直要拜菩萨,经常测试APP的心路历程是,欸,我的证书怎么又出问题了,重新导证书后,欸,怎么还是抓不到MMP…。

为什么https的网站使用伪证书可以抓到,而在app里面同样的方法就抓不到?

  1. 浏览器允许用户忽略证书告警;
  2. 浏览器允许用户导入证书到证书信任区,从而伪造证书;

也就是我们常用的burpsuite导证书操作,所以网站可以利用这种方式伪造证书中间人攻击;

       而APP不行的原因在于SSLPinning(证书绑定),也就是客户端在收到服务器的证书后,对该证书进行强校验,验证该证书是不是客户端承认的证书,如果不是,则直接断开连接,而且客户端承认的证书会在应用发布的时候打包进去,这个时候是不是看起来就没什么办法了呢?

先来看一下实现的代码。

主要实现函数checkServerTrusted();分别对服务端是否有证书,和证书是否正确进行了判断,如果有问题则抛出异常,其实这个函数在每个APP都存在,为什么有些能直接抓取数据包,而有些不能呢,可以抓的是因为在开发的时候开发人员直接将此函数返回空值,不做任何处理导致;

来到这篇文章的重点,怎么绕过这个APP证书绑定呢?

第一种方式

当然是我们的hook大法啦,利用Xposed + JustTruestMe来突破SSL pinning;这种方式网上很多介绍,也就是在程序运行时修改内存中指定的参数,达到修改程序的目的,从而绕过认证;

使用前提是需要root的测试设备,这里就不多说Xposed的使用了。

https://repo.xposed.info/module/de.robv.android.xposed.installer

JustTruestMe插件下载地址:

https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2

第二种方式

自己逆向修改源码;感觉对比起第一种要蠢很多;但是最近一次项目自己就这么做了。

因为刚好遇到有没有加壳的,就拿来练手了;

直接用AndroidKiller反编译,工程搜索checkServerTrusted;应用比较简单,可以看到搜索结果,第一个就是我们要找的checkServerTrusted()函数,第二个只是一个字符型,第三个是函数调用;

打开第一个函数,进去看;

.method public checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V
    .locals 2
    .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/security/cert/CertificateException;
        }
    .end annotation
    .prologue
    .line 1396
    if-nez p1, :cond_0
    .line 1397
    new-instance v0, Ljava/lang/IllegalArgumentException;
    const-string v1, "there were no certificates."
    invoke-direct {v0, v1}, Ljava/lang/IllegalArgumentException;-><init>(Ljava/lang/String;)V
    throw v0

    .line 1399

    :cond_0

    array-length v0, p1

    const/4 v1, 0x1

    if-ne v0, v1, :cond_1

    .line 1401

    const/4 v0, 0x0

    aget-object v0, p1, v0

    invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->checkValidity()V

    .line 1407

    :goto_0

    return-void

    .line 1402

    :cond_1

    iget-object v0, p0, Lcom/mob/tools/network/NetworkHelper$SimpleX509TrustManager;->standardTrustManager:Ljavax/net/ssl/X509TrustManager;

    if-eqz v0, :cond_2

    .line 1403

    iget-object v0, p0, Lcom/mob/tools/network/NetworkHelper$SimpleX509TrustManager;->standardTrustManager:Ljavax/net/ssl/X509TrustManager;

    invoke-interface {v0, p1, p2}, Ljavax/net/ssl/X509TrustManager;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V

    goto :goto_0

    .line 1405

    :cond_2

    new-instance v0, Ljava/security/cert/CertificateException;

    const-string v1, "there were one more certificates but no trust manager found."

    invoke-direct {v0, v1}, Ljava/security/cert/CertificateException;-><init>(Ljava/lang/String;)V
    throw v0

.end method

       简单解释下,可以看到函数中有多处条件跳转,如:cond_0,:cond_1,:cond_2和:goto_0;:cond_处都有对应的处理,我们不用管做啥处理,可以发现只有:goto_0是return-void,不做任何处理,而我们也是要此函数不做任何处理,这样就能达到我们的目的,所以最简单的修改就是将所有的条件跳转位置都改成:goto_0,这样就能导致此函数不管是什么结果都返回空值,当然还有其它的修改方式。

       重新编译,签名,安装成功后,就可以抓到对应的数据包了;当然这个也可以直接用Xposed + JustTruestMe的方式来抓取数据包,但是需要root环境的测试设备,而改数据包的好处就是不需要。其中的原理都是一样的,当然能够抓取数据包的方式肯定不止这两种。

现在抓不到数据包的原因又多了,还有双向证书认证的,突破方式是在app中找本地保存的证书文件,导入到抓包工具即可,但是有的有密码认证,需要额外反编译app,找到其中的密码。

还有抓不到数据包的原因是app走的不是http、https,走tcp、socket、udp、mqtt、蓝牙等其他协议。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值