绕过ssl pinning

本篇文章将讲解如何绕过ssl pingning的常用的几种方法


frida 与 frida-tools 对应关系

frida-tools==1.0.0 ------ 12.0.0<=frida<13.0.0
frida-tools==1.1.0 ------ 12.0.0<=frida<13.0.0
frida-tools==1.2.0 ------ 12.1.0<=frida<13.0.0
frida-tools==1.2.1 ------ 12.1.0<=frida<13.0.0
frida-tools==1.2.2 ------ 12.1.0<=frida<13.0.0
frida-tools==1.2.3 ------ 12.1.0<=frida<13.0.0
frida-tools==1.3.0 ------ 12.3.0<=frida<13.0.0
frida-tools==1.3.1 ------ 12.3.0<=frida<13.0.0
frida-tools==1.3.2 ------ 12.4.0<=frida<13.0.0
frida-tools==2.0.0 ------ 12.5.3<=frida<13.0.0
frida-tools==2.0.1 ------ 12.5.9<=frida<13.0.0
frida-tools==2.0.2 ------ 12.5.9<=frida<13.0.0
frida-tools==2.1.0 ------ 12.5.9<=frida<13.0.0
frida-tools==2.1.1 ------ 12.5.9<=frida<13.0.0
frida-tools==2.2.0 ------ 12.5.9<=frida<13.0.0
frida-tools==3.0.0 ------ 12.6.17<=frida<13.0.0
frida-tools==3.0.1 ------ 12.6.17<=frida<13.0.0
frida-tools==4.0.0 ------ 12.6.21<=frida<13.0.0
frida-tools==4.0.1 ------ 12.6.21<=frida<13.0.0
frida-tools==4.0.2 ------ 12.6.21<=frida<13.0.0
frida-tools==4.1.0 ------ 12.6.21<=frida<13.0.0
frida-tools==5.0.0 ------ 12.6.21<=frida<13.0.0
frida-tools==5.0.1 ------ 12.7.3<=frida<13.0.0
frida-tools==5.1.0 ------ 12.7.3<=frida<13.0.0
frida-tools==5.2.0 ------ 12.7.3<=frida<13.0.0
frida-tools==5.3.0 ------ 12.7.3<=frida<13.0.0
frida-tools==5.4.0 ------ 12.7.3<=frida<13.0.0
frida-tools==6.0.0 ------ 12.8.5<=frida<13.0.0
frida-tools==6.0.1 ------ 12.8.5<=frida<13.0.0
frida-tools==7.0.0 ------ 12.8.12<=frida<13.0.0
frida-tools==7.0.1 ------ 12.8.12<=frida<13.0.0
frida-tools==7.0.2 ------ 12.8.12<=frida<13.0.0
frida-tools==7.1.0 ------ 12.8.12<=frida<13.0.0
frida-tools==7.2.0 ------ 12.8.12<=frida<13.0.0
frida-tools==7.2.1 ------ 12.8.12<=frida<13.0.0
frida-tools==7.2.2 ------ 12.8.12<=frida<13.0.0
frida-tools==8.0.0 ------ 12.10.4<=frida<13.0.0
frida-tools==8.0.1 ------ 12.10.4<=frida<13.0.0
frida-tools==8.1.0 ------ 12.10.4<=frida<13.0.0
frida-tools==8.1.1 ------ 12.10.4<=frida<13.0.0
frida-tools==8.1.2 ------ 12.10.4<=frida<13.0.0
frida-tools==8.1.3 ------ 12.10.4<=frida<13.0.0
frida-tools==8.2.0 ------ 12.10.4<=frida<13.0.0
frida-tools==9.0.0 ------ 14.0.0<=frida<15.0.0
frida-tools==9.0.1 ------ 14.0.0<=frida<15.0.0
frida-tools==9.1.0 ------ 14.2.0<=frida<15.0.0
frida-tools==9.2.0 ------ 14.2.9<=frida<15.0.0
frida-tools==9.2.1 ------ 14.2.9<=frida<15.0.0
frida-tools==9.2.2 ------ 14.2.9<=frida<15.0.0
frida-tools==9.2.3 ------ 14.2.9<=frida<15.0.0
frida-tools==9.2.4 ------ 14.2.9<=frida<15.0.0
frida-tools==9.2.5 ------ 14.2.9<=frida<15.0.0
frida-tools==10.0.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.1.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.1.1 ------ 15.0.0<=frida<16.0.0
frida-tools==10.2.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.2.1 ------ 15.0.0<=frida<16.0.0
frida-tools==10.2.2 ------ 15.0.0<=frida<16.0.0
frida-tools==10.3.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.4.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.4.1 ------ 15.0.0<=frida<16.0.0
frida-tools==10.5.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.5.1 ------ 15.0.0<=frida<16.0.0
frida-tools==10.5.2 ------ 15.0.0<=frida<16.0.0
frida-tools==10.5.3 ------ 15.0.0<=frida<16.0.0
frida-tools==10.5.4 ------ 15.0.0<=frida<16.0.0
frida-tools==10.6.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.6.1 ------ 15.0.0<=frida<16.0.0
frida-tools==10.6.2 ------ 15.0.0<=frida<16.0.0
frida-tools==10.7.0 ------ 15.0.0<=frida<16.0.0
frida-tools==10.8.0 ------ 15.0.0<=frida<16.0.0
frida-tools==11.0.0 ------ 15.2.0<=frida<16.0.0
frida-tools==12.0.0 ------ 16.0.0<=frida<17.0.0
frida-tools==12.0.1 ------ 16.0.0<=frida<17.0.0
frida-tools==12.0.2 ------ 16.0.0<=frida<17.0.0
frida-tools==12.0.3 ------ 16.0.0<=frida<17.0.0
frida-tools==12.0.4 ------ 16.0.0<=frida<17.0.0
frida-tools==12.1.0 ------ 16.0.0<=frida<17.0.0
frida-tools==12.1.1 ------ 16.0.9<=frida<17.0.0
frida-tools==12.1.2 ------ 16.0.9<=frida<17.0.0
frida-tools==12.1.3 ------ 16.0.9<=frida<17.0.0
frida-tools==12.2.0 ------ 16.0.9<=frida<17.0.0
frida-tools==12.2.1 ------ 16.0.9<=frida<17.0.0
frida-tools==12.3.0 ------ 16.0.9<=frida<17.0.0

苹果

ssl-kill-switch2

https://github.com/nabla-c0d3/ssl-kill-switch2/releases

//绕过ssl pingning
scp com.nablac0d3.sslkillswitch2_0.14.deb root@192.168.137.21:/tmp
//ssh连接iphone
dpkg -i com.nablac0d3.sslkillswitch2_0.14.deb 
killall -HUP SpringBoard

使用objection绕过

客户端环境准备:

pip install frida==14.2.18
pip install frida-tools==9.2.5
pip install objection==1.11.0

服务端安装:

//frida-server指定版本的安装
//frida-server的版本与frida的版本要匹配
//指定版本frida-server的获取
https://github.com/frida/frida/releases/tag/14.2.18

scp frida_14.2.18_iphoneos-arm.deb root@192.168.137.48:/tmp
cd /tmp
dpkg -i frida_14.2.18_iphoneos-arm.deb

objection绕过:

//注入进程
objection -g com.chinamobile.xc.MobileUShield explore(输入后会自动打开app) 
//关闭ssl校验 
ios sslpinning disable
objection -g com.central.mbomc explore
objection -g com.asiainfo.ima.base explore

VPN绕过

可以使用小火箭Shadowrocket进行绕过,设置好代理ip和端口,如果没有检测,就可以直接抓包,若有检测反编译后,观察观察相关代码进行绕过

eg:以下为绕过CFNetworkCopySystemProxySettings检测

//frida -U -n xxxx -l bypass_vpn_ios.js
var CFNetworkCopySystemProxySettings = Module.findExportByName("CFNetwork", "CFNetworkCopySystemProxySettings");

if (CFNetworkCopySystemProxySettings) {
    Interceptor.attach(CFNetworkCopySystemProxySettings, {
        onLeave: function (retval) {
            if (!retval.isNull()) {
                var proxySettings = new ObjC.Object(retval).mutableCopy();

                // 设置为关闭代理
                proxySettings.setObject_forKey_(0, 'HTTPEnable');
                proxySettings.setObject_forKey_(0, 'HTTPSEnable');
                proxySettings.setObject_forKey_(0, 'FTPEnable');
                proxySettings.setObject_forKey_(0, 'SOCKSEnable');

                // 清除代理服务器地址和端口
                proxySettings.removeObjectForKey_('HTTPProxy');
                proxySettings.removeObjectForKey_('HTTPSProxy');
                proxySettings.removeObjectForKey_('HTTPPort');
                proxySettings.removeObjectForKey_('HTTPSPort');

                // 清除其它相关设置
                proxySettings.removeObjectForKey_('ExceptionsList');
                proxySettings.removeObjectForKey_('__SCOPED__');

                // 替换原始的返回值
                retval.replace(proxySettings.handle);
            }
        }
    });
} else {
    console.log("CFNetworkCopySystemProxySettings没有找到!");
}

frida绕过

以下为脚本:

const log = {
    "trace": function(msg){
        console.log("\x1b[35m", ` ${msg}`, "\x1b[0m")
    },
    "debug": function(msg){
        console.log("\x1b[32m", ` ${msg}`, "\x1b[0m")
    },
    "info": function(msg){
        console.log("\x1b[34m", ` ${msg}`, "\x1b[0m")
    },
    "warn": function(msg){
        console.log("\x1b[33m", ` ${msg}`, "\x1b[0m")
    },
    "error": function(msg){
        console.log("\x1b[31m", ` ${msg}`, "\x1b[0m")
    },
};

/** 绕过单向证书校验 */
function bypassSSLPinning() {
    let bypass_status = false;
    try {
        /**
         * SecTrustEvaluate:Security.framework的系统函数,iOS版本<13.0 可用它评估一个SecTrust对象是否可以被系统信任。
         * 函数原型:OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result);
         * 参考:https://developer.apple.com/documentation/security/1394363-sectrustevaluate?language=objc
         */
        let SecTrustEvaluate_handle = Module.findExportByName('Security', 'SecTrustEvaluate');    // 如果存在,返回一个地址信息
        if (SecTrustEvaluate_handle) {
            Interceptor.replace(SecTrustEvaluate_handle, new NativeCallback(function (trust, result) {
                return 0;
            }, 'int', ['pointer', 'pointer']));
            log.debug(`[${SecTrustEvaluate_handle}] SecTrustEvaluate hook installed.`);
            bypass_status = true;
        };

        /**
         * SecTrustEvaluateWithError:Security.framework的系统函数,iOS版本>=13.0 可用它评估一个SecTrust对象是否可以被系统信任。
         * 函数原型:bool SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef  _Nullable *error);
         * 参考:https://developer.apple.com/documentation/security/2980705-sectrustevaluatewitherror?language=objc
         */
        let SecTrustEvaluateWithError_handle = Module.findExportByName('Security', 'SecTrustEvaluateWithError');
        if (SecTrustEvaluateWithError_handle) {
            Interceptor.replace(SecTrustEvaluateWithError_handle, new NativeCallback(function (trust, error) {
            return 1;
            }, 'int', ['pointer', 'pointer']));
            log.debug(`[${SecTrustEvaluateWithError_handle}] SecTrustEvaluateWithError hook installed.`);
            bypass_status = true;
        };
        } catch (error) { 
        log.error(`[!] Exception: ${error}`);
        };

        try {
        /**
         * SSL_CTX_set_custom_verify:该函数用于覆盖默认的ssl验证逻辑,。
         * OpenSSL < 1.1.1 ,函数原型:SSL_CTX_set_custom_verify(SSL_CTX *ctx, verify_callback, NULL);
         * OpenSSL >= 1.1.1,函数原型:SSL_CTX_set_custom_verify(SSL_CTX *ctx, enum ssl_verify_mode_t, enum ssl_verify_result_t(*callback)(SSL *ssl, uint8_t *out_alert))) 
         * 第二个参数是选择检验模式,主要看第三个参数,它是一个回调函数,如果数值为0表示检验通过。
         * 参考:https://www.cnblogs.com/theseventhson/p/16051195.html
         */
        let SSL_CTX_set_custom_verify_handle = Module.findExportByName('libboringssl.dylib', 'SSL_CTX_set_custom_verify');
        if (SSL_CTX_set_custom_verify_handle) {
            let SSL_CTX_set_custom_verify = new NativeFunction(SSL_CTX_set_custom_verify_handle, 'void', ['pointer', 'int', 'pointer']);
            let callback = new NativeCallback(function (ssl, out_alert) {
                return 0;   // 修改数值为0x0,表示检验通过
            }, 'int', ['pointer', 'pointer']);
            Interceptor.replace(SSL_CTX_set_custom_verify_handle, new NativeCallback(function (ctx, mode, ssl_verify_result_t) {
                SSL_CTX_set_custom_verify(ctx, 0, callback);
                }, 'void', ['pointer', 'int', 'pointer'])
            );
            log.debug(`[${SSL_CTX_set_custom_verify_handle}] SSL_CTX_set_custom_verify hook installed.`);
            bypass_status = true;
        };

        /**
         * SSL_get_psk_identity:用于获取 TLS-PSK 握手中使用的身份,该函数的返回值为 0 表示成功,非 0 表示失败。
         * 函数原型:SSL_get_psk_identity(SSL_CTX *ctx, char identity, int identity_len);
         * 参考:https://nabla-c0d3.github.io/blog/2019/05/18/ssl-kill-switch-for-ios12/
         */
        let SSL_get_psk_identity_handle = Module.findExportByName('libboringssl.dylib', 'SSL_get_psk_identity');
        if (SSL_get_psk_identity_handle) {
            Interceptor.replace(SSL_get_psk_identity_handle, new NativeCallback(function (ctx, identity, identity_len) {
            return 0;
            }, 'int', ['pointer', 'char', 'int']));
            log.debug(`[${SSL_get_psk_identity_handle}] SSL_get_psk_identity hook installed.`);
            bypass_status = true;
        };

        /**
         * boringssl_context_set_verify_mode:用于设置 SSL 上下文的验证模式,该函数的返回值为 0 表示成功,非 0 表示失败。
         * 函数原型:boringssl_context_set_verify_mode_handle(SSL_CTX *ctx, mode);
         * 参考:https://gist.github.com/azenla/37f941de24c5dfe46f3b8e93d94ce909
         */
        let boringssl_context_set_verify_mode_handle = Module.findExportByName('libboringssl.dylib', 'boringssl_context_set_verify_mode');
        if (boringssl_context_set_verify_mode_handle) {
            Interceptor.replace(boringssl_context_set_verify_mode_handle, new NativeCallback(function (ctx, mode) {
            return 0;
            }, 'int', ['pointer', 'pointer'])
            );
            log.debug(`[${SSL_get_psk_identity_handle}] boringssl_context_set_verify_mode() hook installed.`);
            bypass_status = true;
        };

    } catch (error) {
        log.error(`[!] Exception: ${error}`);
    };

    if (bypass_status) {
        log.info("[+] bypass ssl pinning.");
    };
};

