搜集部分脚本

This commit is contained in:
孟凡懂 2022-05-12 15:06:41 +08:00
commit 9cade69ab9
13 changed files with 1388 additions and 0 deletions

14
code/GPS欺骗.js Normal file
View File

@ -0,0 +1,14 @@
const lat = 27.9864882;
const lng = 33.7279001;
Java.perform(function () {
var Location = Java.use("android.location.Location");
Location.getLatitude.implementation = function() {
send("Overwriting Lat to " + lat);
return lat;
}
Location.getLongitude.implementation = function() {
send("Overwriting Lng to " + lng);
return lng;
}
})

View File

@ -0,0 +1,40 @@
'use strict';
console.log("[*] In Memory Dex Dump v0.1 - @cryptax");
Java.perform(function() {
var memoryclassLoader = Java.use("dalvik.system.InMemoryDexClassLoader");
memoryclassLoader.$init.overload('java.nio.ByteBuffer', 'java.lang.ClassLoader').implementation = function(dexbuffer, loader) {
console.log("[*] Hooking InMemoryDexClassLoader");
var object = this.$init(dexbuffer, loader);
/* dexbuffer is a Java ByteBuffer
you cannot dump to /sdcard unless the app has rights to
*/
var remaining = dexbuffer.remaining();
const filename = '/data/data/YOUR-PACKAGE-NAME/dump.dex';
console.log("[*] Opening file name=" + filename + " to write " + remaining + " bytes");
const f = new File(filename, 'wb');
var buf = new Uint8Array(remaining);
for (var i = 0; i < remaining; i++) {
buf[i] = dexbuffer.get();
//debug: console.log("buf["+i+"]="+buf[i]);
}
console.log("[*] Writing " + remaining + " bytes...");
f.write(buf);
f.close();
// checking
remaining = dexbuffer.remaining();
if (remaining > 0) {
console.log("[-] Error: There are " + remaining + " remaining bytes!");
} else {
console.log("[+] Dex dumped successfully in " + filename);
}
return object;
}
});

View File

@ -0,0 +1,46 @@
Java.perform(function() {
var Log = Java.use("android.util.Log");
Log.d.overload('java.lang.String', 'java.lang.String', 'java.lang.Throwable').implementation = function(a, b, c) {
console.log("The application reports Log.d(" + a.toString() + ", " + b.toString() + ")");
return this.d(a, b, c);
};
Log.v.overload('java.lang.String', 'java.lang.String', 'java.lang.Throwable').implementation = function(a, b, c) {
console.log("The application reports Log.v(" + a.toString() + ", " + b.toString() + ")");
return this.v(a, b, c);
};
Log.i.overload('java.lang.String', 'java.lang.String', 'java.lang.Throwable').implementation = function(a, b, c) {
console.log("The application reports Log.i(" + a.toString() + ", " + b.toString() + ")");
return this.i(a, b, c);
};
Log.e.overload('java.lang.String', 'java.lang.String', 'java.lang.Throwable').implementation = function(a, b, c) {
console.log("The application reports Log.e(" + a.toString() + ", " + b.toString() + ")");
return this.e(a, b, c);
};
Log.w.overload('java.lang.String', 'java.lang.String', 'java.lang.Throwable').implementation = function(a, b, c) {
console.log("The application reports Log.w(" + a.toString() + ", " + b.toString() + ")");
return this.w(a, b, c);
};
Log.d.overload('java.lang.String', 'java.lang.String').implementation = function(a, b) {
console.log("The application reports Log.d(" + a.toString() + ", " + b.toString() + ")");
return this.d(a, b);
};
Log.v.overload('java.lang.String', 'java.lang.String').implementation = function(a, b) {
console.log("The application reports Log.v(" + a.toString() + ", " + b.toString() + ")");
return this.v(a, b);
};
Log.i.overload('java.lang.String', 'java.lang.String').implementation = function(a, b) {
console.log("The application reports Log.i(" + a.toString() + ", " + b.toString() + ")");
return this.i(a, b);
};
Log.e.overload('java.lang.String', 'java.lang.String').implementation = function(a, b) {
console.log("The application reports Log.e(" + a.toString() + ", " + b.toString() + ")");
return this.e(a, b);
};
Log.w.overload('java.lang.String', 'java.lang.String').implementation = function(a, b) {
console.log("The application reports Log.w(" + a.toString() + ", " + b.toString() + ")");
return this.w(a, b);
};
});

View File

@ -0,0 +1,156 @@
/*
Author: secretdiary.ninja
License: (CC BY-SA 4.0)
* */
setImmediate(function() {
Java.perform(function() {
var sqliteDatabase = Java.use("android.database.sqlite.SQLiteDatabase");
// execSQL(String sql)
sqliteDatabase.execSQL.overload('java.lang.String').implementation = function(var0) {
console.log("[*] SQLiteDatabase.exeqSQL called with query: " + var0 + "\n");
var execSQLRes = this.execSQL(var0);
return execSQLRes;
};
// execSqL(String, sql, Obj[] bindArgs)
sqliteDatabase.execSQL.overload('java.lang.String', '[Ljava.lang.Object;').implementation = function(var0, var1) {
console.log("[*] SQLiteDatabase.exeqSQL called with query: " + var0 + " and arguments: " + var1 + "\n");
var execSQLRes = this.execSQL(var0, var1);
return execSQLRes;
};
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
sqliteDatabase.query.overload('boolean', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function(var0, var1, var2, var3, var4, var5, var6, var7, var8) {
var methodVal = "[*] SQLiteDatabase.query called.";
var logVal = "Table: " + var1 + ", selection value: " + var3 + ", selectionArgs: " + var4 + " distinct: " + var0;
console.log(methodVal + " " + logVal + "\n");
var queryRes = this.query(var0, var1, var2, var3, var4, var5, var6, var7, var8);
return queryRes;
};
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
sqliteDatabase.query.overload('java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function(var0, var1, var2, var3, var4, var5, var6, var7) {
var methodVal = "[*] SQLiteDatabase.query called.";
var logVal = "Table: " + var0 + ", selection value: " + var2 + ", selectionArgs: " + var3;
console.log(methodVal + " " + logVal + "\n");
var queryRes = this.query(var0, var1, var2, var3, var4, var5, var6, var7);
return queryRes;
};
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
sqliteDatabase.query.overload('boolean', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'android.os.CancellationSignal').implementation = function(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9) {
var methodVal = "[*] SQLiteDatabase.query called.";
var logVal = "Table: " + var1 + ", selection value: " + var3 + ", selectionArgs: " + var4;
console.log(methodVal + " " + logVal + "\n");
var queryRes = this.query(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9);
return queryRes;
};
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
sqliteDatabase.query.overload('java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function(var0, var1, var2, var3, var4, var5, var6) {
var methodVal = "[*] SQLiteDatabase.query called.";
var logVal = "Table: " + var0 + ", selection value: " + var2 + ", selectionArgs: " + var3;
console.log(methodVal + " " + logVal + "\n");
var queryRes = this.query(var0, var1, var2, var3, var4, var5, var6);
return queryRes;
};
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
sqliteDatabase.queryWithFactory.overload('android.database.sqlite.SQLiteDatabase$CursorFactory', 'boolean', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9) {
var methodVal = "[*] SQLiteDatabase.queryWithFactory called.";
var logVal = "Table: " + var2 + ", selection value: " + var4 + ", selectionArgs: " + var5 + " distinct: " + var1;
console.log(methodVal + " " + logVal + "\n");
var queryWithFactoryRes = this.queryWithFactory(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9);
return queryWithFactoryRes;
};
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
sqliteDatabase.queryWithFactory.overload('android.database.sqlite.SQLiteDatabase$CursorFactory', 'boolean', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'android.os.CancellationSignal').implementation = function(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9, var10) {
var methodVal = "[*] SQLiteDatabase.queryWithFactory called.";
var logVal = "Table: " + var2 + ", selection value: " + var4 + ", selectionArgs: " + var5 + " distinct: " + var1;
console.log(methodVal + " " + logVal + "\n");
var queryWithFactoryRes = this.queryWithFactory(var0, var1, var2, var3, var4, var5, var6, var7, var8, var9, var10);
return queryWithFactoryRes;
};
// rawQuery(String sql, String[] selectionArgs)
sqliteDatabase.rawQuery.overload('java.lang.String', '[Ljava.lang.String;').implementation = function(var0, var1) {
console.log("[*] SQLiteDatabase.rawQuery called with query: " + var0 + " and contentValues: " + var1 +"\n");
var rawQueryRes = this.rawQuery(var0, var1);
return rawQueryRes;
};
// rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal)
sqliteDatabase.rawQuery.overload('java.lang.String', '[Ljava.lang.String;', 'android.os.CancellationSignal').implementation = function(var0, var1, var2) {
console.log("[*] SQLiteDatabase.rawQuery called with query: " + var0 + " and contentValues: " + var1 +"\n");
var rawQueryRes = this.rawQuery(var0, var1, var2);
return rawQueryRes;
};
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal)
sqliteDatabase.rawQueryWithFactory.overload('android.database.sqlite.SQLiteDatabase$CursorFactory', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'android.os.CancellationSignal').implementation = function(var0, var1, var2, var3, var4) {
console.log("[*] SQLiteDatabase.rawQueryWithFactory called with query: " + var1 + " and contentValues: " + var2 + "\n");
var rawQueryWithFactoryRes = this.rawQueryWithFactory(var0, var1, var2, var3, var4);
return rawQueryWithFactoryRes;
};
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable)
sqliteDatabase.rawQueryWithFactory.overload('android.database.sqlite.SQLiteDatabase$CursorFactory', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String').implementation = function(var0, var1, var2, var3) {
console.log("[*] SQLiteDatabase.rawQueryWithFactory2 called with query: " + var1 + " and contentValues: " + var2 +"\n");
var rawQueryWithFactoryRes = this.rawQueryWithFactory(var0, var1, var2, var3);
return rawQueryWithFactoryRes;
};
// insert(String table, String nullColumnHack, ContentValues values)
sqliteDatabase.insert.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(var0, var1, var2) {
console.log("[*] SQLiteDatabase.insert called. Adding new value: " + var2 + " to database: " + var0 + "\n");
var insertValueRes = this.insert(var0, var1, var2);
return insertValueRes;
};
// insertOrThrow(String table, String nullColumnHack, ContentValues values)
sqliteDatabase.insertOrThrow.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(var0, var1, var2) {
console.log("[*] SQLiteDatabase.insertOrThrow called. Adding new value: " + var2 + " to database: " + var0 + "\n");
var insertValueRes = this.insertOrThrow(var0, var1, var2);
return insertValueRes;
};
// insertOrThrow(String table, String nullColumnHack, ContentValues values)
sqliteDatabase.insertOrThrow.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(var0, var1, var2) {
console.log("[*] SQLiteDatabase.insertOrThrow called. Adding new value: " + var2 + " to database: " + var0 + "\n");
var insertValueRes = this.insertOrThrow(var0, var1, var2);
return insertValueRes;
};
// insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm)
sqliteDatabase.insertWithOnConflict.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues', 'int').implementation = function(var0, var1, var2, var3) {
console.log("[*] SQLiteDatabase.insertWithOnConflict called. Adding new value: " + var2 + " to database: " + var0 + " and conflictAlgorithm: " + var3 + "\n");
var insertValueRes = this.insertWithOnConflict(var0, var1, var2, var3);
return insertValueRes;
};
// update(String table, ContentValues values, String whereClause, String[] whereArgs)
sqliteDatabase.update.overload('java.lang.String', 'android.content.ContentValues', 'java.lang.String', '[Ljava.lang.String;').implementation = function(var0, var1, var2, var3) {
var methodVal = "[*] SQLiteDatabase.update called.";
var logVal = "Update table: " + var0 + " with where clause: " + var2 + " whereArgs:" + var3.toString() + " and values to update: " + var1.toString() +"\n";
console.log(methodVal, logVal);
var updateRes = this.update(var0, var1, var2, var3);
return updateRes;
};
// updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)
sqliteDatabase.updateWithOnConflict.overload('java.lang.String', 'android.content.ContentValues', 'java.lang.String', '[Ljava.lang.String;', 'int').implementation = function(var0, var1, var2, var3, var4) {
var methodVal = "[*] SQLiteDatabase.updateWithOnConflict called.";
var logVal = "Update table: " + var0 + " with where clause: " + var2 + " whereArgs:" + var3 + " values to update: " + var1 + " and conflictAlgorithm: " + var4 +"\n";
console.log(methodVal, logVal);
var updateRes = this.updateWithOnConflict(var0, var1, var2, var3, var4);
return updateRes;
};
});
});

