【Android 抓包对抗】客户端证书和域名校验绕过

1. 按照之前的方式(https://www.cnblogs.com/gradyblog/p/17197707.html)进行抓包发现证书校验失败

SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknown)

2. apk拖入到jadx中查看

private static OkHttpClient getClient() {
        OkHttpClient okHttpClient = client;
        if (okHttpClient == null) {
            try {
                Certificate generateCertificate = CertificateFactory.getInstance("X509").generateCertificate(in_cer);
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null, null);
                keyStore.setCertificateEntry("wallpaper", generateCertificate);
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init(keyStore);
                TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
                SSLContext sSLContext = SSLContext.getInstance("TLS");
                sSLContext.init(null, trustManagers, null);
                SSLSocketFactory socketFactory = sSLContext.getSocketFactory();
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.sslSocketFactory(socketFactory, (X509TrustManager) trustManagers[0]);
                builder.hostnameVerifier(new HostnameVerifier() { // from class: com.dta.dtawallpaper.util.OkHttpUtil.1
                    @Override // javax.net.ssl.HostnameVerifier
                    public boolean verify(String str, SSLSession sSLSession) {
                        return str.equals("www.dtasecurity.cn");
                    }
                });
......
                return builder.build();
            } catch (Exception unused) {
                return null;
            }
        }
        return okHttpClient;
    }

从这里可以看出进行了 客户端证书的校验,和Hostname的校验,就防止了中间人转发的问题,但这也不是问题

2. 编写frida脚本绕过

function main(){
    Java.perform(function (){
 
        //TrustAllManager
        var TrustAllManagerClass = Java.registerClass({
            name: "TrustAllManager",
            implements:[Java.use("javax.net.ssl.X509TrustManager")],
            methods: {
                checkClientTrusted(chain, authType) {
                    console.log("checkClientTrusted Called!!")
                },
                checkServerTrusted(chain, authType) {
                    console.log("checkServerTrusted Called!!")
                },
                getAcceptedIssuers() {
                  return [];
                },
              }
        })
        var trustAllManagerHandle = TrustAllManagerClass.$new()
 
        var sslContext = Java.use("javax.net.ssl.SSLContext").getInstance("TLS")
        var trustManagers = Java.array("Ljavax.net.ssl.X509TrustManager;",[trustAllManagerHandle])
        sslContext.init(null,trustManagers,null)
        var sslSocketFactory = sslContext.getSocketFactory()
 
        Java.use("okhttp3.OkHttpClient$Builder").sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory', 'javax.net.ssl.X509TrustManager').implementation = function(arg0, arg1){
            console.log("sslSocketFactory Called!!")
            return this.sslSocketFactory(sslSocketFactory,trustAllManagerHandle)
        }
 
 
        //HostnameVerify
        var MyHostnameVerify = Java.registerClass({
            name: "MyHostnameVerify",
            implements:[Java.use("javax.net.ssl.HostnameVerifier")],
            methods: {
                verify(hostname, session){
                    console.log(hostname)
                    return true
                }
            }
        })
        var myHostnameVerifyHandle = MyHostnameVerify.$new()
 
        Java.use("okhttp3.OkHttpClient$Builder").build.implementation = function(){
            this.hostnameVerifier(myHostnameVerifyHandle)
            console.log(this.hostnameVerifier)
            return this.build()
        }
    })
}
 
setImmediate(main)


这里主要是自定义了TrustAllManager类和HostnameVerifier类,来控制其行为实现绕过

3. 以spawn模式执行,成功抓到https的包

ps 这里遇到了一个小问题,但是本应该不存在的 首先我们要在 (SSL Proxy Settings)中设置好host和port ,比如我设置的是*:443 和 *:10081,但是有一个请求还是没有显示,右键它 选择enable ssl proxying就好了
参考: https://stackoverflow.com/questions/49117151/charles-proxy-ssl-ssl-proxying-not-enabled-for-this-host

posted @ 2023-03-09 16:42  明月照江江  阅读(1340)  评论(0编辑  收藏  举报