diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-adb-detection.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-adb-detection.js new file mode 100644 index 0000000000..2f627fee6d --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-adb-detection.js @@ -0,0 +1,207 @@ +/* + Description: Android ADB Detection Bypass frida script + Credit: meerkati + + Useful when bypassing USB debugging detection on Android! + If it doesn't work, remove the conditional statement + + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/DebugMode_Emulator/android-adb-detection-bypass.js + Link: + https://developer.android.com/reference/android/os/Build.VERSION +*/ + +setTimeout(function() +{ + Java.perform(function() + { + var androidSettings = ['adb_enabled']; + var sdkVersion = Java.use('android.os.Build$VERSION'); + console.log("SDK Version : " + sdkVersion.SDK_INT.value); + + /* API 16 or lower Settings.Global Hook */ + if (sdkVersion.SDK_INT.value <= 16) + { + var settingSecure = Java.use('android.provider.Settings$Secure'); + + settingSecure.getInt.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingSecure.getInt(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Secure.getInt(cr, name) Bypassed'); + return 0; + } + var ret = this.getInt(cr, name); + return ret; + } + + settingSecure.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').implementation = function(cr, name, def) + { + //console.log("[*]settingSecure.getInt(cr,name,def) : " + name); + if (name == (androidSettings[0])) + { + console.log('[+]Secure.getInt(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getInt(cr, name, def); + return ret; + } + + settingSecure.getFloat.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingSecure.getFloat(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Secure.getFloat(cr, name) Bypassed'); + return 0; + } + var ret = this.getFloat(cr, name) + return ret; + } + + settingSecure.getFloat.overload('android.content.ContentResolver', 'java.lang.String', 'float').implementation = function(cr, name, def) + { + //console.log("[*]settingSecure.getFloat(cr,name,def) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Secure.getFloat(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getFloat(cr, name, def); + return ret; + } + + settingSecure.getLong.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingSecure.getLong(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Secure.getLong(cr, name) Bypassed'); + return 0; + } + var ret = this.getLong(cr, name) + return ret; + } + + settingSecure.getLong.overload('android.content.ContentResolver', 'java.lang.String', 'long').implementation = function(cr, name, def) + { + //console.log("[*]settingSecure.getLong(cr,name,def) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Secure.getLong(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getLong(cr, name, def); + return ret; + } + + settingSecure.getString.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingSecure.getString(cr,name) : " + name); + if (name == androidSettings[0]) + { + var stringClass = Java.use("java.lang.String"); + var stringInstance = stringClass.$new("0"); + + console.log('[+]Secure.getString(cr, name) Bypassed'); + return stringInstance; + } + var ret = this.getString(cr, name); + return ret; + } + } + + /* API 17 or higher Settings.Global Hook */ + if (sdkVersion.SDK_INT.value >= 17) + { + var settingGlobal = Java.use('android.provider.Settings$Global'); + + settingGlobal.getInt.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingGlobal.getInt(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Global.getInt(cr, name) Bypassed'); + return 0; + } + var ret = this.getInt(cr, name); + return ret; + } + + settingGlobal.getInt.overload('android.content.ContentResolver', 'java.lang.String', 'int').implementation = function(cr, name, def) + { + //console.log("[*]settingGlobal.getInt(cr,name,def) : " + name); + if (name == (androidSettings[0])) + { + console.log('[+]Global.getInt(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getInt(cr, name, def); + return ret; + } + + settingGlobal.getFloat.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingGlobal.getFloat(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Global.getFloat(cr, name) Bypassed'); + return 0; + } + var ret = this.getFloat(cr, name); + return ret; + } + + settingGlobal.getFloat.overload('android.content.ContentResolver', 'java.lang.String', 'float').implementation = function(cr, name, def) + { + //console.log("[*]settingGlobal.getFloat(cr,name,def) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Global.getFloat(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getFloat(cr, name, def); + return ret; + } + + settingGlobal.getLong.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingGlobal.getLong(cr,name) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Global.getLong(cr, name) Bypassed'); + return 0; + } + var ret = this.getLong(cr, name); + return ret; + } + + settingGlobal.getLong.overload('android.content.ContentResolver', 'java.lang.String', 'long').implementation = function(cr, name, def) + { + //console.log("[*]settingGlobal.getLong(cr,name,def) : " + name); + if (name == androidSettings[0]) + { + console.log('[+]Global.getLong(cr, name, def) Bypassed'); + return 0; + } + var ret = this.getLong(cr, name, def); + return ret; + } + + settingGlobal.getString.overload('android.content.ContentResolver', 'java.lang.String').implementation = function(cr, name) + { + //console.log("[*]settingGlobal.getString(cr,name) : " + name); + if (name == androidSettings[0]) + { + var stringClass = Java.use("java.lang.String"); + var stringInstance = stringClass.$new("0"); + + console.log('[+]Global.getString(cr, name) Bypassed'); + return stringInstance; + } + var ret = this.getString(cr, name); + return ret; + } + } + }); +}, 0); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-emulator-detection.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-emulator-detection.js new file mode 100644 index 0000000000..884535df9f --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/bypass-emulator-detection.js @@ -0,0 +1,214 @@ +/* + Description: Android Emulator Detection Bypass frida script + Credit: @Areizen_ + + Useful when bypassing USB debugging detection on Android! + If it doesn't work, remove the conditional statement + + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/DebugMode_Emulator/android-emulator-detection-bypass.js + Link: + https://developer.android.com/reference/android/os/Build.VERSION +*/ + +Java.perform(function() +{ + console.log("--> Anti Emulator Detection Bypass (aka BluePill) - Script Loaded") + /*********************************************************** + *** IMPORTANT *** + uncomment instructions below to skip one or more bypasses + /***********************************************************/ + bypass_build_properties() + bypass_phonenumber() + bypass_deviceid() + bypass_imsi() + bypass_operator_name() + bypass_sim_operator_name() + bypass_has_file() + bypass_processbuilder() + bypass_system_properties() +}); + + +function replaceFinaleField(object, fieldName, value) +{ + var field = object.class.getDeclaredField(fieldName) + field.setAccessible(true) + field.set(null, value) +} + +function bypass_build_properties() +{ + console.log("Build Properties - Bypass Loaded") + // Class containing const that we want to modify + const Build = Java.use("android.os.Build") + + // reflection class for changing const + const Field = Java.use('java.lang.reflect.Field') + const Class = Java.use('java.lang.Class') + + // Replacing Build static fields + replaceFinaleField(Build, "FINGERPRINT", "abcd/C1505:4.1.1/11.3.A.2.13:user/release-keys") + replaceFinaleField(Build, "MODEL", "C1505") + replaceFinaleField(Build, "MANUFACTURER", "Sony") + replaceFinaleField(Build, "BRAND", "Xperia") + replaceFinaleField(Build, "BOARD", "7x27") + replaceFinaleField(Build, "ID", "11.3.A.2.13") + replaceFinaleField(Build, "SERIAL", "abcdef123") + replaceFinaleField(Build, "TAGS", "release-keys") + replaceFinaleField(Build, "USER", "administrator") +} + +function bypass_phonenumber() +{ + console.log("Phone Number - Bypass Loaded") + const TelephonyManager = Java.use('android.telephony.TelephonyManager') + + TelephonyManager.getLine1Number.overload().implementation = function() + { + console.log("Phone number - bypass done!") + return "060102030405" + } +} + +function bypass_deviceid() +{ + console.log("Device ID - Bypass Loaded") + const TelephonyManager = Java.use('android.telephony.TelephonyManager') + + TelephonyManager.getDeviceId.overload().implementation = function() + { + console.log("Device ID - bypass done!") + return "012343545456445" + } +} + +function bypass_imsi() +{ + console.log("IMSI - Bypass Loaded") + const TelephonyManager = Java.use('android.telephony.TelephonyManager') + + TelephonyManager.getSubscriberId.overload().implementation = function() + { + console.log("Device ID (getSubscriberId) - bypass done!") + return "310260000000111" + } +} + +function bypass_operator_name() +{ + console.log("Operator Name - Bypass Loaded") + const TelephonyManager = Java.use('android.telephony.TelephonyManager') + + TelephonyManager.getNetworkOperatorName.overload().implementation = function() + { + console.log("Operator Name - bypass done!") + return "not" + } +} + +function bypass_sim_operator_name() +{ + console.log("SIM Operator Name - Bypass Loaded") + const TelephonyManager = Java.use('android.telephony.TelephonyManager') + + TelephonyManager.getSimOperatorName.overload().implementation = function() + { + console.log("SIM Operator Name - bypass done!") + return "not" + } +} + +function bypass_has_file() +{ + console.log("Emulator related files check - Bypass Loaded") + const File = Java.use("java.io.File") + const KnownFiles= [ + "ueventd.android_x86.rc", + "x86.prop", + "ueventd.ttVM_x86.rc", + "init.ttVM_x86.rc", + "fstab.ttVM_x86", + "fstab.vbox86", + "init.vbox86.rc", + "ueventd.vbox86.rc", + "/dev/socket/qemud", + "/dev/qemu_pipe", + "/system/lib/libc_malloc_debug_qemu.so", + "/sys/qemu_trace", + "/system/bin/qemu-props", + "/dev/socket/genyd", + "/dev/socket/baseband_genyd", + "/proc/tty/drivers", + "/proc/cpuinfo" + ] + + File.exists.implementation = function () + { + var x = this.getAbsolutePath(); + for(var i=0; i + { + + //Create a new instance of HttpLoggingInterceptor class + function getInterceptor() + { + try + { + const HttpLoggingInterceptor = Java.use('okhttp3.logging.HttpLoggingInterceptor'); + const Level = Java.use('okhttp3.logging.HttpLoggingInterceptor$Level'); + + const MyLogger = Java.registerClass( + { + name: 'MyLogger', + superClass: Java.use('java.lang.Object'), + implements: [Java.use('okhttp3.logging.HttpLoggingInterceptor$Logger')], + methods: + { + log: [ + { + returnType: 'void', + argumentTypes: ['java.lang.String'], + implementation: function(message) + { + send(' [LOG] ' + message); + } + }] + }, + }); + + var logInstance = HttpLoggingInterceptor.$new(MyLogger.$new()); + + //If you want to log at the logcat just change to the line bellow + //var logInstance = HttpLoggingInterceptor.$new(); + logInstance.setLevel(Level.BODY.value); + + return logInstance; + + } + catch (err) + { + send("[-] Error creating interceptor") + send(err); + send(err.stack) + return null; + } + } + + try + { + var Builder = Java.use('okhttp3.OkHttpClient$Builder') + var build = Builder.build.overload(); + + build.implementation = function() + { + send('[+] OkHttpClient$Builder ==> Adding log interceptor') + + //Add the new interceptor before call the 'build' function + try + { + this.addInterceptor(getInterceptor()); + } + catch (err) + { + send('[-] OkHttpClient$Builder.addInterceptor error'); + } + + return build.call(this); + } + } + catch (err) + { + send('[-] OkHttpClient$Builder error'); + send(err); + } + }); +}, 1000); + + +Java.perform(function() +{ + function okhttp3RealCall(){ + var OkHttpClient = Java.use("okhttp3.OkHttpClient"); + var RealCall = Java.use("okhttp3.RealCall"); + var Buffer = Java.use("okio.Buffer"); + var StandardCharsets = Java.use("java.nio.charset.StandardCharsets"); + + RealCall.getResponseWithInterceptorChain.implementation = function() + { + var response = this.getResponseWithInterceptorChain() + var request = response.request() + send("REQUEST: " + request) + send(request.headers()) + var body = ""; + + if (request.headers().get("content-type") === "application/x-www-form-urlencoded") + { + var buffer = Buffer.$new() + request.body().writeTo(buffer) + body = buffer.readString(StandardCharsets.UTF_8.value) + } + + send(body) + send("RESPONSE: " + response) + send(response.headers()) + return response + } + } + try{ + okhttp3RealCall(); + } catch(err){} +}); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-change-sdk-version.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-change-sdk-version.js new file mode 100644 index 0000000000..b3386dbffd --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-change-sdk-version.js @@ -0,0 +1,12 @@ +/* + Description: Android SDK version changer frida script + Credit: Unknown + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/android-sdk-version-change.js + https://developer.android.com/reference/android/os/Build.VERSION +*/ + +Java.perform(function() +{ + var ver = Java.use('android.os.Build$VERSION'); + ver.SDK_INT.value = 15; +}); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-spoof-gps.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-spoof-gps.js new file mode 100644 index 0000000000..c0a07a9075 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-android-spoof-gps.js @@ -0,0 +1,35 @@ +/* + Description: Android GPS Location Spoofing + Credit: @rsenet + + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/Location/android-location-spoofing.js + Link: + https://developer.android.com/reference/android/location/Location +*/ + +const lat = 10.0000000; +const lng = 10.0000000; +const alt = 10.0000000; + +Java.perform(function () +{ + var Location = Java.use("android.location.Location"); + + Location.getLatitude.implementation = function() + { + send("Changing Latitude to " + lat); + return lat; + } + + Location.getLongitude.implementation = function() + { + send("Changing Longitude to " + lng); + return lng; + } + + Location.getAltitude.implementation = function() + { + send("Changing Altitude to " + alt); + return alt; + } +}) \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-heap-search.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-heap-search.js new file mode 100644 index 0000000000..4800eed8b9 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/helper-heap-search.js @@ -0,0 +1,54 @@ +/************************************************************************ + * Name: Heap Search and method call + * OS: Android + * Author: @mobilesecurity_ + * Source: https://github.com/m0bilesecurity + * Info: make sure to replace placeholders + * {className} + * {classMethod} + * {args} +*************************************************************************/ + + +Java.performNow(function () { + var classname = "{className}" + var classmethod = "{classMethod}"; + + Java.choose(classname, { + onMatch: function (instance) { + try + { + var returnValue; + //{methodSignature} + returnValue = instance.{classMethod}({args}); //<-- replace v[i] with the value that you want to pass + + //Output + var s = ""; + s=s + "[*] Heap Search - START\\n" + + s=s + "Instance Found: " + instance.toString() + "\\n"; + s=s + "Calling method: \\n"; + s=s + " Class: " + classname + "\\n" + s=s + " Method: " + classmethod + "\\n" + s=s + "-->Output: " + returnValue + "\\n"; + + s = s + "[*] Heap Search - END\\n" + + send(s); + } + catch (err) + { + var s = ""; + s=s + "[*] Heap Search - START\\n" + s=s + "Instance NOT Found or Exception while calling the method\\n"; + s=s + " Class: " + classname + "\\n" + s=s + " Method: " + classmethod + "\\n" + s=s + "-->Exception: " + err + "\\n" + s=s + "[*] Heap Search - END\\n" + send(s) + } + + } + }); + +}); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-bluetooth.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-bluetooth.js new file mode 100644 index 0000000000..849719e1fb --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-bluetooth.js @@ -0,0 +1,69 @@ + +/* + Credit: optiv + Link: + https://github.com/optiv/blemon +*/ + +var Color = +{ + Reset: "\x1b[39;49;00m", + Black: "\x1b[30;01m", Blue: "\x1b[34;01m", Cyan: "\x1b[36;01m", Gray: "\x1b[37;11m", + Green: "\x1b[32;01m", Purple: "\x1b[35;01m", Red: "\x1b[31;01m", Yellow: "\x1b[33;01m", + Light: + { + Black: "\x1b[30;11m", Blue: "\x1b[34;11m", Cyan: "\x1b[36;11m", Gray: "\x1b[37;01m", + Green: "\x1b[32;11m", Purple: "\x1b[35;11m", Red: "\x1b[31;11m", Yellow: "\x1b[33;11m" + } +}; + +// thanks: https://awakened1712.github.io/hacking/hacking-frida/ +function bytes2hex(array) +{ + var result = ''; + for (var i = 0; i < array.length; ++i) + result += ('0' + (array[i] & 0xFF).toString(16)).slice(-2); + return result; +}; + + +Java.perform(function () +{ + var BTGattCB = Java.use("android.bluetooth.BluetoothGattCallback"); + // https://github.com/frida/frida/issues/310#issuecomment-462447292 + + BTGattCB.$init.overload().implementation = function () + { + console.log("[+] BluetoothGattCallback constructor called from " + this.$className); + const NewCB = Java.use(this.$className); + + NewCB.onCharacteristicRead.implementation = function (g, c, s) + { + const retVal = NewCB.onCharacteristicRead.call(this, g, c, s); + var uuid = c.getUuid(); + console.log(Color.Blue + "[BLE Read <=]" + Color.Light.Black + " UUID: " + uuid.toString() + Color.Reset + " data: 0x" + bytes2hex(c.getValue())); + return retVal; + }; + + NewCB.onCharacteristicWrite.implementation = function (g, c, s) + { + const retVal = NewCB.onCharacteristicWrite.call(this, g, c, s); + var uuid = c.getUuid(); + console.log(Color.Green + "[BLE Write =>]" + Color.Light.Black + " UUID: " + uuid.toString() + Color.Reset + " data: 0x" + bytes2hex(c.getValue())); + return retVal; + }; + + NewCB.onCharacteristicChanged.implementation = function (g, c) + { + const retVal = NewCB.onCharacteristicChanged.call(this, g, c); + var uuid = c.getUuid(); + console.log(Color.Cyan + "[BLE Notify <=]" + Color.Light.Black + " UUID: " + uuid.toString() + Color.Reset + " data: 0x" + bytes2hex(c.getValue())); + return retVal; + }; + + return this.$init(); + }; + +}); // end perform + + diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-shared-preference.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-shared-preference.js new file mode 100644 index 0000000000..5fcd4826b5 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/trace-shared-preference.js @@ -0,0 +1,102 @@ +/************************************************************************ + * Name: SharedPreferences Monitor + * OS: Android + * Author: @mobilesecurity_ + * Source: https://github.com/m0bilesecurity + * Info: + * android.app.SharedPreferencesImpl + * android.app.SharedPreferencesImpl$EditorImpl +*************************************************************************/ + +Java.perform(function () { + var SharedPreferencesImpl = Java.use("android.app.SharedPreferencesImpl"); + var SharedPreferencesImpl_EditorImpl = Java.use("android.app.SharedPreferencesImpl$EditorImpl"); + + SharedPreferencesImpl.contains.implementation = function (key) { + var value = this.contains.apply(this, arguments); + print("contains",key,value); + return value; + }; + + SharedPreferencesImpl.getInt.implementation = function (key, defValue) { + var value = this.getInt.apply(this, arguments); + print("getInt",key,value); + return value; + }; + + SharedPreferencesImpl.getFloat.implementation = function (key, defValue) { + var value = this.getFloat.apply(this, arguments); + print("getFloat",key,value); + return value; + }; + + SharedPreferencesImpl.getLong.implementation = function (key, defValue) { + var value = this.getLong.apply(this, arguments); + print("getLong",key,value); + return value; + }; + + SharedPreferencesImpl.getBoolean.implementation = function (key, defValue) { + var value = this.getBoolean.apply(this, arguments); + print("getBoolean",key,value); + return value; + }; + + SharedPreferencesImpl.getString.implementation = function (key, defValue) { + var value = this.getString.apply(this, arguments); + print("getString",key,value); + return value; + }; + + SharedPreferencesImpl.getStringSet.implementation = function (key, defValue) { + var value = this.getStringSet.apply(this, arguments); + print("getStringSet",key,value); + return value; + }; + + SharedPreferencesImpl_EditorImpl.putString.implementation = function (key, value) { + print("putString",key,value); + return this.putString.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.putStringSet.implementation = function (key, values) { + print("putStringSet",key,values); + return this.putStringSet.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.putInt.implementation = function (key, value) { + print("putInt",key,value); + return this.putInt.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.putFloat.implementation = function (key, value) { + print("putFloat",key,value); + return this.putFloat.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.putBoolean.implementation = function (key, value) { + print("putBoolean",key,value); + return this.putBoolean.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.putLong.implementation = function (key, value) { + print("putLong",key,value); + return this.putLong.apply(this, arguments); + }; + + SharedPreferencesImpl_EditorImpl.remove.implementation = function (key) { + print("remove",key,""); + return this.remove.apply(this, arguments); + }; + + function print(method,key,value){ + var mkey = key ? key.toString() : 'null'; + var mvalue = value ? value.toString() : 'null'; + + send("API Monitor | "+ + "SharedPreferences" + " | " + + method + " - " + + "(" + mkey + ":" + mvalue + ")" + ); + } + }); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-deeplink-trace.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-deeplink-trace.js new file mode 100644 index 0000000000..c5808ac864 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-deeplink-trace.js @@ -0,0 +1,24 @@ +// Source: https://codeshare.frida.re/@leolashkevych/android-deep-link-observer/ +Java.perform(function() { + var Intent = Java.use("android.content.Intent"); + Intent.getData.implementation = function() { + var action = this.getAction() !== null ? this.getAction().toString() : false; + if (action) { + console.log("[*] Intent.getData() was called"); + console.log("[*] Activity: " + this.getComponent().getClassName()); + console.log("[*] Action: " + action); + var uri = this.getData(); + if (uri !== null) { + console.log("\n[*] Data"); + uri.getScheme() && console.log("- Scheme:\t" + uri.getScheme() + "://"); + uri.getHost() && console.log("- Host:\t\t/" + uri.getHost()); + uri.getQuery() && console.log("- Params:\t" + uri.getQuery()); + uri.getFragment() && console.log("- Fragment:\t" + uri.getFragment()); + console.log("\n\n"); + } else { + console.log("[-] No data supplied."); + } + } + return this.getData(); + } +}); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-bypass-flag-secure.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-flag-secure-bypass.js similarity index 100% rename from mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-bypass-flag-secure.js rename to mobsf/DynamicAnalyzer/tools/frida_scripts/android/others/ui-flag-secure-bypass.js diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-flutter-ssl.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-ssl-flutter.js similarity index 100% rename from mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-flutter-ssl.js rename to mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-ssl-flutter.js diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-ssl-trustkit.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-ssl-trustkit.js new file mode 100644 index 0000000000..30b651139a --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/bypass-ssl-trustkit.js @@ -0,0 +1,33 @@ +/* + Description: iOS TrustKit Certificate Pinning ByPass + Usage: frida -U -f XXX -l ios-trustkit-pinning-bypass.js + Credit: Unknown + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/CertificatePinning/ios-trustkit-pinning-bypass.js +*/ + +if (ObjC.available) +{ + console.log("SSLUnPinning Enabled"); + + for (var className in ObjC.classes) + { + if (ObjC.classes.hasOwnProperty(className)) + { + if (className == "TrustKit") + { + console.log("Found our target class : " + className); + var hook = ObjC.classes.TrustKit["+ initSharedInstanceWithConfiguration:"]; + + Interceptor.replace(hook.implementation, new NativeCallback(function() + { + console.log("Hooking TrustKit"); + return; + }, 'int', [])); + } + } + } +} +else +{ + console.log("Objective-C Runtime is not available!"); +} \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-change-system-version.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-change-system-version.js new file mode 100644 index 0000000000..24e79a9c88 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-change-system-version.js @@ -0,0 +1,45 @@ +/* + Description: iOS System Version changer frida script + Credit: rsenet + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/ios-change-system-version.js + https://developer.apple.com/documentation/uikit/uidevice/1620043-systemversion +*/ + +if (ObjC.available) +{ + try + { + var desiredVersion = "16.0"; + var className = "UIDevice"; + var funcName = "- systemVersion"; + + var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]'); + + Interceptor.attach(hook.implementation, + { + onLeave: function(returnvalue) + { + // Display + console.log('Return Value Object (Original): ' + typeof returnvalue + ' | value: ' + returnvalue); + console.log('Intial System Version: ' + ObjC.Object(returnvalue).toString()); + //console.log(ObjC.Object(returnvalue).$className) + + // Change value + var new_version = ObjC.classes.NSString.stringWithString_(desiredVersion); + returnvalue.replace(new_version) + + // New display + console.log('New System Version: ' + ObjC.Object(new_version).toString()); + console.log("") + } + }); + } + catch(error) + { + console.log("[!] Exception: " + error.message); + } +} +else +{ + console.log("Objective-C Runtime is not available!"); +} \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-spoof-gps.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-spoof-gps.js new file mode 100644 index 0000000000..717d1f7b5b --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/helper-ios-spoof-gps.js @@ -0,0 +1,23 @@ +/* + Description: iOS GPS Location Spoofing + Credit: Divya Mudgal + + Src: https://github.com/rsenet/FriList/blob/main/02_SecurityBypass/Location/ios-location-spoofing.js + Link: + https://developer.apple.com/documentation/corelocation/cllocation +*/ + +function spoof_location(spoof_latitude, spoof_longitude) +{ + var hook_cllocation = ObjC.classes["CLLocation"]["- coordinate"] + + Interceptor.attach(hook_cllocation.implementation, { + onLeave: function(return_value) + { + var spoofed_return_value = (new ObjC.Object(return_value)).initWithLatitude_longitude_(spoof_latitude, spoof_longitude) + return_value.replace(spoofed_return_value) + } + }); +} + +spoof_location(10.0000000,10.0000000) \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/trace-bluetooth.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/trace-bluetooth.js new file mode 100644 index 0000000000..af91841d9d --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/trace-bluetooth.js @@ -0,0 +1,68 @@ +/* + Credit: optiv + + Link: + https://github.com/optiv/blemon +*/ + +var Color = +{ + Reset: "\x1b[39;49;00m", + Black: "\x1b[30;01m", Blue: "\x1b[34;01m", Cyan: "\x1b[36;01m", Gray: "\x1b[37;11m", + Green: "\x1b[32;01m", Purple: "\x1b[35;01m", Red: "\x1b[31;01m", Yellow: "\x1b[33;01m", + Light: + { + Black: "\x1b[30;11m", Blue: "\x1b[34;11m", Cyan: "\x1b[36;11m", Gray: "\x1b[37;01m", + Green: "\x1b[32;11m", Purple: "\x1b[35;11m", Red: "\x1b[31;11m", Yellow: "\x1b[33;11m" + } +}; + +function pad(num, size) +{ + var s = num + ""; + while (s.length < size) s = "0" + s; + return s; +} + + +Interceptor.attach(ObjC.classes.CBPeripheral['- writeValue:forCharacteristic:type:'].implementation, +{ + onEnter: function (args) + { + var data = new ObjC.Object(args[2]); + var CBChar = new ObjC.Object(args[3]); + var dataBytes = Memory.readByteArray(data.bytes(), data.length()); + var b = new Uint8Array(dataBytes); + var hexData = ""; + + for (var i = 0; i < b.length; i++) + { + hexData += pad(b[i].toString(16), 2); + } + console.log(Color.Green + "[BLE Write =>]" + Color.Light.Black + " UUID: " + CBChar.$ivars['_UUID'] + Color.Reset + " data: 0x" + hexData); + } +}); //end Interceptor + +Interceptor.attach(ObjC.classes.CBCharacteristic['- value'].implementation, +{ + onEnter: function (args) + { + var CBChar = new ObjC.Object(args[0]); + // turns <12 34> into 1234 + var data = CBChar.$ivars['_value'] + + if (data != null) + { + data = data.toString().replace(/ /g, '').slice(1, -1) + } + + if (CBChar.$ivars['_isNotifying'] === true) + { + console.log(Color.Cyan + "[BLE Notify <=]" + Color.Light.Black + " UUID: " + CBChar.$ivars['_UUID'] + Color.Reset + " data: 0x" + data); + } + else + { + console.log(Color.Blue + "[BLE Read <=]" + Color.Light.Black + " UUID: " + CBChar.$ivars['_UUID'] + Color.Reset + " data: 0x" + data); + } + } +}); //end Interceptor diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-enable-webinspector.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-enable-webinspector.js new file mode 100644 index 0000000000..679594252c --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-enable-webinspector.js @@ -0,0 +1,50 @@ +/* + Description: iOS Enable WebInspector + Credit: leolashkevych + Src: https://github.com/rsenet/FriList/blob/main/01_Observer/Network/WebInspector/ios-webinspector-enable.js + Enable WebView debugging for all iOS apps. Before running the script, enable Web Inspector in Safari settings + (see https://github.com/OWASP/owasp-mastg/blob/master/Document/0x06h-Testing-Platform-Interaction.md#safari-web-inspector). + Jailbreak required. +*/ + +const CFRelease = new NativeFunction(Module.findExportByName(null, 'CFRelease'), 'void', ['pointer']); +const CFStringGetCStringPtr = new NativeFunction(Module.findExportByName(null, 'CFStringGetCStringPtr'),'pointer', ['pointer', 'uint32']); +const kCFStringEncodingUTF8 = 0x08000100; +const SecTaskCopyValueForEntitlement = Module.findExportByName(null, 'SecTaskCopyValueForEntitlement'); + +const entitlements = [ + 'com.apple.security.get-task-allow', + 'com.apple.webinspector.allow', + 'com.apple.private.webinspector.allow-remote-inspection', + 'com.apple.private.webinspector.allow-carrier-remote-inspection' +]; + +Interceptor.attach(SecTaskCopyValueForEntitlement, +{ + onEnter: function(args) + { + const pEntitlement = CFStringGetCStringPtr(args[1], kCFStringEncodingUTF8) + const entitlement = Memory.readUtf8String(pEntitlement) + + if (entitlements.indexOf(entitlement) > -1) + { + this.shouldOverride = true + this.entitlement = entitlement + } + }, + + onLeave: function(retVal) + { + if (this.shouldOverride) + { + console.log('Overriding value for entitlement: ', this.entitlement) + if (!retVal.isNull()) + { + console.log('Old value: ', retVal) + CFRelease(retVal) + } + retVal.replace(ObjC.classes.NSNumber.numberWithBool_(1)); + console.log('New value: ', retVal) + } + } +}); \ No newline at end of file diff --git a/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-webview-trace.js b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-webview-trace.js new file mode 100644 index 0000000000..4655837114 --- /dev/null +++ b/mobsf/DynamicAnalyzer/tools/frida_scripts/ios/others/ui-webview-trace.js @@ -0,0 +1,59 @@ +/* + Description: iOS WebView Observer + Usage: frida -U -f XXX -l ios-webview-observer.js + Credit: MASTG + Src: https://github.com/rsenet/FriList/blob/main/01_Observer/Network/Webview/ios-webview-observer.js + Link: + https://developer.apple.com/documentation/uikit/uiwebview + https://developer.apple.com/documentation/webkit/wkwebview + https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller +*/ + +if (ObjC.available) +{ + ObjC.choose(ObjC.classes['UIWebView'], + { + onMatch: function (ui) + { + console.log('onMatch: ', ui); + console.log('URL: ', ui.request().toString()); + }, + onComplete: function () + { + console.log('done for UIWebView!'); + } + }); + + ObjC.choose(ObjC.classes['WKWebView'], + { + onMatch: function (wk) + { + console.log('onMatch: ', wk); + console.log('URL: ', wk.URL().toString()); + console.log('javaScriptEnabled: ', wk.configuration().preferences().javaScriptEnabled()); + console.log('allowFileAccessFromFileURLs: ', wk.configuration().preferences().valueForKey_('allowFileAccessFromFileURLs').toString()); + console.log('hasOnlySecureContent: ', wk.hasOnlySecureContent().toString()); + console.log('allowUniversalAccessFromFileURLs: ', wk.configuration().valueForKey_('allowUniversalAccessFromFileURLs').toString()); + }, + onComplete: function () + { + console.log('done for WKWebView!'); + } + }); + + ObjC.choose(ObjC.classes['SFSafariViewController'], + { + onMatch: function (sf) + { + console.log('onMatch: ', sf); + }, + onComplete: function () + { + console.log('done for SFSafariViewController!'); + } + }); +} +else +{ + console.log("Objective-C Runtime is not available!"); +} \ No newline at end of file