172
code/aesinfo.js Normal file
View File

@ -0,0 +1,172 @@
Java.perform(function() {
var use_single_byte = false;
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');
var ivParameterSpecDef_init_1 = ivParameterSpecDef.$init.overload('[B');
var ivParameterSpecDef_init_2 = ivParameterSpecDef.$init.overload('[B', 'int', 'int');
secretKeySpecDef_init_1.implementation = function(arr, alg) {
var key = b2s(arr);
send("Creating " + alg + " secret key, plaintext:\\n" + hexdump(key));
return secretKeySpecDef_init_1.call(this, arr, alg);
}
secretKeySpecDef_init_2.implementation = function(arr, off, len, alg) {
var key = b2s(arr);
send("Creating " + alg + " secret key, plaintext:\\n" + hexdump(key));
return secretKeySpecDef_init_2.call(this, arr, off, len, alg);
}
/*ivParameterSpecDef_init_1.implementation = function(arr)
{
var iv = b2s(arr);
send("Creating IV:\\n" + hexdump(iv));
return ivParameterSpecDef_init_1.call(this, arr);
}
ivParameterSpecDef_init_2.implementation = function(arr, off, len)
{
var iv = b2s(arr);
send("Creating IV, plaintext:\\n" + hexdump(iv));
return ivParameterSpecDef_init_2.call(this, arr, off, len);
}*/
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) {
send("Performing encryption/decryption");
if (iv) {
send("Initialization Vector: \\n" + hexdump(b2s(iv)));
} else {
send("Initialization Vector: " + iv);
}
send("Algorithm: " + alg);
send("In: \\n" + hexdump(b2s(plain)));
send("Out: \\n" + hexdump(b2s(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;
}
}
});

View File

@ -0,0 +1,13 @@
// Usage : frida -U -f bundle_id -l enable_debug.js --no-pause
// Blog link to be added
// Written by @67616d654661636 and @sunnyrockzzs
Java.perform(function() {
var Webview = Java.use("android.webkit.WebView")
Webview.loadUrl.overload("java.lang.String").implementation = function(url) {
console.log("\n[+]Loading URL from", url);
console.log("[+]Setting the value of setWebContentsDebuggingEnabled() to TRUE");
this.setWebContentsDebuggingEnabled(true);
this.loadUrl.overload("java.lang.String").call(this, url);
}
});

View File

@ -0,0 +1,730 @@
/* 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) pinner');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
} catch (err) {
console.log('[-] TrustManager (Android < 7) pinner not found');
//console.log(err);
}
// OkHTTPv3 (quadruple bypass) //
/////////////////////////////////
try {
// Bypass OkHTTPv3 {1}
var 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 {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {1} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {2}
// This method of CertificatePinner.check is deprecated but could be found in some old Android apps
var 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 {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {2} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {3}
var 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 {3}: ' + a);
return;
};
} catch(err) {
console.log('[-] OkHTTPv3 {3} pinner not found');
//console.log(err);
}
try {
// Bypass OkHTTPv3 {4}
var okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner');
//okhttp3_Activity_4['check$okhttp'].implementation = function(a, b) {
okhttp3_Activity_4.check$okhttp.overload('java.lang.String', 'kotlin.jvm.functions.Function0').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {4}: ' + a);
return;
};
} catch(err) {
console.log('[-] OkHTTPv3 {4} pinner not found');
//console.log(err);
}
// Trustkit (triple bypass) //
//////////////////////////////
try {
// Bypass Trustkit {1}
var 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 {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {1} pinner not found');
//console.log(err);
}
try {
// Bypass Trustkit {2}
var 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 {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {2} pinner not found');
//console.log(err);
}
try {
// Bypass Trustkit {3}
var trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');
trustkit_PinningTrustManager.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String').implementation = function(chain, authType) {
console.log('[+] Bypassing Trustkit {3}');
//return;
};
} catch (err) {
console.log('[-] Trustkit {3} pinner not found');
//console.log(err);
}
// TrustManagerImpl (Android > 7) //
////////////////////////////////////
try {
// Bypass TrustManagerImpl (Android > 7) {1}
var array_list = Java.use("java.util.ArrayList");
var TrustManagerImpl_Activity_1 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl_Activity_1.checkTrustedRecursive.implementation = function(certs, ocspData, tlsSctData, host, clientAuth, untrustedChain, trustAnchorChain, used) {
console.log('[+] Bypassing TrustManagerImpl (Android > 7) checkTrustedRecursive check: '+ host);
return array_list.$new();
};
} catch (err) {
console.log('[-] TrustManagerImpl (Android > 7) checkTrustedRecursive check not found');
//console.log(err);
}
try {
// Bypass TrustManagerImpl (Android > 7) {2} (probably no more necessary)
var TrustManagerImpl_Activity_2 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl_Activity_2.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log('[+] Bypassing TrustManagerImpl (Android > 7) verifyChain check: ' + host);
return untrustedChain;
};
} catch (err) {
console.log('[-] TrustManagerImpl (Android > 7) verifyChain check not found');
//console.log(err);
}
// Appcelerator Titanium PinningTrustManager //
///////////////////////////////////////////////
try {
var appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
appcelerator_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Bypassing Appcelerator PinningTrustManager');
return;
};
} catch (err) {
console.log('[-] Appcelerator PinningTrustManager pinner not found');
//console.log(err);
}
// Fabric PinningTrustManager //
////////////////////////////////
try {
var fabric_PinningTrustManager = Java.use('io.fabric.sdk.android.services.network.PinningTrustManager');
fabric_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Bypassing Fabric PinningTrustManager');
return;
};
} catch (err) {
console.log('[-] Fabric PinningTrustManager pinner not found');
//console.log(err);
}
// OpenSSLSocketImpl Conscrypt (double bypass) //
/////////////////////////////////////////////////
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, JavaObject, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt {1}');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Conscrypt {1} pinner not found');
//console.log(err);
}
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certChain, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt {2}');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Conscrypt {2} pinner not found');
//console.log(err);
}
// OpenSSLEngineSocketImpl Conscrypt //
///////////////////////////////////////
try {
var 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);
};
} 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 //
////////////////////////////////////
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(a, b, c) {
console.log('[+] Bypassing PhoneGap sslCertificateChecker: ' + a);
return true;
};
} catch (err) {
console.log('[-] PhoneGap sslCertificateChecker pinner not found');
//console.log(err);
}
// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) //
////////////////////////////////////////////////////////////////////
try {
// Bypass IBM MobileFirst {1}
var 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 {1}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {1} pinner not found');
//console.log(err);
}
try {
// Bypass IBM MobileFirst {2}
var 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 {2}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {2} pinner not found');
//console.log(err);
}
// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) //
///////////////////////////////////////////////////////////////////////////////////////////////////////
try {
// Bypass IBM WorkLight {1}
var 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 {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {1} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {2}
var 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 {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {2} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {3}
var 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 {3}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {3} pinner not found');
//console.log(err);
}
try {
// Bypass IBM WorkLight {4}
var 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 {4}: ' + a);
return true;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {4} pinner not found');
//console.log(err);
}
// Conscrypt CertPinManager //
//////////////////////////////
try {
var conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
conscrypt_CertPinManager_Activity.checkChainPinning.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing Conscrypt CertPinManager: ' + a);
//return;
return true;
};
} catch (err) {
console.log('[-] Conscrypt CertPinManager pinner not found');
//console.log(err);
}
// Conscrypt CertPinManager (Legacy) //
///////////////////////////////////////
try {
var legacy_conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
legacy_conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing Conscrypt CertPinManager (Legacy): ' + a);
return true;
};
} catch (err) {
console.log('[-] Conscrypt CertPinManager (Legacy) 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(a, b) {
console.log('[+] Bypassing CWAC-Netsecurity CertPinManager: ' + a);
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(a, b, c) {
console.log('[+] Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a);
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 {
// Bypass Squareup CertificatePinner {1}
var 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 {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {1} pinner not found');
//console.log(err);
}
try {
// Bypass Squareup CertificatePinner {2}
var 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 {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {2} pinner not found');
//console.log(err);
}
// Squareup OkHostnameVerifier [OkHTTP v3] (double bypass) //
/////////////////////////////////////////////////////////////
try {
// Bypass Squareup OkHostnameVerifier {1}
var 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 {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier check not found');
//console.log(err);
}
try {
// Bypass Squareup OkHostnameVerifier {2}
var 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 {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier check not found');
//console.log(err);
}
// Android WebViewClient (quadruple bypass) //
//////////////////////////////////////////////
try {
// Bypass WebViewClient {1} (deprecated from Android 6)
var 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 check {1}');
};
} catch (err) {
console.log('[-] Android WebViewClient {1} check not found');
//console.log(err)
}
try {
// Bypass WebViewClient {2}
var 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 check {2}');
};
} catch (err) {
console.log('[-] Android WebViewClient {2} check not found');
//console.log(err)
}
try {
// Bypass WebViewClient {3}
var AndroidWebViewClient_Activity_3 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_3.onReceivedError.overload('android.webkit.WebView', 'int', 'java.lang.String', 'java.lang.String').implementation = function(obj1, obj2, obj3, obj4) {
console.log('[+] Bypassing Android WebViewClient check {3}');
};
} catch (err) {
console.log('[-] Android WebViewClient {3} check not found');
//console.log(err)
}
try {
// Bypass WebViewClient {4}
var AndroidWebViewClient_Activity_4 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_4.onReceivedError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function(obj1, obj2, obj3) {
console.log('[+] Bypassing Android WebViewClient check {4}');
};
} catch (err) {
console.log('[-] Android WebViewClient {4} check 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 check');
obj3.proceed();
};
} catch (err) {
console.log('[-] Apache Cordova WebViewClient check 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 check: ' + host);
};
} catch (err) {
console.log('[-] Boye AbstractVerifier check not found');
//console.log(err);
}
// Apache AbstractVerifier //
/////////////////////////////
try {
var apache_AbstractVerifier = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
apache_AbstractVerifier.verify.implementation = function(a, b, c, d) {
console.log('[+] Bypassing Apache AbstractVerifier check: ' + a);
return;
};
} catch (err) {
console.log('[-] Apache AbstractVerifier check not found');
//console.log(err);
}
// Chromium Cronet //
/////////////////////
try {
var CronetEngineBuilderImpl_Activity = Java.use("org.chromium.net.impl.CronetEngineBuilderImpl");
// Setting argument to TRUE (default is TRUE) to disable Public Key pinning for local trust anchors
CronetEngine_Activity.enablePublicKeyPinningBypassForLocalTrustAnchors.overload('boolean').implementation = function(a) {
console.log("[+] Disabling Public Key pinning for local trust anchors in Chromium Cronet");
var cronet_obj_1 = CronetEngine_Activity.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);
return cronet_obj_1;
};
// Bypassing Chromium Cronet pinner
CronetEngine_Activity.addPublicKeyPins.overload('java.lang.String', 'java.util.Set', 'boolean', 'java.util.Date').implementation = function(hostName, pinsSha256, includeSubdomains, expirationDate) {
console.log("[+] Bypassing Chromium Cronet pinner: " + hostName);
var cronet_obj_2 = CronetEngine_Activity.addPublicKeyPins.call(this, hostName, pinsSha256, includeSubdomains, expirationDate);
return cronet_obj_2;
};
} catch (err) {
console.log('[-] Chromium Cronet pinner not found')
//console.log(err);
}
// Flutter Pinning packages http_certificate_pinning and ssl_pinning_plugin (double bypass) //
//////////////////////////////////////////////////////////////////////////////////////////////
try {
// Bypass HttpCertificatePinning.check {1}
var HttpCertificatePinning_Activity = Java.use('diefferson.http_certificate_pinning.HttpCertificatePinning');
HttpCertificatePinning_Activity.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function (a, b, c ,d, e) {
console.log('[+] Bypassing Flutter HttpCertificatePinning : ' + a);
return true;
};
} catch (err) {
console.log('[-] Flutter HttpCertificatePinning pinner not found');
//console.log(err);
}
try {
// Bypass SslPinningPlugin.check {2}
var SslPinningPlugin_Activity = Java.use('com.macif.plugin.sslpinningplugin.SslPinningPlugin');
SslPinningPlugin_Activity.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function (a, b, c ,d, e) {
console.log('[+] Bypassing Flutter SslPinningPlugin: ' + a);
return true;
};
} catch (err) {
console.log('[-] Flutter SslPinningPlugin pinner not found');
//console.log(err);
}
// Dynamic SSLPeerUnverifiedException Patcher //
// An useful technique to bypass SSLPeerUnverifiedException failures raising //
// when the Android app uses some uncommon SSL Pinning methods or an heavily //
// code obfuscation. Inspired by an idea of: https://github.com/httptoolkit //
///////////////////////////////////////////////////////////////////////////////
function rudimentaryFix(typeName) {
// This is a improvable rudimentary fix, if not works you can patch it manually
if (typeName === undefined){
return;
} else if (typeName === 'boolean') {
return true;
} else {
return null;
}
}
try {
var UnverifiedCertError = Java.use('javax.net.ssl.SSLPeerUnverifiedException');
UnverifiedCertError.$init.implementation = function (str) {
console.log('\x1b[36m[!] Unexpected SSLPeerUnverifiedException occurred, trying to patch it dynamically...\x1b[0m');
try {
var stackTrace = Java.use('java.lang.Thread').currentThread().getStackTrace();
var exceptionStackIndex = stackTrace.findIndex(stack =>
stack.getClassName() === "javax.net.ssl.SSLPeerUnverifiedException"
);
// Retrieve the method raising the SSLPeerUnverifiedException
var callingFunctionStack = stackTrace[exceptionStackIndex + 1];
var className = callingFunctionStack.getClassName();
var methodName = callingFunctionStack.getMethodName();
var callingClass = Java.use(className);
var callingMethod = callingClass[methodName];
console.log('\x1b[36m[!] Attempting to bypass uncommon SSL Pinning method on: '+className+'.'+methodName+'\x1b[0m');
// Skip it when already patched by Frida
if (callingMethod.implementation) {
return;
}
// Trying to patch the uncommon SSL Pinning method via implementation
var returnTypeName = callingMethod.returnType.type;
callingMethod.implementation = function() {
rudimentaryFix(returnTypeName);
};
} catch (e) {
// Dynamic patching via implementation does not works, then trying via function overloading
//console.log('[!] The uncommon SSL Pinning method has more than one overload);
if (String(e).includes(".overload")) {
var splittedList = String(e).split(".overload");
for (let i=2; i<splittedList.length; i++) {
var extractedOverload = splittedList[i].trim().split("(")[1].slice(0,-1).replaceAll("'","");
// Check if extractedOverload has multiple arguments
if (extractedOverload.includes(",")) {
// Go here if overloaded method has multiple arguments (NOTE: max 6 args are covered here)
var argList = extractedOverload.split(", ");
console.log('\x1b[36m[!] Attempting overload of '+className+'.'+methodName+' with arguments: '+extractedOverload+'\x1b[0m');
if (argList.length == 2) {
callingMethod.overload(argList[0], argList[1]).implementation = function(a,b) {
rudimentaryFix(returnTypeName);
}
} else if (argNum == 3) {
callingMethod.overload(argList[0], argList[1], argList[2]).implementation = function(a,b,c) {
rudimentaryFix(returnTypeName);
}
} else if (argNum == 4) {
callingMethod.overload(argList[0], argList[1], argList[2], argList[3]).implementation = function(a,b,c,d) {
rudimentaryFix(returnTypeName);
}
} else if (argNum == 5) {
callingMethod.overload(argList[0], argList[1], argList[2], argList[3], argList[4]).implementation = function(a,b,c,d,e) {
rudimentaryFix(returnTypeName);
}
} else if (argNum == 6) {
callingMethod.overload(argList[0], argList[1], argList[2], argList[3], argList[4], argList[5]).implementation = function(a,b,c,d,e,f) {
rudimentaryFix(returnTypeName);
}
}
// Go here if overloaded method has a single argument
} else {
callingMethod.overload(extractedOverload).implementation = function(a) {
rudimentaryFix(returnTypeName);
}
}
}
} else {
console.log('\x1b[36m[-] Failed to dynamically patch SSLPeerUnverifiedException '+e+'\x1b[0m');
}
}
//console.log('\x1b[36m[+] SSLPeerUnverifiedException hooked\x1b[0m');
return this.$init(str);
};
} catch (err) {
//console.log('\x1b[36m[-] SSLPeerUnverifiedException not found\x1b[0m');
//console.log('\x1b[36m'+err+'\x1b[0m');
}
});
}, 0);

View File

@ -0,0 +1,32 @@
function native_log(type,tag,msg){
var tag_new = Memory.allocUtf8String(tag)
var msg_new = Memory.allocUtf8String(msg)
var param_type_list = ["int","pointer","pointer","..."]
var print_ptr = Module.getExportByName("liblog.so","__android_log_print")
const print = new NativeFunction(print_ptr, 'int', param_type_list)
print(type,tag_new,msg_new)
}
function logv(tag,msg){
native_log(2,tag,msg)
}
function logd(tag,msg){
native_log(3,tag,msg)
}
function logi(tag,msg){
native_log(4,tag,msg)
}
function logw(tag,msg){
native_log(5,tag,msg)
}
function loge(tag,msg){
native_log(6,tag,msg)
}
function logf(tag,msg){
native_log(7,tag,msg)
}

View File

@ -0,0 +1,17 @@
// frida -U -l network-security-config-bypass.js --no-pause -f your.package.name
Java.perform(function() {
NetworkSecurityConfig_Builder = Java.use("android.security.net.config.NetworkSecurityConfig$Builder")
CertificatesEntryRef = Java.use("android.security.net.config.CertificatesEntryRef")
CertificateSource = Java.use("android.security.net.config.CertificateSource")
UserCertificateSource = Java.use("android.security.net.config.UserCertificateSource")
NetworkSecurityConfig_Builder.getEffectiveCertificatesEntryRefs.implementation = function() {
origin = this.getEffectiveCertificatesEntryRefs()
source = UserCertificateSource.getInstance()
userCert = CertificatesEntryRef.$new(source, true)
origin.add(userCert)
return origin
}
})

View File

@ -0,0 +1,23 @@
setTimeout(function() {
Java.perform(function() {
console.log('')
console.log("# OkHTTP proxy");
var OkHttpClient = Java.use("okhttp3.OkHttpClient");
var OkHttpBuilder = Java.use("okhttp3.OkHttpClient$Builder");
var Proxy = Java.use("java.net.Proxy");
var ProxyType = Java.use("java.net.Proxy$Type");
var InetSocketAddress = Java.use("java.net.InetSocketAddress");
var proxy = Proxy.$new(ProxyType.HTTP.value, InetSocketAddress.createUnresolved("1.2.3.4", 5678));
OkHttpClient.newBuilder.overload().implementation = function() {
return OkHttpBuilder.$new();
}
OkHttpBuilder.build.overload().implementation = function() {
console.log('[+] Installing proxy');
this.proxy(proxy);
return this.build();
}
})
}, 0)

View File

@ -0,0 +1,63 @@
/*
* Description: OkHttp3 various SSL Pinning bypasses, including versions 4.2+.
* Authors: @apps3c and @pcipolloni
*/
setTimeout(function() {
Java.perform(function () {
var okhttp3_CertificatePinner_class = null;
try {
okhttp3_CertificatePinner_class = Java.use('okhttp3.CertificatePinner');
} catch (err) {
console.log('[-] OkHTTPv3 CertificatePinner class not found. Skipping.');
okhttp3_CertificatePinner_class = null;
}
if(okhttp3_CertificatePinner_class != null) {
try{
okhttp3_CertificatePinner_class.check.overload('java.lang.String', 'java.util.List').implementation = function (str,list) {
console.log('[+] Bypassing OkHTTPv3 1: ' + str);
return true;
};
console.log('[+] Loaded OkHTTPv3 hook 1');
} catch(err) {
console.log('[-] Skipping OkHTTPv3 hook 1');
}
try{
okhttp3_CertificatePinner_class.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (str,cert) {
console.log('[+] Bypassing OkHTTPv3 2: ' + str);
return true;
};
console.log('[+] Loaded OkHTTPv3 hook 2');
} catch(err) {
console.log('[-] Skipping OkHTTPv3 hook 2');
}
try {
okhttp3_CertificatePinner_class.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function (str,cert_array) {
console.log('[+] Bypassing OkHTTPv3 3: ' + str);
return true;
};
console.log('[+] Loaded OkHTTPv3 hook 3');
} catch(err) {
console.log('[-] Skipping OkHTTPv3 hook 3');
}
try {
okhttp3_CertificatePinner_class['check$okhttp'].implementation = function (str,obj) {
console.log('[+] Bypassing OkHTTPv3 4 (4.2+): ' + str);
};
console.log('[+] Loaded OkHTTPv3 hook 4 (4.2+)');
} catch(err) {
console.log('[-] Skipping OkHTTPv3 hook 4 (4.2+)');
}
}
});
}, 0);

View File

@ -0,0 +1,16 @@
function killUIWebViewSSL() {
Interceptor.attach(ObjC.classes.UIWebView["- webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:"].implementation, {
onLeave: function(retval) {
retval.replace(ptr('0x1'));
}
});
Interceptor.attach(ObjC.classes.UIWebView["- webView:resource:didReceiveAuthenticationChallenge:fromDataSource:"].implementation, {
onEnter: function(args) {
const chall = new ObjC.Object(args[4]);
const sender = chall.sender();
const cred = ObjC.classes.NSURLCredential.credentialForTrust_(chall.protectionSpace().serverTrust());
sender.useCredential_forAuthenticationChallenge_(cred, chall);
}
});
}

View File

@ -0,0 +1,66 @@
/*
Android SSL Re-pinning frida script v0.2 030417-pier
$ adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt
$ frida -U -f it.app.mobile -l frida-android-repinning.js --no-pause
https://techblog.mediaservice.net/2017/07/universal-android-ssl-pinning-bypass-with-frida/
UPDATE 20191605: Fixed undeclared var. Thanks to @oleavr and @ehsanpc9999 !
*/
setTimeout(function(){
Java.perform(function (){
console.log("");
console.log("[.] Cert Pinning Bypass/Re-Pinning");
var CertificateFactory = Java.use("java.security.cert.CertificateFactory");
var FileInputStream = Java.use("java.io.FileInputStream");
var BufferedInputStream = Java.use("java.io.BufferedInputStream");
var X509Certificate = Java.use("java.security.cert.X509Certificate");
var KeyStore = Java.use("java.security.KeyStore");
var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");
var SSLContext = Java.use("javax.net.ssl.SSLContext");
// Load CAs from an InputStream
console.log("[+] Loading our CA...")
var cf = CertificateFactory.getInstance("X.509");
try {
var fileInputStream = FileInputStream.$new("/data/local/tmp/cert-der.crt");
}
catch(err) {
console.log("[o] " + err);
}
var bufferedInputStream = BufferedInputStream.$new(fileInputStream);
var ca = cf.generateCertificate(bufferedInputStream);
bufferedInputStream.close();
var certInfo = Java.cast(ca, X509Certificate);
console.log("[o] Our CA Info: " + certInfo.getSubjectDN());
// Create a KeyStore containing our trusted CAs
console.log("[+] Creating a KeyStore for our CA...");
var keyStoreType = KeyStore.getDefaultType();
var keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
console.log("[+] Creating a TrustManager that trusts the CA in our KeyStore...");
var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
console.log("[+] Our TrustManager is ready...");
console.log("[+] Hijacking SSLContext methods now...")
console.log("[-] Waiting for the app to invoke SSLContext.init()...")
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation = function(a,b,c) {
console.log("[o] App invoked javax.net.ssl.SSLContext.init...");
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").call(this, a, tmf.getTrustManagers(), c);
console.log("[+] SSLContext initialized with our custom TrustManager!");
}
});
},0);