Package
$ aapt d badging com.p1.mobile.***.apk
package: name='com.p1.mobile.***' versionCode='233' versionName='3.2.8' platformBuildVersionName='8.0.0'
sdkVersion:'16'
targetSdkVersion:'22'
Details
package l;
/* renamed from: l.cNi */
final class C3253cNi extends C5966cNk {
static final class iF extends C5967cNq {
/* renamed from: ˏ */
public final C5967cNq m16620(X509TrustManager x509TrustManager) {
try {
Class cls = Class.forName("android.net.http.X509TrustManagerExtensions");
return new iF(cls.getConstructor(new Class[]{X509TrustManager.class}).newInstance(new Object[]{x509TrustManager}), cls.getMethod("checkServerTrusted", new Class[]{X509Certificate[].class, String.class, String.class}));
} catch (Exception unused) {
return super.m16518(x509TrustManager);
}
}
}
}
在l.cNi中有个函数m16620使用的 X509TrustManagerExtensions.checkServerTrusted 获取证书链
Android源码中X509TrustManagerExtensions.checkServerTrusted的定义
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
String host) throws CertificateException {
X509Certificate[] chain 是当前域名的证书
String host 是当前域名
不打开Charles,看看checkServerTrusted的参数和返回值
checkServerTrusted - Arg 0: Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6e:ee:71:d4:91:20:32:f7:a2:98:7d:a5:89:a1:2f:14
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3
Validity
Not Before: Dec 29 00:00:00 2016 GMT
Not After : Dec 29 23:59:59 2018 GMT
Subject: C=CN, ST=Beijing, L=Beiijing, O=*** Cultural Development (Beijing) Co., Ltd., OU=DevOps, CN=*.***app.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
... //Arg 0的Certificate打印出来有很多数据,这里省略部分数据
checkServerTrusted - Arg 1: RSA
checkServerTrusted - Arg 2: account.***app.com
checkServerTrusted - Result:
...
[Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6e:ee:71:d4:91:20:32:f7:a2:98:7d:a5:89:a1:2f:14
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3
Validity
Not Before: Dec 29 00:00:00 2016 GMT
Not After : Dec 29 23:59:59 2018 GMT
Subject: C=CN, ST=Beijing, L=Beiijing, O=*** Cultural Development (Beijing) Co., Ltd., OU=DevOps, CN=*.***app.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
...
打开Charles,看看checkServerTrusted的参数和返回值
checkServerTrusted - Arg 0: Certificate:
...
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Charles Proxy Custom Root Certificate (built on mac.lan, 23 äºæ 2016), OU=http://charlesproxy.com/ssl, O=XK72 Ltd, L=Auckland, ST=Auckland, C=NZ
Validity
Not Before: Dec 29 00:00:00 2016 GMT
Not After : Dec 29 23:59:59 2018 GMT
Subject: C=CN, ST=Beijing, L=Beiijing, O=*** Cultural Development (Beijing) Co., Ltd., OU=DevOps, CN=*.***app.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
checkServerTrusted - Arg 1: RSA
checkServerTrusted - Arg 2: account.***app.com
checkServerTrusted - Result: [Certificate:
...
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Charles Proxy Custom Root Certificate (built on mac.lan, 23 äºæ 2016), OU=http://charlesproxy.com/ssl, O=XK72 Ltd, L=Auckland, ST=Auckland, C=NZ
Validity
Not Before: Dec 29 00:00:00 2016 GMT
Not After : Dec 29 23:59:59 2018 GMT
Subject: C=CN, ST=Beijing, L=Beiijing, O=*** Cultural Development (Beijing) Co., Ltd., OU=DevOps, CN=*.***app.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
那么我们要绕过他的证书校验,只需要每次都给checkServerTrusted的arg0传入真正的证书就可以了。
以下是frida的脚本
/*
使用说明:按以下顺序执行步骤
1. 关闭抓包工具
2. frida 注入脚本
3. app中正常访问一下,会打印出真正的证书“Subject: C=CN, ST=Beijing, L=Beiijing, O=*** Cultural Development (Beijing) Co., Ltd., OU=DevOps, CN=*.***app.com”
4. 打开抓包工具
*/
setImmediate(function() {
console.log("[*]start bypass script...");
Java.perform(function () {
var X509TrustManager = Java.use("android.net.http.X509TrustManagerExtensions");
var ArrayList = Java.use('java.util.ArrayList');
var checkServerTrusted_arg1= null;
console.log(checkServerTrusted_arg1);
X509TrustManager.checkServerTrusted.implementation = function(arg1, arg2, arg3) {
if (checkServerTrusted_arg1 != null) {
arg1 = checkServerTrusted_arg1;
}
var result = this.checkServerTrusted(arg1, arg2, arg3);
var items = ArrayList.$new(result);
console.log("X509TrustManager.checkServerTrusted:", arg1, arg2, arg3, "\r\n\r\n", items);
checkServerTrusted_arg1 = arg1;
return result;
};
});
});
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-11-25 00:10
被Imyang编辑
,原因: