functiongetFieldValue(obj, fieldName) { var cls = obj.getClass(); var field = cls.getDeclaredField(fieldName); field.setAccessible(true); var name = field.getName(); var value = field.get(obj); return value; }
functiongetMethodValue(obj, methodName) { var res; var cls = obj.getClass(); var methods = cls.getDeclaredMethods();
methods.forEach(function (method) { var method_name = method.getName(); console.log(method_name, method); if (method_name === methodName) { method.setAccessible(true); res = method; return; } }) return res; }
varRealConnection = Java.use('okhttp3.internal.connection.RealConnection'); RealConnection.connectTls.implementation = function (connectionSpecSelector) { var route = getFieldValue(this, "route"); // this.route var address = getFieldValue(route, 'address'); // address var hostnameVerifier = getFieldValue(address, 'hostnameVerifier'); console.log('\n[+] hostnameVerifier', hostnameVerifier); /* try { var route = getFieldValue(this, "route"); var address = getFieldValue(route, 'address'); var func = getMethodValue(address, "hostnameVerifier"); console.log('\n[+] addhostnameVerifierress', func.invoke(address, null)); } catch (e) { console.log(e); } */ returnthis.connectTls(connectionSpecSelector); }; });
functiongetFieldValue(obj, fieldName) { var cls = obj.getClass(); var field = cls.getDeclaredField(fieldName); field.setAccessible(true); var name = field.getName(); var value = field.get(obj); return value; }
functiongetMethodValue(obj, methodName) { var res; var cls = obj.getClass(); var methods = cls.getDeclaredMethods();
methods.forEach(function (method) { var method_name = method.getName(); console.log(method_name, method); if (method_name === methodName) { method.setAccessible(true); res = method; return; } }) return res; }
functiongetFieldValue(obj, fieldName) { var cls = obj.getClass(); var field = cls.getDeclaredField(fieldName); field.setAccessible(true); var name = field.getName(); var value = field.get(obj); return value; }
functiongetMethodValue(obj, methodName) { var res; var cls = obj.getClass(); var methods = cls.getDeclaredMethods();
methods.forEach(function (method) { var method_name = method.getName(); console.log(method_name, method); if (method_name === methodName) { method.setAccessible(true); res = method; return; } }) return res; }
varRealConnection = Java.use('okhttp3.internal.connection.RealConnection'); RealConnection.connectTls.implementation = function (connectionSpecSelector) { var route = getFieldValue(this, "route"); var address = getFieldValue(route, 'address'); var hostnameVerifier = getFieldValue(address, 'hostnameVerifier'); console.log('\n[+] hostnameVerifier', hostnameVerifier); /* try { var route = getFieldValue(this, "route"); var address = getFieldValue(route, 'address'); var func = getMethodValue(address, "hostnameVerifier"); console.log('\n[+] addhostnameVerifierress', func.invoke(address, null)); } catch (e) { console.log(e); } */ returnthis.connectTls(connectionSpecSelector); }; });
2.客户端证书校验 and 服务端证书校验 - 客户端证书校验 Java.use('okhttp3.CertificatePinner'); Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
方案:找系统包 + 调用栈 + 对比分析 -> 被混淆的模块名称
- 服务端证书校验 Java.use("java.security.KeyStore");
3.源码调用栈和底层执行过程 测试运行:Net04 手机环境:系统代理去掉 客户端证书: CertificatePinner.check X509TrustManager.checkServerTrusted 输出调用栈 Log.e("调用栈", Log.getStackTraceString(new Throwable())); at com.nb.net04.MainActivity$1.checkServerTrusted(MainActivity.java:50) at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:228) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:407) at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336) HostnameVerifier.verify
3.2 系统包doHandshake at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336)
正常: at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226) at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336) at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)
滴答清单: at com.android.org.conscrypt.NativeSsl.doHandshake(Native Method) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226) at uk.c.f(RealConnection.java:27) at uk.c.c(RealConnection.java:22) at uk.f.d(StreamAllocation.java:95)
定义在自定义类中: X509TrustManager trustManager = new X509TrustManager() { @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { ... }
}
调用栈: at com.nb.net04.MainActivity$1.checkServerTrusted(MainActivity.java:50) at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:228)