Last active
August 29, 2023 20:16
-
-
Save jcalabres/24024677df6ff653e5217cc29bc31f26 to your computer and use it in GitHub Desktop.
Pinning Bypass + Crypto Hooks
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
Java.deoptimizeEverything() | |
Java.perform(function () { | |
hookCrypto() | |
enable_cert_unpinning() | |
}); | |
var printBacktrace = function () { | |
Java.perform(function() { | |
var JLog = Java.use('android.util.Log'), JException = Java.use('java.lang.Exception'); | |
// getting stacktrace by throwing an exception | |
console.warn(JLog.getStackTraceString(JException.$new())); | |
}); | |
}; | |
function hookCrypto() { | |
var complete_bytes = new Array(); | |
var index = 0; | |
var secretKeySpecDef = Java.use('javax.crypto.spec.SecretKeySpec'); | |
var ivParameterSpecDef = Java.use('javax.crypto.spec.IvParameterSpec'); | |
var cipherDef = Java.use('javax.crypto.Cipher'); | |
var cipherDoFinal_1 = cipherDef.doFinal.overload(); | |
var cipherDoFinal_2 = cipherDef.doFinal.overload('[B'); | |
var cipherDoFinal_3 = cipherDef.doFinal.overload('[B', 'int'); | |
var cipherDoFinal_4 = cipherDef.doFinal.overload('[B', 'int', 'int'); | |
var cipherDoFinal_5 = cipherDef.doFinal.overload('[B', 'int', 'int', '[B'); | |
var cipherDoFinal_6 = cipherDef.doFinal.overload('[B', 'int', 'int', '[B', 'int'); | |
var cipherUpdate_1 = cipherDef.update.overload('[B'); | |
var cipherUpdate_2 = cipherDef.update.overload('[B', 'int', 'int'); | |
var cipherUpdate_3 = cipherDef.update.overload('[B', 'int', 'int', '[B'); | |
var cipherUpdate_4 = cipherDef.update.overload('[B', 'int', 'int', '[B', 'int'); | |
var secretKeySpecDef_init_1 = secretKeySpecDef.$init.overload('[B', 'java.lang.String'); | |
var secretKeySpecDef_init_2 = secretKeySpecDef.$init.overload('[B', 'int', 'int', 'java.lang.String'); | |
// KeyGenerator | |
var keyGenerator = Java.use("javax.crypto.KeyGenerator"); | |
keyGenerator.generateKey.implementation = function () { | |
console.log("[*] Generate symmetric key called. "); | |
return this.generateKey(); | |
}; | |
keyGenerator.getInstance.overload('java.lang.String').implementation = function (var0) { | |
console.log("[*] KeyGenerator.getInstance called with algorithm: " + var0 + "\n"); | |
return this.getInstance(var0); | |
}; | |
keyGenerator.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (var0, var1) { | |
console.log("[*] KeyGenerator.getInstance called with algorithm: " + var0 + " and provider: " + var1 + "\n"); | |
return this.getInstance(var0, var1); | |
}; | |
keyGenerator.getInstance.overload('java.lang.String', 'java.security.Provider').implementation = function (var0, var1) { | |
console.log("[*] KeyGenerator.getInstance called with algorithm: " + var0 + " and provider: " + var1 + "\n"); | |
return this.getInstance(var0, var1); | |
}; | |
// KeyPairGenerator | |
var keyPairGenerator = Java.use("java.security.KeyPairGenerator"); | |
keyPairGenerator.getInstance.overload('java.lang.String').implementation = function (var0) { | |
console.log("[*] GetPairGenerator.getInstance called with algorithm: " + var0 + "\n"); | |
return this.getInstance(var0); | |
}; | |
keyPairGenerator.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (var0, var1) { | |
console.log("[*] GetPairGenerator.getInstance called with algorithm: " + var0 + " and provider: " + var1 + "\n"); | |
return this.getInstance(var0, var1); | |
}; | |
keyPairGenerator.getInstance.overload('java.lang.String', 'java.security.Provider').implementation = function (var0, var1) { | |
console.log("[*] GetPairGenerator.getInstance called with algorithm: " + var0 + " and provider: " + var1 + "\n"); | |
return this.getInstance(var0, var1); | |
}; | |
cipherDoFinal_1.implementation = function() { | |
var ret = cipherDoFinal_1.call(this); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, ret); | |
return ret; | |
} | |
cipherDoFinal_2.implementation = function(arr) { | |
addtoarray(arr); | |
var ret = cipherDoFinal_2.call(this, arr); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, ret); | |
return ret; | |
} | |
cipherDoFinal_3.implementation = function(arr, a) { | |
addtoarray(arr); | |
var ret = cipherDoFinal_3.call(this, arr, a); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, ret); | |
return ret; | |
} | |
cipherDoFinal_4.implementation = function(arr, a, b) { | |
addtoarray(arr); | |
var ret = cipherDoFinal_4.call(this, arr, a, b); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, ret); | |
return ret; | |
} | |
cipherDoFinal_5.implementation = function(arr, a, b, c) { | |
addtoarray(arr); | |
var ret = cipherDoFinal_5.call(this, arr, a, b, c); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, ret); | |
return ret; | |
} | |
cipherDoFinal_6.implementation = function(arr, a, b, c, d) { | |
addtoarray(arr); | |
var ret = cipherDoFinal_6.call(this, arr, a, b, c, d); | |
info(this.getIV(), this.getAlgorithm(), complete_bytes, c); | |
return ret; | |
} | |
cipherUpdate_1.implementation = function(arr) { | |
addtoarray(arr); | |
return cipherUpdate_1.call(this, arr); | |
} | |
cipherUpdate_2.implementation = function(arr, a, b) { | |
addtoarray(arr); | |
return cipherUpdate_2.call(this, arr, a, b); | |
} | |
cipherUpdate_3.implementation = function(arr, a, b, c) { | |
addtoarray(arr); | |
return cipherUpdate_3.call(this, arr, a, b, c); | |
} | |
cipherUpdate_4.implementation = function(arr, a, b, c, d) { | |
addtoarray(arr); | |
return cipherUpdate_4.call(this, arr, a, b, c, d); | |
} | |
function info(iv, alg, plain, encoded) { | |
backtrace() | |
console.log("Performing encryption/decryption"); | |
if (iv) { | |
console.log("Initialization Vector: \\n" + hexdump(b2s(iv))); | |
} else { | |
console.log("Initialization Vector: " + iv); | |
} | |
console.log("Algorithm: " + alg); | |
console.log("In: " + plain); | |
console.log("Out: " + encoded); | |
complete_bytes = []; | |
index = 0; | |
} | |
function hexdump(buffer, blockSize) { | |
blockSize = blockSize || 16; | |
var lines = []; | |
var hex = "0123456789ABCDEF"; | |
for (var b = 0; b < buffer.length; b += blockSize) { | |
var block = buffer.slice(b, Math.min(b + blockSize, buffer.length)); | |
var addr = ("0000" + b.toString(16)).slice(-4); | |
var codes = block.split('').map(function(ch) { | |
var code = ch.charCodeAt(0); | |
return " " + hex[(0xF0 & code) >> 4] + hex[0x0F & code]; | |
}).join(""); | |
codes += " ".repeat(blockSize - block.length); | |
var chars = block.replace(/[\\x00-\\x1F\\x20]/g, '.'); | |
chars += " ".repeat(blockSize - block.length); | |
lines.push(addr + " " + codes + " " + chars); | |
} | |
return lines.join("\\n"); | |
} | |
function b2s(array) { | |
var result = ""; | |
for (var i = 0; i < array.length; i++) { | |
result += String.fromCharCode(modulus(array[i], 256)); | |
} | |
return result; | |
} | |
function modulus(x, n) { | |
return ((x % n) + n) % n; | |
} | |
function addtoarray(arr) { | |
for (var i = 0; i < arr.length; i++) { | |
complete_bytes[index] = arr[i]; | |
index = index + 1; | |
} | |
} | |
} | |
var Color = { | |
RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01", | |
Light: { | |
Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11" | |
} | |
}; | |
/** | |
* | |
* @param input. | |
* If an object is passed it will print as json | |
* @param kwargs options map { | |
* -l level: string; log/warn/error | |
* -i indent: boolean; print JSON prettify | |
* -c color: @see ColorMap | |
* } | |
*/ | |
var LOG = function (input, kwargs) { | |
kwargs = kwargs || {}; | |
var logLevel = kwargs['l'] || 'log', colorPrefix = '\x1b[3', colorSuffix = 'm'; | |
if (typeof input === 'object') | |
input = JSON.stringify(input, null, kwargs['i'] ? 2 : null); | |
if (kwargs['c']) | |
input = colorPrefix + kwargs['c'] + colorSuffix + input + Color.RESET; | |
console[logLevel](input); | |
}; | |
function enable_cert_unpinning() { | |
console.log("---"); | |
console.log("Unpinning Android app..."); | |
// HttpsURLConnection | |
try { | |
const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection"); | |
HttpsURLConnection.setDefaultHostnameVerifier.implementation = function (hostnameVerifier) { | |
console.log(' --> Bypassing HttpsURLConnection (setDefaultHostnameVerifier)'); | |
return; // Do nothing, i.e. don't change the hostname verifier | |
}; | |
console.log('[+] HttpsURLConnection (setDefaultHostnameVerifier)'); | |
} catch (err) { | |
console.log('[ ] HttpsURLConnection (setDefaultHostnameVerifier)'); | |
} | |
try { | |
const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection"); | |
HttpsURLConnection.setSSLSocketFactory.implementation = function (SSLSocketFactory) { | |
console.log(' --> Bypassing HttpsURLConnection (setSSLSocketFactory)'); | |
return; // Do nothing, i.e. don't change the SSL socket factory | |
}; | |
console.log('[+] HttpsURLConnection (setSSLSocketFactory)'); | |
} catch (err) { | |
console.log('[ ] HttpsURLConnection (setSSLSocketFactory)'); | |
} | |
try { | |
const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection"); | |
HttpsURLConnection.setHostnameVerifier.implementation = function (hostnameVerifier) { | |
console.log(' --> Bypassing HttpsURLConnection (setHostnameVerifier)'); | |
return; // Do nothing, i.e. don't change the hostname verifier | |
}; | |
console.log('[+] HttpsURLConnection (setHostnameVerifier)'); | |
} catch (err) { | |
console.log('[ ] HttpsURLConnection (setHostnameVerifier)'); | |
} | |
// SSLContext | |
try { | |
const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager'); | |
const SSLContext = Java.use('javax.net.ssl.SSLContext'); | |
const 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() | |
const TrustManagers = [TrustManager.$new()]; | |
// Get a handle on the init() on the SSLContext class | |
const SSLContext_init = SSLContext.init.overload( | |
'[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom' | |
); | |
// 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); | |
}; | |
console.log('[+] SSLContext'); | |
} catch (err) { | |
console.log('[ ] SSLContext'); | |
} | |
// TrustManagerImpl (Android > 7) | |
try { | |
const array_list = Java.use("java.util.ArrayList"); | |
const TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl'); | |
// This step is notably what defeats the most common case: network security config | |
TrustManagerImpl.checkTrustedRecursive.implementation = function (a1, a2, a3, a4, a5, a6) { | |
console.log(' --> Bypassing TrustManagerImpl checkTrusted '); | |
//showStacks(); | |
return array_list.$new(); | |
} | |
TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) { | |
console.log(' --> Bypassing TrustManagerImpl verifyChain: ' + host); | |
return untrustedChain; | |
}; | |
console.log('[+] TrustManagerImpl'); | |
} catch (err) { | |
console.log('[ ] TrustManagerImpl'); | |
} | |
// OkHTTPv3 (quadruple bypass) | |
try { | |
// Bypass OkHTTPv3 {1} | |
const okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner'); | |
okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function (a, b) { | |
console.log(' --> Bypassing OkHTTPv3 (list): ' + a); | |
return; | |
}; | |
console.log('[+] OkHTTPv3 (list)'); | |
} catch (err) { | |
console.log('[ ] OkHTTPv3 (list)'); | |
} | |
try { | |
// Bypass OkHTTPv3 {2} | |
// This method of CertificatePinner.check could be found in some old Android app | |
const okhttp3_Activity_2 = Java.use('okhttp3.CertificatePinner'); | |
okhttp3_Activity_2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) { | |
console.log(' --> Bypassing OkHTTPv3 (cert): ' + a); | |
return; | |
}; | |
console.log('[+] OkHTTPv3 (cert)'); | |
} catch (err) { | |
console.log('[ ] OkHTTPv3 (cert)'); | |
} | |
try { | |
// Bypass OkHTTPv3 {3} | |
const okhttp3_Activity_3 = Java.use('okhttp3.CertificatePinner'); | |
okhttp3_Activity_3.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function (a, b) { | |
console.log(' --> Bypassing OkHTTPv3 (cert array): ' + a); | |
return; | |
}; | |
console.log('[+] OkHTTPv3 (cert array)'); | |
} catch (err) { | |
console.log('[ ] OkHTTPv3 (cert array)'); | |
} | |
try { | |
// Bypass OkHTTPv3 {4} | |
const okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner'); | |
okhttp3_Activity_4['check$okhttp'].implementation = function (a, b) { | |
console.log(' --> Bypassing OkHTTPv3 ($okhttp): ' + a); | |
}; | |
console.log('[+] OkHTTPv3 ($okhttp)'); | |
} catch (err) { | |
console.log('[ ] OkHTTPv3 ($okhttp)'); | |
} | |
// Trustkit (triple bypass) | |
try { | |
// Bypass Trustkit {1} | |
const trustkit_Activity_1 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier'); | |
trustkit_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) { | |
console.log(' --> Bypassing Trustkit OkHostnameVerifier(SSLSession): ' + a); | |
return true; | |
}; | |
console.log('[+] Trustkit OkHostnameVerifier(SSLSession)'); | |
} catch (err) { | |
console.log('[ ] Trustkit OkHostnameVerifier(SSLSession)'); | |
} | |
try { | |
// Bypass Trustkit {2} | |
const trustkit_Activity_2 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier'); | |
trustkit_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) { | |
console.log(' --> Bypassing Trustkit OkHostnameVerifier(cert): ' + a); | |
return true; | |
}; | |
console.log('[+] Trustkit OkHostnameVerifier(cert)'); | |
} catch (err) { | |
console.log('[ ] Trustkit OkHostnameVerifier(cert)'); | |
} | |
try { | |
// Bypass Trustkit {3} | |
const trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager'); | |
trustkit_PinningTrustManager.checkServerTrusted.implementation = function () { | |
console.log(' --> Bypassing Trustkit PinningTrustManager'); | |
}; | |
console.log('[+] Trustkit PinningTrustManager'); | |
} catch (err) { | |
console.log('[ ] Trustkit PinningTrustManager'); | |
} | |
// Appcelerator Titanium | |
try { | |
const appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager'); | |
appcelerator_PinningTrustManager.checkServerTrusted.implementation = function () { | |
console.log(' --> Bypassing Appcelerator PinningTrustManager'); | |
}; | |
console.log('[+] Appcelerator PinningTrustManager'); | |
} catch (err) { | |
console.log('[ ] Appcelerator PinningTrustManager'); | |
} | |
// OpenSSLSocketImpl Conscrypt | |
try { | |
const OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl'); | |
OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) { | |
console.log(' --> Bypassing OpenSSLSocketImpl Conscrypt'); | |
}; | |
console.log('[+] OpenSSLSocketImpl Conscrypt'); | |
} catch (err) { | |
console.log('[ ] OpenSSLSocketImpl Conscrypt'); | |
} | |
// OpenSSLEngineSocketImpl Conscrypt | |
try { | |
const OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl'); | |
OpenSSLEngineSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function (a, b) { | |
console.log(' --> Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + b); | |
}; | |
console.log('[+] OpenSSLEngineSocketImpl Conscrypt'); | |
} catch (err) { | |
console.log('[ ] OpenSSLEngineSocketImpl Conscrypt'); | |
} | |
// OpenSSLSocketImpl Apache Harmony | |
try { | |
const OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl'); | |
OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function (asn1DerEncodedCertificateChain, authMethod) { | |
console.log(' --> Bypassing OpenSSLSocketImpl Apache Harmony'); | |
}; | |
console.log('[+] OpenSSLSocketImpl Apache Harmony'); | |
} catch (err) { | |
console.log('[ ] OpenSSLSocketImpl Apache Harmony'); | |
} | |
// PhoneGap sslCertificateChecker (https://github.com/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin) | |
try { | |
const phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker'); | |
phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (a, b, c) { | |
console.log(' --> Bypassing PhoneGap sslCertificateChecker: ' + a); | |
return true; | |
}; | |
console.log('[+] PhoneGap sslCertificateChecker'); | |
} catch (err) { | |
console.log('[ ] PhoneGap sslCertificateChecker'); | |
} | |
// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) | |
try { | |
// Bypass IBM MobileFirst {1} | |
const WLClient_Activity_1 = Java.use('com.worklight.wlclient.api.WLClient'); | |
WLClient_Activity_1.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function (cert) { | |
console.log(' --> Bypassing IBM MobileFirst pinTrustedCertificatePublicKey (string): ' + cert); | |
return; | |
}; | |
console.log('[+] IBM MobileFirst pinTrustedCertificatePublicKey (string)'); | |
} catch (err) { | |
console.log('[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string)'); | |
} | |
try { | |
// Bypass IBM MobileFirst {2} | |
const WLClient_Activity_2 = Java.use('com.worklight.wlclient.api.WLClient'); | |
WLClient_Activity_2.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function (cert) { | |
console.log(' --> Bypassing IBM MobileFirst pinTrustedCertificatePublicKey (string array): ' + cert); | |
return; | |
}; | |
console.log('[+] IBM MobileFirst pinTrustedCertificatePublicKey (string array)'); | |
} catch (err) { | |
console.log('[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string array)'); | |
} | |
// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) | |
try { | |
// Bypass IBM WorkLight {1} | |
const worklight_Activity_1 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning'); | |
worklight_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function (a, b) { | |
console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket): ' + a); | |
return; | |
}; | |
console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket)'); | |
} catch (err) { | |
console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket)'); | |
} | |
try { | |
// Bypass IBM WorkLight {2} | |
const worklight_Activity_2 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning'); | |
worklight_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) { | |
console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (cert): ' + a); | |
return; | |
}; | |
console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (cert)'); | |
} catch (err) { | |
console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (cert)'); | |
} | |
try { | |
// Bypass IBM WorkLight {3} | |
const worklight_Activity_3 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning'); | |
worklight_Activity_3.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function (a, b) { | |
console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (string string): ' + a); | |
return; | |
}; | |
console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (string string)'); | |
} catch (err) { | |
console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (string string)'); | |
} | |
try { | |
// Bypass IBM WorkLight {4} | |
const worklight_Activity_4 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning'); | |
worklight_Activity_4.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) { | |
console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession): ' + a); | |
return true; | |
}; | |
console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession)'); | |
} catch (err) { | |
console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession)'); | |
} | |
// Conscrypt CertPinManager | |
try { | |
const conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager'); | |
conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) { | |
console.log(' --> Bypassing Conscrypt CertPinManager: ' + a); | |
return true; | |
}; | |
console.log('[+] Conscrypt CertPinManager'); | |
} catch (err) { | |
console.log('[ ] Conscrypt CertPinManager'); | |
} | |
// CWAC-Netsecurity (unofficial back-port pinner for Android<4.2) CertPinManager | |
try { | |
const cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager'); | |
cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) { | |
console.log(' --> Bypassing CWAC-Netsecurity CertPinManager: ' + a); | |
return true; | |
}; | |
console.log('[+] CWAC-Netsecurity CertPinManager'); | |
} catch (err) { | |
console.log('[ ] CWAC-Netsecurity CertPinManager'); | |
} | |
// Worklight Androidgap WLCertificatePinningPlugin | |
try { | |
const 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 (a, b, c) { | |
console.log(' --> Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a); | |
return true; | |
}; | |
console.log('[+] Worklight Androidgap WLCertificatePinningPlugin'); | |
} catch (err) { | |
console.log('[ ] Worklight Androidgap WLCertificatePinningPlugin'); | |
} | |
// Netty FingerprintTrustManagerFactory | |
try { | |
const netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory'); | |
netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function (type, chain) { | |
console.log(' --> Bypassing Netty FingerprintTrustManagerFactory'); | |
}; | |
console.log('[+] Netty FingerprintTrustManagerFactory'); | |
} catch (err) { | |
console.log('[ ] Netty FingerprintTrustManagerFactory'); | |
} | |
// Squareup CertificatePinner [OkHTTP<v3] (double bypass) | |
try { | |
// Bypass Squareup CertificatePinner {1} | |
const Squareup_CertificatePinner_Activity_1 = Java.use('com.squareup.okhttp.CertificatePinner'); | |
Squareup_CertificatePinner_Activity_1.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) { | |
console.log(' --> Bypassing Squareup CertificatePinner (cert): ' + a); | |
return; | |
}; | |
console.log('[+] Squareup CertificatePinner (cert)'); | |
} catch (err) { | |
console.log('[ ] Squareup CertificatePinner (cert)'); | |
} | |
try { | |
// Bypass Squareup CertificatePinner {2} | |
const Squareup_CertificatePinner_Activity_2 = Java.use('com.squareup.okhttp.CertificatePinner'); | |
Squareup_CertificatePinner_Activity_2.check.overload('java.lang.String', 'java.util.List').implementation = function (a, b) { | |
console.log(' --> Bypassing Squareup CertificatePinner (list): ' + a); | |
return; | |
}; | |
console.log('[+] Squareup CertificatePinner (list)'); | |
} catch (err) { | |
console.log('[ ] Squareup CertificatePinner (list)'); | |
} | |
// Squareup OkHostnameVerifier [OkHTTP v3] (double bypass) | |
try { | |
// Bypass Squareup OkHostnameVerifier {1} | |
const Squareup_OkHostnameVerifier_Activity_1 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier'); | |
Squareup_OkHostnameVerifier_Activity_1.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) { | |
console.log(' --> Bypassing Squareup OkHostnameVerifier (cert): ' + a); | |
return true; | |
}; | |
console.log('[+] Squareup OkHostnameVerifier (cert)'); | |
} catch (err) { | |
console.log('[ ] Squareup OkHostnameVerifier (cert)'); | |
} | |
try { | |
// Bypass Squareup OkHostnameVerifier {2} | |
const Squareup_OkHostnameVerifier_Activity_2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier'); | |
Squareup_OkHostnameVerifier_Activity_2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) { | |
console.log(' --> Bypassing Squareup OkHostnameVerifier (SSLSession): ' + a); | |
return true; | |
}; | |
console.log('[+] Squareup OkHostnameVerifier (SSLSession)'); | |
} catch (err) { | |
console.log('[ ] Squareup OkHostnameVerifier (SSLSession)'); | |
} | |
// Android WebViewClient (double bypass) | |
try { | |
// Bypass WebViewClient {1} (deprecated from Android 6) | |
const AndroidWebViewClient_Activity_1 = Java.use('android.webkit.WebViewClient'); | |
AndroidWebViewClient_Activity_1.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) { | |
console.log(' --> Bypassing Android WebViewClient (SslErrorHandler)'); | |
}; | |
console.log('[+] Android WebViewClient (SslErrorHandler)'); | |
} catch (err) { | |
console.log('[ ] Android WebViewClient (SslErrorHandler)'); | |
} | |
try { | |
// Bypass WebViewClient {2} | |
const AndroidWebViewClient_Activity_2 = Java.use('android.webkit.WebViewClient'); | |
AndroidWebViewClient_Activity_2.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function (obj1, obj2, obj3) { | |
console.log(' --> Bypassing Android WebViewClient (WebResourceError)'); | |
}; | |
console.log('[+] Android WebViewClient (WebResourceError)'); | |
} catch (err) { | |
console.log('[ ] Android WebViewClient (WebResourceError)'); | |
} | |
// Apache Cordova WebViewClient | |
try { | |
const 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'); | |
} | |
// Boye AbstractVerifier | |
try { | |
const 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'); | |
} | |
} | |
function backtrace() { | |
Java.perform(function() { | |
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())) | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment