绕过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
单向双向证书校验
查看CA证书
cd /system/etc/security/cacerts
ls -liat
免责声明
免责声明:本博客的内容仅供合法、正当、健康的用途,切勿将其用于违反法律法规的行为。如因此导致任何法律责任或纠纷,本博客概不负责。谢谢您的理解与配合!