bypassSSLPinning();

安卓

使用objection的时候本机python需要在3.7以上

1.模拟器安装frida服务端

使用adb查看设备abi信息(需要打开逍遥模拟器):

adb shell getprop ro.product.cpu.abi

下载frida服务端地址:https://github.com/frida/frida/releases

下载时对应电脑上的frida版本下载

下载后解压,把解压后的文件使用adb命令上传到设备的/data/local/tmp 目录下

adb push frida-server-16.0.2-android-x86_64 /data/local/tmp

给frida-server-16.0.2-android-x86可执行权限,并执行

adb shell

cd /data/local/tmp

chmod 777 frida-server-16.0.2-android-x86

./frida-server-16.0.2-android-x86

按下回车后没有反应,说明此时已经执行成功了

objection绕过

objection.exe -g 包名 explore(输入后会自动打开app)
objection.exe -g com.xx.xx explore

然后输入 android sslpinning disable

在进行抓包就可以绕过sslpinning了。

ps:如果还是显示网络错误需要按照第二步重新做一下,输入完第一个命令后,等app打开后在输入android sslpinning disable ,输入完毕后此时还不能抓包,需要把app在后台关闭后在重新打开,这样就能抓包了。

frida绕过

sslpinning、root、代理检测

查包名:

adb shell pm list packages -3
frida -U -l zhihuibangong.js -f cn.cmit.xxxx
frida -U -l mbomc2.js -f  centralize.xxx.ebomc.xxx

单向双向证书校验

推荐阅读
DroidSSLUnpinning

查看CA证书

cd /system/etc/security/cacerts
ls -liat

免责声明

免责声明:本博客的内容仅供合法、正当、健康的用途,切勿将其用于违反法律法规的行为。如因此导致任何法律责任或纠纷,本博客概不负责。谢谢您的理解与配合!

本文链接:

https://sanshiok.com/archive/5.html

# 最新文章