双向证书校验绕过

  1. 一、摘要
  2. 二、服务端校验客户端
  3. 三、客户端校验服务端
  4. 四、总结

一、摘要

在逆向app时,如果app存在双向证书校验,指服务端校验服务端证书和客户端校验服务端

  1. 前者需导出app的证书,无论是抓包还是爬虫发起请求,都需要携带上此证书,否则会发包被拒
  2. 后者可通过hook java层的com.android.org.conscrypt.Platform.checkServerTrusted方法,将校验逻辑改为空,即可绕过
    本文使用r0capture导出app客户端证书,过掉服务端校验,使用fridah-hook修改java层方法过掉客户端校验。

二、服务端校验客户端

目标app是东呈青猫会,如果安卓直接抓包,app显示:
20250215152433
报文显示:
20250215173643
首先,启动frida-server,
r0capture下载地址:https://github.com/r0ysue/r0capture
下载完后,修改一下r0capture.py脚本
20250215152812
这样做的目的是

  1. 去掉文件写入log,避免产生大量log文件、
  2. 直接允许python脚本,更方便(命令行允许发现终端无法中止,只能关闭)

这里使用了wait参数,给与了0.5s的值是因为,app可能在一开始java层就进行了证书校验,如果我们hook的过早,frida注入的痕迹会被其检测到,所以等待0.5s,让app加载完成后再hook。
导出的客户端证书默认路径在/sdcard/download/xx.p12, 密码默认是r0ysue
20250215153557
使用adb命令导出到pc,adb pull /sdcar./donnload/xx.p12 /

reqable安装客户端证书
20250215153835

对于ios设备

setTimeout(function() {
    Interceptor.attach(Module.findExportByName("Security", 'SecPKCS12Import'), {
        onEnter: function(args) {
            console.log('SecPKCS12Import called');
            let ciper=ObjC.Object(args[0]);
            console.log("SecPKCS12Import cert",hexdump(ciper.bytes(), {
                length: ciper.length(),
            }
            ))
            console.log("SecPKCS12Import key",ObjC.Object(args[1]))
        }
    });
}, 500); // 延迟 0.5s后注入

frida -U -f com.dossen.app -l cert.js -o output.txt
20250219174754
这一段的hexdump是证书的hex值,将其复制出来,用开源工具cyperchef,将hex转为p12文件
20250219175145
密码是 :
20250219175213

三、客户端校验服务端

checkServerTrusted方法的主要作用是验证服务器证书链的有效性。当客户端与服务器建立安全连接时,服务器会发送其证书链给客户端。客户端通过调用checkServerTrusted方法来验证这些证书是否可信,从而确保服务器的身份是可靠的。如果证书链验证失败,则会抛出CertificateException异常,导致连接失败‌。

setTimeout(() => {
    Java.perform(function () {
        function hook_ssl() {
            Java.perform(function () {
                var ClassName = "com.android.org.conscrypt.Platform";
                var Platform = Java.use(ClassName);
                var targetMethod = "checkServerTrusted";
                var len = Platform[targetMethod].overloads.length;
                console.log(len);
                for (var i = 0; i < len; ++i) {
                    Platform[targetMethod].overloads[i].implementation = function () {
                        console.log("class:", ClassName, "target:", targetMethod, " i:", i, arguments);
                        //printStack(ClassName + "." + targetMethod);
                    }
                }
            });
            console.log("hook_ssl")
        }
        hook_ssl()
    })
}, 500)

保存为cert.js
运行frida -U -f com.dossen.app -l cert.js

对于ios设备

objection -g com.dossen.app explore
ios sslpinning disable

20250215155517
20250215155549
抓包成功。

四、总结

  1. 客户端校验服务端证书,使用frida hook checkServerTrusted方法,使其不抛出异常,绕过客户端证书校验。
  2. 服务端校验客户端证书,使用r0capture工具导出客户端证书,交与抓包软件或代码使用,绕过服务端证书校验。
  3. 通过延迟0.5s,避免过早注入导致会相应进程检测到注入痕迹, 举例而言就像是我们等宿管查完房后再偷偷出去。

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,如有问题请邮件至2454612285@qq.com。
跃迁主页