-
-
Save thnt/b05bb29fdf7ac52d89f889b218eb3ee7 to your computer and use it in GitHub Desktop.
Another Android ssl certificate pinning bypass for various methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Android ssl certificate pinning bypass script for various methods | |
by Maurizio Siddu | |
Run with: | |
frida -U -f [APP_ID] -l frida_multiple_unpinning.js --no-pause | |
*/ | |
setTimeout(function() { | |
Java.perform(function () { | |
console.log(''); | |
console.log('======'); | |
console.log('[#] Android Bypass for various Certificate Pinning methods [#]'); | |
console.log('======'); | |
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager'); | |
var SSLContext = Java.use('javax.net.ssl.SSLContext'); | |
// TrustManager (Android < 7) | |
var TrustManager = Java.registerClass({ | |
// Implement a custom TrustManager | |
name: 'dev.asd.test.TrustManager', | |
implements: [X509TrustManager], | |
methods: { | |
checkClientTrusted: function (chain, authType) {}, | |
checkServerTrusted: function (chain, authType) {}, | |
getAcceptedIssuers: function () {return []; } | |
} | |
}); | |
// Prepare the TrustManager array to pass to SSLContext.init() | |
var TrustManagers = [TrustManager.$new()]; | |
// Get a handle on the init() on the SSLContext class | |
var SSLContext_init = SSLContext.init.overload( | |
'[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'); | |
try { | |
// Override the init method, specifying the custom TrustManager | |
SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) { | |
console.log('[+] Bypassing Trustmanager (Android < 7) request'); | |
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom); | |
}; | |
} catch (err) { | |
console.log('[-] TrustManager (Android < 7) pinner not found'); | |
//console.log(err); | |
} | |
// OkHTTPv3 (double bypass) | |
try { | |
var okhttp3_Activity = Java.use('okhttp3.CertificatePinner'); | |
okhttp3_Activity.check.overload('java.lang.String', 'java.util.List').implementation = function (str) { | |
console.log('[+] Bypassing OkHTTPv3 {1}: ' + str); | |
return true; | |
}; | |
// This method of CertificatePinner.check could be found in some old Android app | |
okhttp3_Activity.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (str) { | |
console.log('[+] Bypassing OkHTTPv3 {2}: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] OkHTTPv3 pinner not found'); | |
//console.log(err); | |
} | |
// Trustkit (triple bypass) | |
try { | |
var trustkit_Activity = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier'); | |
trustkit_Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (str) { | |
console.log('[+] Bypassing Trustkit {1}: ' + str); | |
return true; | |
}; | |
trustkit_Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (str) { | |
console.log('[+] Bypassing Trustkit {2}: ' + str); | |
return true; | |
}; | |
var trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager'); | |
trustkit_PinningTrustManager.checkServerTrusted.implementation = function () { | |
console.log('[+] Bypassing Trustkit {3}'); | |
}; | |
} catch (err) { | |
console.log('[-] Trustkit pinner not found'); | |
//console.log(err); | |
} | |
// TrustManagerImpl (Android > 7) | |
try { | |
var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl'); | |
TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) { | |
console.log('[+] Bypassing TrustManagerImpl (Android > 7): ' + host); | |
return untrustedChain; | |
}; | |
} catch (err) { | |
console.log('[-] TrustManagerImpl (Android > 7) pinner not found'); | |
//console.log(err); | |
} | |
// Appcelerator Titanium | |
try { | |
var appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager'); | |
appcelerator_PinningTrustManager.checkServerTrusted.implementation = function () { | |
console.log('[+] Bypassing Appcelerator PinningTrustManager'); | |
}; | |
} catch (err) { | |
console.log('[-] Appcelerator PinningTrustManager pinner not found'); | |
//console.log(err); | |
} | |
// OpenSSLSocketImpl Conscrypt | |
try { | |
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl'); | |
OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) { | |
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt'); | |
}; | |
} catch (err) { | |
console.log('[-] OpenSSLSocketImpl Conscrypt pinner not found'); | |
//console.log(err); | |
} | |
// OpenSSLEngineSocketImpl Conscrypt | |
try { | |
var OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl'); | |
OpenSSLSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function (str1, str2) { | |
console.log('[+] Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + str2); | |
}; | |
} catch (err) { | |
console.log('[-] OpenSSLEngineSocketImpl Conscrypt pinner not found'); | |
//console.log(err); | |
} | |
// OpenSSLSocketImpl Apache Harmony | |
try { | |
var OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl'); | |
OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function (asn1DerEncodedCertificateChain, authMethod) { | |
console.log('[+] Bypassing OpenSSLSocketImpl Apache Harmony'); | |
}; | |
} catch (err) { | |
console.log('[-] OpenSSLSocketImpl Apache Harmony pinner not found'); | |
//console.log(err); | |
} | |
// PhoneGap sslCertificateChecker (https://github.com/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin) | |
try { | |
var phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker'); | |
phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (str) { | |
console.log('[+] Bypassing PhoneGap sslCertificateChecker: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] PhoneGap sslCertificateChecker pinner not found'); | |
//console.log(err); | |
} | |
// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) | |
try { | |
var WLClient_Activity = Java.use('com.worklight.wlclient.api.WLClient'); | |
WLClient_Activity.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function (cert) { | |
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {1}: ' + cert); | |
return; | |
}; | |
WLClient_Activity.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function (cert) { | |
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {2}: ' + cert); | |
return; | |
}; | |
} catch (err) { | |
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey pinner not found'); | |
//console.log(err); | |
} | |
// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) | |
try { | |
var worklight_Activity = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning'); | |
worklight_Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function (str) { | |
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {1}: ' + str); | |
return; | |
}; | |
worklight_Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (str) { | |
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {2}: ' + str); | |
return; | |
}; | |
worklight_Activity.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function (str) { | |
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {3}: ' + str); | |
return; | |
}; | |
worklight_Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (str) { | |
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {4}: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning pinner not found'); | |
//console.log(err); | |
} | |
// Conscrypt CertPinManager | |
try { | |
var conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager'); | |
conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (str) { | |
console.log('[+] Bypassing Conscrypt CertPinManager: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] Conscrypt CertPinManager pinner not found'); | |
//console.log(err); | |
} | |
// CWAC-Netsecurity (unofficial back-port pinner for Android < 4.2) CertPinManager | |
try { | |
var cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager'); | |
cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (str) { | |
console.log('[+] Bypassing CWAC-Netsecurity CertPinManager: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] CWAC-Netsecurity CertPinManager pinner not found'); | |
//console.log(err); | |
} | |
// Worklight Androidgap WLCertificatePinningPlugin | |
try { | |
var androidgap_WLCertificatePinningPlugin_Activity = Java.use('com.worklight.androidgap.plugin.WLCertificatePinningPlugin'); | |
androidgap_WLCertificatePinningPlugin_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (str) { | |
console.log('[+] Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + str); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] Worklight Androidgap WLCertificatePinningPlugin pinner not found'); | |
//console.log(err); | |
} | |
// Netty FingerprintTrustManagerFactory | |
try { | |
var netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory'); | |
//NOTE: sometimes this below implementation could be useful | |
//var netty_FingerprintTrustManagerFactory = Java.use('org.jboss.netty.handler.ssl.util.FingerprintTrustManagerFactory'); | |
netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function (type, chain) { | |
console.log('[+] Bypassing Netty FingerprintTrustManagerFactory'); | |
}; | |
} catch (err) { | |
console.log('[-] Netty FingerprintTrustManagerFactory pinner not found'); | |
//console.log(err); | |
} | |
// Squareup CertificatePinner [OkHTTP < v3] (double bypass) | |
try { | |
var Squareup_CertificatePinner_Activity = Java.use('com.squareup.okhttp.CertificatePinner'); | |
Squareup_CertificatePinner_Activity.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (str1, str2) { | |
console.log('[+] Bypassing Squareup CertificatePinner {1}: ' + str1); | |
return; | |
}; | |
Squareup_CertificatePinner_Activity.check.overload('java.lang.String', 'java.util.List').implementation = function (str1, str2) { | |
console.log('[+] Bypassing Squareup CertificatePinner {2}: ' + str1); | |
return; | |
}; | |
} catch (err) { | |
console.log('[-] Squareup CertificatePinner pinner not found'); | |
//console.log(err); | |
} | |
// Squareup OkHostnameVerifier [OkHTTP v3] (double bypass) | |
try { | |
var Squareup_OkHostnameVerifier_Activity = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier'); | |
Squareup_OkHostnameVerifier_Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (str1, str2) { | |
console.log('[+] Bypassing Squareup OkHostnameVerifier {1}: ' + str1); | |
return true; | |
}; | |
Squareup_OkHostnameVerifier_Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (str1, str2) { | |
console.log('[+] Bypassing Squareup OkHostnameVerifier {2}: ' + str1); | |
return true; | |
}; | |
} catch (err) { | |
console.log('[-] Squareup OkHostnameVerifier pinner not found'); | |
//console.log(err); | |
} | |
// Android WebViewClient | |
try { | |
var AndroidWebViewClient_Activity = Java.use('android.webkit.WebViewClient'); | |
AndroidWebViewClient_Activity.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) { | |
console.log('[+] Bypassing Android WebViewClient'); | |
}; | |
} catch (err) { | |
console.log('[-] Android WebViewClient pinner not found'); | |
//console.log(err); | |
} | |
// Apache Cordova WebViewClient | |
try { | |
var CordovaWebViewClient_Activity = Java.use('org.apache.cordova.CordovaWebViewClient'); | |
CordovaWebViewClient_Activity.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) { | |
console.log('[+] Bypassing Apache Cordova WebViewClient'); | |
obj3.proceed(); | |
}; | |
} catch (err) { | |
console.log('[-] Apache Cordova WebViewClient pinner not found'); | |
//console.log(err): | |
} | |
// Boye AbstractVerifier | |
try { | |
var boye_AbstractVerifier = Java.use('ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier'); | |
boye_AbstractVerifier.verify.implementation = function (host, ssl) { | |
console.log('[+] Bypassing Boye AbstractVerifier: ' + host); | |
}; | |
} catch (err) { | |
console.log('[-] Boye AbstractVerifier pinner not found'); | |
//console.log(err): | |
} | |
}); | |
}, 0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment