SSL Pinning之双向认证

概述

本篇只介绍怎么解决ssl pinning, 不讲ssl/tls 原理。
为了解决ssl pinning 服务端验证(又称 双向认证), 解决步骤如下:

获取证书

我们知道服务端证书绑定在客户端中, 那么直接解压apk就可以获取了

常见 akp 的证书一般放在assets 目录下面, 常见的证书格式: cer、pem、p12、pfx、bks
示例:
在这里插入图片描述

逆向app 获取证书的KeyStore的 key

通过ssl pinning 原理我们知道服务端证书被绑定在客户端中(apk里)
这里分为两步:第一步获取 证书passwrd代码位置; 第二步通过frida hook获取password

常见java代码模拟双向认证的请求的过程:

// 双向认证证书
KeyStore keyStore = KeyStore.getInstance("PKCS12");
KeyStore trustStore = KeyStore.getInstance("jks");
// keyStore是服务端验证客户端的证书,trustStore是客户端的信任证书
InputStream ksIn = new FileInputStream("E:/Java/jre8/lib/security/re/1.pfx");
InputStream tsIn = new FileInputStream(new File("E:/Java/jre8/lib/security/re/1"));

// 这里是客户端证书加载, 123456为keyStore的password
keyStore.load(ksIn, "123456".toCharArray());

SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
        .loadKeyMaterial(keyStore, "123456".toCharArray()).setSecureRandom(new SecureRandom()).useSSL().build();

ConnectionSocketFactory pSocketFactory = new PlainConnectionSocketFactory();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);

Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory> create()
        .register("http", pSocketFactory).register("https", sslConnectionSocketFactory).build();
PoolingHttpClientConnectionManager secureConnectionManager = new PoolingHttpClientConnectionManager(r);

HttpClientBuilder secureHttpBulder = HttpClients.custom().setConnectionManager(secureConnectionManager);
HttpClient client = secureHttpBulder.build();

HttpGet httpGet = new HttpGet("https://xxx.com");
HttpResponse httpResponse1 = client.execute(httpGet);

通过jadx 反编译 app 获取证书:

  • 查找特征:
    • keyStore.load

示例: ( 图二 )
图一

frida hook

由于不同apk hook代码不同, 这里介绍两个hook点, 不提供hook 代码

  • hook 密码解密函数
  • hook keyStore 的load 函数

示例:(以图二为例)

// 这里使用hook 点一
function main(){
    Java.perform(function(){
        Java.enumerateClassLoaders({
            onMatch : function(loader){
                try {
                    // loadClass or findClass
                    if (loader.loadClass("o0O0000o.OooO0OO")){
                        Java.classFactory.loader = loader;
                        // something to do;
						var OooO0OO = Java.use("o0O0000o.OooO0OO");
						console.log("success hook it :", OooO0OO);
						OooO0OO["OooO00o"].implementation = function (j) {
							console.log(`OooO0OO.OooO00o is called: j=${j}`);
							let result = this["OooO00o"](j);
							console.log(`OooO0OO.OooO00o result= ${result}`);
							return result;
						};
                    }
                } catch (error) {
                    // pass
                }
            },
            
            onComplete: function () {
                console.log("complete !!! ")
            }
        })
    })
}

setImmediate(main);

结果:

OooO0OO.OooO00o is called: j=-1973552697099
OooO0OO.OooO00o result= MZ4cozY8Qu32UzGe
OooO0OO.OooO00o is called: j=-2046567141131
OooO0OO.OooO00o result= MZ4cozY8Qu32UzGe

证书转换

如果如果证书是bks 的, 还需转换成p12(PKCS12) 或 pem(因为charles 只支持p12 和pem)
转换方式这里介绍两种: 第一种命令行; 第二种使用portecle工具

命令行转换

keytool -importkeystore -srckeystore your_bks_cert.bks -srcstoretype BKS -destkeystore bks.p12 -deststoretype PKCS12

其中,your_bks_cert.bks 是你的 bks格式证书文件,bks.p12 是输出的p12格式证书文件名;之后,按照提示输入bks证书的密码(MZ4cozY8Qu32UzGe)和p12证书的密码(同bks证书)。

portecle 工具使用

网上有很多, 这里提供一个不错的blog 点击前往

charles 配置 p12 格式证书

网上有很多, 这里提供一个不错的blog 点击前往

借鉴:

相关推荐

  1. HTTPS双向认证

    2024-04-15 02:30:02       45 阅读
  2. kingbase配置SSL双向认证

    2024-04-15 02:30:02       29 阅读
  3. 基于openssl实现TCP双向认证

    2024-04-15 02:30:02       17 阅读
  4. cpprestsdk https双向认证小测

    2024-04-15 02:30:02       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-15 02:30:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-15 02:30:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-15 02:30:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-15 02:30:02       18 阅读

热门阅读

  1. AcWing 794. 高精度除法——算法基础课题解

    2024-04-15 02:30:02       15 阅读
  2. lstm时间序列预测python

    2024-04-15 02:30:02       14 阅读
  3. 【LeetCode刷题记录】560. 和为 K 的子数组

    2024-04-15 02:30:02       12 阅读
  4. 文心一言VSchatGPT4

    2024-04-15 02:30:02       11 阅读
  5. 使用 bert-base-chinese-ner 模型实现中文NER

    2024-04-15 02:30:02       11 阅读
  6. Golang实践:用Sync.Map实现简易内存缓存系统

    2024-04-15 02:30:02       14 阅读
  7. Sql缺失索引查询,自动创建执行语句

    2024-04-15 02:30:02       12 阅读
  8. 【SpinalHDL】Scala编程中的class及case class

    2024-04-15 02:30:02       13 阅读
  9. vue 插槽使用

    2024-04-15 02:30:02       13 阅读
  10. HTML的基本结构

    2024-04-15 02:30:02       15 阅读
  11. MongoDB聚合运算符:$push

    2024-04-15 02:30:02       14 阅读