mirror of
https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
synced 2026-10-12 02:06:59 +00:00
[HOTFIX] RPC hook suggestions + Bug Fix (#2301)
* String compare script improvements * Fix iOS Frida script bugs * Added RPC helpers for hook suggestion (TODO:Expose to UI) * Code QA
This commit is contained in:
@@ -1,15 +1,37 @@
|
||||
//https://github.com/iddoeldor/frida-snippets#reveal-native-methods
|
||||
//String comparison
|
||||
Java.perform(function () {
|
||||
send('[AUXILIARY] [String Compare] capturing all string comparisons')
|
||||
var str = Java.use('java.lang.String'), objectClass = 'java.lang.Object';
|
||||
str.equals.overload(objectClass).implementation = function (obj) {
|
||||
var response = str.equals.overload(objectClass).call(this, obj);
|
||||
if (obj) {
|
||||
if (obj.toString().length > 5) {
|
||||
send('[AUXILIARY] [String Compare] ' + str.toString.call(this) + ' == ' + obj.toString() + ' ? ' + response);
|
||||
}
|
||||
let Exception = Java.use('java.lang.Exception');
|
||||
let javaString = Java.use('java.lang.String')
|
||||
let objectClass = 'java.lang.Object';
|
||||
var skiplist = ['android.app.SystemServiceRegistry.getSystemService']
|
||||
javaString.equals.overload(objectClass).implementation = function (obj) {
|
||||
var response = javaString.equals.overload(objectClass).call(this, obj);
|
||||
if (obj && obj.toString().length > 5) {
|
||||
var stack = [];
|
||||
var calledFrom = Exception.$new().getStackTrace().toString().split(',');
|
||||
// Otherwise capture string comparisons
|
||||
let i = 0;
|
||||
do {
|
||||
i = i + 1;
|
||||
stack.push(calledFrom[i]);
|
||||
} while (i <= 5);
|
||||
var skipClass, skipMethod = false;
|
||||
skiplist.forEach(function (toSkip) {
|
||||
if (calledFrom[4].includes(toSkip))
|
||||
skipClass = true;
|
||||
});
|
||||
if (!skipClass) {
|
||||
var data = {
|
||||
caller: stack,
|
||||
string1: javaString.toString.call(this),
|
||||
string2: obj.toString(),
|
||||
return: response,
|
||||
}
|
||||
send('[AUXILIARY] [String Compare] ' + JSON.stringify(data, null, 2));
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +1,42 @@
|
||||
// Based on https://github.com/sensepost/objection/blob/f8e78d8a29574c6dadd2b953a63207b45a19b1cf/objection/hooks/android/clipboard/monitor.js
|
||||
var ActivityThread = Java.use('android.app.ActivityThread');
|
||||
var ClipboardManager = Java.use('android.content.ClipboardManager');
|
||||
var CLIPBOARD_SERVICE = 'clipboard';
|
||||
|
||||
var currentApplication = ActivityThread.currentApplication();
|
||||
var context = currentApplication.getApplicationContext();
|
||||
|
||||
var clipboard_handle = context.getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
|
||||
var clipboard = Java.cast(clipboard_handle, ClipboardManager);
|
||||
|
||||
// Variable used for the current string data
|
||||
var string_data;
|
||||
|
||||
function check_clipboard_data() {
|
||||
|
||||
Java.perform(function () {
|
||||
var ActivityThread = Java.use('android.app.ActivityThread');
|
||||
var ClipboardManager = Java.use('android.content.ClipboardManager');
|
||||
var CLIPBOARD_SERVICE = 'clipboard';
|
||||
|
||||
var primary_clip = clipboard.getPrimaryClip();
|
||||
var currentApplication = ActivityThread.currentApplication();
|
||||
var context = currentApplication.getApplicationContext();
|
||||
|
||||
// If we have managed to get the primary clipboard and there are
|
||||
// items stored in it, process an update.
|
||||
if (primary_clip != null && primary_clip.getItemCount() > 0) {
|
||||
var clipboard_handle = context.getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
|
||||
var clipboard = Java.cast(clipboard_handle, ClipboardManager);
|
||||
|
||||
var data = primary_clip.getItemAt(0).coerceToText(context).toString();
|
||||
setInterval(function(){
|
||||
|
||||
// If the data is the same, just stop.
|
||||
if (string_data == data) {
|
||||
return;
|
||||
var primary_clip = clipboard.getPrimaryClip();
|
||||
|
||||
// If we have managed to get the primary clipboard and there are
|
||||
// items stored in it, process an update.
|
||||
if (primary_clip != null && primary_clip.getItemCount() > 0) {
|
||||
|
||||
var data = primary_clip.getItemAt(0).coerceToText(context).toString();
|
||||
|
||||
// If the data is the same, just stop.
|
||||
if (string_data == data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the data with the new string and report back.
|
||||
string_data = data;
|
||||
send('mobsf-android-clipboard:' + data);
|
||||
}
|
||||
|
||||
// Update the data with the new string and report back.
|
||||
string_data = data;
|
||||
send('mobsf-android-clipboard:' + data);
|
||||
}
|
||||
// Poll every 5 seconds
|
||||
}, 1000 * 5);
|
||||
});
|
||||
}
|
||||
|
||||
// Poll every 5 seconds
|
||||
setInterval(check_clipboard_data, 1000 * 5);
|
||||
check_clipboard_data();
|
||||
@@ -132,38 +132,46 @@ Java.perform(function() {
|
||||
console.error(e);
|
||||
}
|
||||
})
|
||||
Interceptor.attach(Module.findExportByName(null, "exit"), {
|
||||
onEnter: function(args) {
|
||||
console.warn("Native Exit() Called :-->:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n") + "\n");
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
Interceptor.attach(Module.findExportByName(null, "abort"), {
|
||||
onEnter: function(args) {
|
||||
console.warn("Native Abort() Called :-->:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n") + "\n");
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
var fork = Module.findExportByName(null, "fork")
|
||||
Interceptor.attach(fork, {
|
||||
onEnter: function(args) {},
|
||||
onLeave: function(retval) {
|
||||
var pid = parseInt(retval.toString(16), 16)
|
||||
console.log("Second Process PID : ", pid)
|
||||
}
|
||||
})
|
||||
Interceptor.attach(Module.findExportByName("libc.so", "system"), {
|
||||
onEnter: function(args) {
|
||||
var cmd = Memory.readCString(args[0]);
|
||||
if (cmd.indexOf("kill") != -1) {
|
||||
console.log("Bypass native system: " + cmd);
|
||||
var NewKill = args[0].writeUtf8String("bypassed");
|
||||
args[0] = ptr(NewKill);
|
||||
try {
|
||||
Interceptor.attach(Module.findExportByName(null, "exit"), {
|
||||
onEnter: function(args) {
|
||||
console.warn("Native Exit() Called :-->:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n") + "\n");
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
} catch (e) {}
|
||||
try {
|
||||
Interceptor.attach(Module.findExportByName(null, "abort"), {
|
||||
onEnter: function(args) {
|
||||
console.warn("Native Abort() Called :-->:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n") + "\n");
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
} catch (e) {}
|
||||
try {
|
||||
var fork = Module.findExportByName(null, "fork")
|
||||
Interceptor.attach(fork, {
|
||||
onEnter: function(args) {},
|
||||
onLeave: function(retval) {
|
||||
var pid = parseInt(retval.toString(16), 16)
|
||||
console.log("Second Process PID : ", pid)
|
||||
}
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
|
||||
})
|
||||
} catch (e) {}
|
||||
try {
|
||||
Interceptor.attach(Module.findExportByName("libc.so", "system"), {
|
||||
onEnter: function(args) {
|
||||
var cmd = Memory.readCString(args[0]);
|
||||
if (cmd.indexOf("kill") != -1) {
|
||||
console.log("Bypass native system: " + cmd);
|
||||
var NewKill = args[0].writeUtf8String("bypassed");
|
||||
args[0] = ptr(NewKill);
|
||||
}
|
||||
},
|
||||
onLeave: function(retval) {}
|
||||
});
|
||||
} catch (e) {}
|
||||
try {
|
||||
var abortPtr = Module.getExportByName('libc.so', 'abort');
|
||||
var abort = new NativeFunction(abortPtr, 'int', ['int']);
|
||||
var exitPtr = Module.getExportByName('libc.so', 'exit');
|
||||
@@ -200,4 +208,4 @@ Interceptor.attach(Module.findExportByName("libc.so", "system"), {
|
||||
console.log('Shutdown Replaced');
|
||||
return 0;
|
||||
}, 'int', ['int', 'int']));
|
||||
|
||||
} catch (e) {}
|
||||
|
||||
@@ -1,90 +1,89 @@
|
||||
var paths = [
|
||||
"/Applications/blackra1n.app",
|
||||
"/Applications/Cydia.app",
|
||||
"/Applications/FakeCarrier.app",
|
||||
"/Applications/Icy.app",
|
||||
"/Applications/IntelliScreen.app",
|
||||
"/Applications/MxTube.app",
|
||||
"/Applications/RockApp.app",
|
||||
"/Applications/SBSetttings.app",
|
||||
"/Applications/WinterBoard.app",
|
||||
"/bin/bash",
|
||||
"/bin/sh",
|
||||
"/bin/su",
|
||||
"/etc/apt",
|
||||
"/etc/ssh/sshd_config",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
|
||||
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
"/pguntether",
|
||||
"/private/var/lib/cydia",
|
||||
"/private/var/mobile/Library/SBSettings/Themes",
|
||||
"/private/var/stash",
|
||||
"/private/var/tmp/cydia.log",
|
||||
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
|
||||
"/usr/bin/cycript",
|
||||
"/usr/bin/ssh",
|
||||
"/usr/bin/sshd",
|
||||
"/usr/libexec/sftp-server",
|
||||
"/usr/libexec/ssh-keysign",
|
||||
"/usr/sbin/frida-server",
|
||||
"/usr/sbin/sshd",
|
||||
"/var/cache/apt",
|
||||
"/var/lib/cydia",
|
||||
"/var/log/syslog",
|
||||
"/var/mobile/Media/.evasi0n7_installed",
|
||||
"/var/tmp/cydia.log",
|
||||
"/etc/apt",
|
||||
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
"/Applications/Cydia.app",
|
||||
"/Applications/blackra1n.app",
|
||||
"/Applications/FakeCarrier.app",
|
||||
"/Applications/Icy.app",
|
||||
"/Applications/IntelliScreen.app",
|
||||
"/Applications/MxTube.app",
|
||||
"/Applications/RockApp.app",
|
||||
"/Applications/SBSetttings.app",
|
||||
"/private/var/lib/apt/",
|
||||
"/Applications/WinterBoard.app",
|
||||
"/usr/sbin/sshd",
|
||||
"/private/var/tmp/cydia.log",
|
||||
"/usr/binsshd",
|
||||
"/usr/libexec/sftp-server",
|
||||
"/Systetem/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/System/Library/LaunchDaemons/[email protected]",
|
||||
"/var/log/syslog",
|
||||
"/bin/bash",
|
||||
"/bin/sh",
|
||||
"/etc/ssh/sshd_config",
|
||||
"/usr/libexec/ssh-keysign",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
|
||||
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/private/var/stash",
|
||||
"/usr/bin/cycript",
|
||||
"/usr/bin/ssh",
|
||||
"/usr/bin/sshd",
|
||||
"/var/cache/apt",
|
||||
"/var/lib/cydia",
|
||||
"/var/tmp/cydia.log",
|
||||
"/Applications/SBSettings.app",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
|
||||
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
|
||||
"/private/var/lib/apt",
|
||||
"/private/var/lib/cydia",
|
||||
"/private/var/mobile/Library/SBSettings/Themes",
|
||||
"/var/lib/apt",
|
||||
"/private/jailbreak.txt",
|
||||
"/bin/su",
|
||||
"/pguntether",
|
||||
"/usr/sbin/frida-server",
|
||||
"/private/Jailbreaktest.txt",
|
||||
"/var/mobile/Media/.evasi0n7_installed",
|
||||
"cydia://package/com.example.package"
|
||||
];
|
||||
|
||||
function bypassJailbreakDetection(){
|
||||
|
||||
var paths = [
|
||||
"/Applications/blackra1n.app",
|
||||
"/Applications/Cydia.app",
|
||||
"/Applications/FakeCarrier.app",
|
||||
"/Applications/Icy.app",
|
||||
"/Applications/IntelliScreen.app",
|
||||
"/Applications/MxTube.app",
|
||||
"/Applications/RockApp.app",
|
||||
"/Applications/SBSetttings.app",
|
||||
"/Applications/WinterBoard.app",
|
||||
"/bin/bash",
|
||||
"/bin/sh",
|
||||
"/bin/su",
|
||||
"/etc/apt",
|
||||
"/etc/ssh/sshd_config",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
|
||||
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
"/pguntether",
|
||||
"/private/var/lib/cydia",
|
||||
"/private/var/mobile/Library/SBSettings/Themes",
|
||||
"/private/var/stash",
|
||||
"/private/var/tmp/cydia.log",
|
||||
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
|
||||
"/usr/bin/cycript",
|
||||
"/usr/bin/ssh",
|
||||
"/usr/bin/sshd",
|
||||
"/usr/libexec/sftp-server",
|
||||
"/usr/libexec/ssh-keysign",
|
||||
"/usr/sbin/frida-server",
|
||||
"/usr/sbin/sshd",
|
||||
"/var/cache/apt",
|
||||
"/var/lib/cydia",
|
||||
"/var/log/syslog",
|
||||
"/var/mobile/Media/.evasi0n7_installed",
|
||||
"/var/tmp/cydia.log",
|
||||
"/etc/apt",
|
||||
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
"/Applications/Cydia.app",
|
||||
"/Applications/blackra1n.app",
|
||||
"/Applications/FakeCarrier.app",
|
||||
"/Applications/Icy.app",
|
||||
"/Applications/IntelliScreen.app",
|
||||
"/Applications/MxTube.app",
|
||||
"/Applications/RockApp.app",
|
||||
"/Applications/SBSetttings.app",
|
||||
"/private/var/lib/apt/",
|
||||
"/Applications/WinterBoard.app",
|
||||
"/usr/sbin/sshd",
|
||||
"/private/var/tmp/cydia.log",
|
||||
"/usr/binsshd",
|
||||
"/usr/libexec/sftp-server",
|
||||
"/Systetem/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/System/Library/LaunchDaemons/[email protected]",
|
||||
"/var/log/syslog",
|
||||
"/bin/bash",
|
||||
"/bin/sh",
|
||||
"/etc/ssh/sshd_config",
|
||||
"/usr/libexec/ssh-keysign",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
|
||||
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
|
||||
"/private/var/stash",
|
||||
"/usr/bin/cycript",
|
||||
"/usr/bin/ssh",
|
||||
"/usr/bin/sshd",
|
||||
"/var/cache/apt",
|
||||
"/var/lib/cydia",
|
||||
"/var/tmp/cydia.log",
|
||||
"/Applications/SBSettings.app",
|
||||
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
|
||||
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
|
||||
"/private/var/lib/apt",
|
||||
"/private/var/lib/cydia",
|
||||
"/private/var/mobile/Library/SBSettings/Themes",
|
||||
"/var/lib/apt",
|
||||
"/private/jailbreak.txt",
|
||||
"/bin/su",
|
||||
"/pguntether",
|
||||
"/usr/sbin/frida-server",
|
||||
"/private/Jailbreaktest.txt",
|
||||
"/var/mobile/Media/.evasi0n7_installed",
|
||||
"cydia://package/com.example.package"
|
||||
];
|
||||
|
||||
try {
|
||||
|
||||
var f = Module.findExportByName("libSystem.B.dylib", "stat64");
|
||||
@@ -196,20 +195,21 @@ function bypassJailbreakDetection2() {
|
||||
},
|
||||
onComplete: function() {}
|
||||
});
|
||||
send("[Jailbreak Detection Bypass 2] success");
|
||||
send("[Jailbreak Detection Bypass] success");
|
||||
}
|
||||
catch(e) {
|
||||
send('[Jailbreak Detection Bypass 2] script error:' + e.toString());
|
||||
send('[Jailbreak Detection Bypass] script error:' + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (ObjC.available) {
|
||||
send('Bypassing Jailbreak detection checks');
|
||||
bypassJailbreakDetection();
|
||||
// Disable the below if the app is crashing
|
||||
setTimeout(() => {
|
||||
bypassJailbreakDetection2();
|
||||
}, "1000");
|
||||
}, 1000);
|
||||
} else {
|
||||
send('[Jailbreak Detection Bypass] error: Objective-C Runtime is not available!');
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ send('Dumping Application Directory file information');
|
||||
try {
|
||||
setTimeout(() => {
|
||||
send(JSON.stringify({'[MBSFDUMP] datadir': getDataProtectionKeysForAllPaths()}));
|
||||
}, "2000");
|
||||
}, 2000);
|
||||
} catch(err) {}
|
||||
|
||||
// /********************************************************************************
|
||||
|
||||
@@ -26,8 +26,13 @@ function NSLogv(){
|
||||
}
|
||||
|
||||
try {
|
||||
NSlog();
|
||||
setTimeout(() => {
|
||||
NSlog();
|
||||
}, 1000);
|
||||
|
||||
} catch(err) {}
|
||||
try {
|
||||
NSLogv();
|
||||
setTimeout(() => {
|
||||
NSLogv();
|
||||
}, 1000);
|
||||
} catch(err) {}
|
||||
@@ -30,6 +30,6 @@ function ns_userdefaults() {
|
||||
try{
|
||||
setTimeout(() => {
|
||||
ns_userdefaults();
|
||||
}, "2000");
|
||||
}, 2000);
|
||||
|
||||
} catch(err) {}
|
||||
@@ -1,6 +1,3 @@
|
||||
import io
|
||||
import os
|
||||
import glob
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import sys
|
||||
@@ -21,7 +18,6 @@ from mobsf.DynamicAnalyzer.views.android.frida_scripts import (
|
||||
)
|
||||
from mobsf.MobSF.utils import (
|
||||
get_device,
|
||||
is_file_exists,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -37,28 +33,26 @@ class Frida:
|
||||
self.auxiliary = auxiliary
|
||||
self.extras = extras
|
||||
self.code = code
|
||||
self.frida_dir = os.path.join(settings.TOOLS_DIR,
|
||||
'frida_scripts', 'android')
|
||||
self.apk_dir = os.path.join(settings.UPLD_DIR, self.hash + '/')
|
||||
self.api_mon = os.path.join(self.apk_dir, 'mobsf_api_monitor.txt')
|
||||
self.frida_log = os.path.join(self.apk_dir, 'mobsf_frida_out.txt')
|
||||
self.deps = os.path.join(self.apk_dir, 'mobsf_app_deps.txt')
|
||||
self.clipboard = os.path.join(self.apk_dir, 'mobsf_app_clipboard.txt')
|
||||
self.frida_dir = Path(settings.TOOLS_DIR) / 'frida_scripts' / 'android'
|
||||
self.apk_dir = Path(settings.UPLD_DIR) / self.hash
|
||||
self.api_mon = self.apk_dir / 'mobsf_api_monitor.txt'
|
||||
self.frida_log = self.apk_dir / 'mobsf_frida_out.txt'
|
||||
self.deps = self.apk_dir / 'mobsf_app_deps.txt'
|
||||
self.clipboard = self.apk_dir / 'mobsf_app_clipboard.txt'
|
||||
|
||||
def get_default_scripts(self):
|
||||
"""Get default Frida Scripts."""
|
||||
def get_scripts(self, script_type, selected_scripts):
|
||||
"""Get Frida Scripts."""
|
||||
combined_script = []
|
||||
header = []
|
||||
if not self.defaults:
|
||||
if not selected_scripts:
|
||||
return header
|
||||
def_scripts = os.path.join(self.frida_dir, 'default')
|
||||
files = glob.glob(def_scripts + '**/*.js', recursive=True)
|
||||
for item in files:
|
||||
script = Path(item)
|
||||
if script.stem in self.defaults:
|
||||
header.append('send("Loaded Frida Script - {}");'.format(
|
||||
script.stem))
|
||||
combined_script.append(script.read_text())
|
||||
all_scripts = self.frida_dir / script_type
|
||||
for script in all_scripts.rglob('*.js'):
|
||||
if '*' in selected_scripts:
|
||||
combined_script.append(script.read_text('utf-8', 'ignore'))
|
||||
if script.stem in selected_scripts:
|
||||
header.append(f'send("Loaded Frida Script - {script.stem}");')
|
||||
combined_script.append(script.read_text('utf-8', 'ignore'))
|
||||
return header + combined_script
|
||||
|
||||
def get_auxiliary(self):
|
||||
@@ -88,12 +82,16 @@ class Frida:
|
||||
"""Get final script."""
|
||||
if not self.code:
|
||||
self.code = ''
|
||||
rpc_list = []
|
||||
# Load custom code first
|
||||
scripts = [self.code]
|
||||
scripts.extend(self.get_default_scripts())
|
||||
scripts.extend(self.get_scripts('default', self.defaults))
|
||||
rpc_list.extend(self.get_scripts('rpc', ['*']))
|
||||
scripts.extend(self.get_auxiliary())
|
||||
rpc_script = ','.join(rpc_list)
|
||||
rpc = f'rpc.exports = {{ \n{rpc_script}\n }};'
|
||||
combined = '\n'.join(scripts)
|
||||
final = f'setTimeout(function() {{ \n{combined}\n}}, 1000)'
|
||||
final = f'{rpc}\n setTimeout(function() {{ \n{combined}\n }}, 1000)'
|
||||
return final
|
||||
|
||||
def frida_response(self, message, data):
|
||||
@@ -112,15 +110,15 @@ class Frida:
|
||||
msg = msg.replace(clip, '')
|
||||
self.write_log(self.clipboard, f'{msg}\n')
|
||||
elif msg.startswith(deps):
|
||||
info = msg.replace(deps, '') + '\n'
|
||||
self.write_log(self.deps, info)
|
||||
self.write_log(self.frida_log, info)
|
||||
info = msg.replace(deps, '')
|
||||
self.write_log(self.deps, f'{info}\n')
|
||||
self.write_log(self.frida_log, f'{info}\n')
|
||||
elif msg.startswith(aux):
|
||||
self.write_log(self.frida_log,
|
||||
msg.replace(aux, '[*] ') + '\n')
|
||||
msg = msg.replace(aux, '[*] ')
|
||||
self.write_log(self.frida_log, f'{msg}\n')
|
||||
else:
|
||||
logger.debug('[Frida] %s', msg)
|
||||
self.write_log(self.frida_log, msg + '\n')
|
||||
self.write_log(self.frida_log, f'{msg}\n')
|
||||
else:
|
||||
logger.error('[Frida] %s', message)
|
||||
|
||||
@@ -165,13 +163,23 @@ class Frida:
|
||||
if pid and package:
|
||||
_FPID = pid
|
||||
self.package = package
|
||||
try:
|
||||
front = device.get_frontmost_application()
|
||||
if front and front.pid != _FPID:
|
||||
# Not the front most app.
|
||||
# Get the pid of the front most app
|
||||
logger.warning('Front most app has PID %s', front.pid)
|
||||
_FPID = front.pid
|
||||
except Exception:
|
||||
pass
|
||||
# pid is the fornt most app
|
||||
session = device.attach(_FPID)
|
||||
time.sleep(2)
|
||||
except frida.NotSupportedError:
|
||||
logger.exception('Not Supported Error')
|
||||
return
|
||||
except Exception:
|
||||
logger.warning('Cannot attach to pid, spawning again')
|
||||
logger.exception('Cannot attach to pid, spawning again')
|
||||
self.spawn()
|
||||
session = device.attach(_FPID)
|
||||
time.sleep(2)
|
||||
@@ -179,6 +187,8 @@ class Frida:
|
||||
script = session.create_script(self.get_script())
|
||||
script.on('message', self.frida_response)
|
||||
script.load()
|
||||
api = script.exports_sync
|
||||
self.api_handler(api)
|
||||
sys.stdin.read()
|
||||
script.unload()
|
||||
session.detach()
|
||||
@@ -212,18 +222,57 @@ class Frida:
|
||||
logger.exception('Failed to enumerate running applications')
|
||||
return ps_dict
|
||||
|
||||
def api_handler(self, api):
|
||||
"""Call Frida rpc functions."""
|
||||
loaded_classes = []
|
||||
loaded_class_methods = []
|
||||
implementations = []
|
||||
try:
|
||||
raction = self.extras.get('rclass_action')
|
||||
rclass = self.extras.get('rclass_name')
|
||||
rclass_pattern = self.extras.get('rclass_pattern')
|
||||
rmethod = self.extras.get('rmethod_name')
|
||||
rmethod_pattern = self.extras.get('rmethod_pattern')
|
||||
if raction == 'raction':
|
||||
loaded_classes = api.getLoadedClasses()
|
||||
elif raction == 'getclasses' and rclass_pattern:
|
||||
loaded_classes = api.getLoadedClasses(f'/{rclass_pattern}/i')
|
||||
elif raction == 'getmethods' and rclass and rmethod:
|
||||
loaded_class_methods = api.getMethods(rclass)
|
||||
elif raction == 'getmethods' and rclass and rmethod_pattern:
|
||||
loaded_class_methods = api.getMethods(
|
||||
rclass,
|
||||
f'/{rmethod_pattern}/i')
|
||||
elif raction == 'getimplementations' and rclass and rmethod:
|
||||
implementations = api.getImplementations(rclass, rmethod)
|
||||
except Exception:
|
||||
logger.exception('Error while calling Frida RPC functions')
|
||||
if loaded_classes:
|
||||
rpc_classes = self.apk_dir / 'mobsf_rpc_classes.txt'
|
||||
loaded_classes = sorted(loaded_classes)
|
||||
rpc_classes.write_text('\n'.join(
|
||||
loaded_classes), 'utf-8')
|
||||
if loaded_class_methods:
|
||||
rpc_methods = self.apk_dir / 'mobsf_rpc_methods.txt'
|
||||
loaded_class_methods = sorted(loaded_class_methods)
|
||||
rpc_methods.write_text('\n'.join(
|
||||
loaded_class_methods), 'utf-8')
|
||||
if implementations:
|
||||
implementations = sorted(implementations)
|
||||
rpc_impl = self.apk_dir / 'mobsf_rpc_impl.txt'
|
||||
rpc_impl.write_text('\n'.join(
|
||||
implementations), 'utf-8')
|
||||
|
||||
def clean_up(self):
|
||||
if is_file_exists(self.api_mon):
|
||||
os.remove(self.api_mon)
|
||||
if is_file_exists(self.frida_log):
|
||||
os.remove(self.frida_log)
|
||||
if is_file_exists(self.clipboard):
|
||||
os.remove(self.clipboard)
|
||||
if self.api_mon.exists():
|
||||
self.api_mon.unlink()
|
||||
if self.frida_log.exists():
|
||||
self.frida_log.unlink()
|
||||
if self.clipboard.exists():
|
||||
self.clipboard.unlink()
|
||||
|
||||
def write_log(self, file_path, data):
|
||||
with io.open(
|
||||
file_path,
|
||||
'a',
|
||||
encoding='utf-8',
|
||||
errors='replace') as flip:
|
||||
with file_path.open('a',
|
||||
encoding='utf-8',
|
||||
errors='replace') as flip:
|
||||
flip.write(data)
|
||||
|
||||
@@ -163,44 +163,6 @@ def live_api(request, api=False):
|
||||
return print_n_send_error_response(request, err, api)
|
||||
|
||||
|
||||
def frida_logs(request, api=False):
|
||||
try:
|
||||
if api:
|
||||
apphash = request.POST['hash']
|
||||
stream = True
|
||||
else:
|
||||
apphash = request.GET.get('hash', '')
|
||||
stream = request.GET.get('stream', '')
|
||||
if not is_md5(apphash):
|
||||
return invalid_params(api)
|
||||
if stream:
|
||||
apk_dir = os.path.join(settings.UPLD_DIR, apphash + '/')
|
||||
frida_logs = os.path.join(apk_dir, 'mobsf_frida_out.txt')
|
||||
data = {}
|
||||
if not is_file_exists(frida_logs):
|
||||
data = {
|
||||
'status': 'failed',
|
||||
'message': 'Data does not exist.'}
|
||||
return send_response(data, api)
|
||||
with open(frida_logs, 'r',
|
||||
encoding='utf8',
|
||||
errors='ignore') as flip:
|
||||
data = {'data': flip.read()}
|
||||
return send_response(data, api)
|
||||
logger.info('Frida Logs live streaming')
|
||||
template = 'dynamic_analysis/android/frida_logs.html'
|
||||
return render(request,
|
||||
template,
|
||||
{'hash': apphash,
|
||||
'package': request.GET.get('package', ''),
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': 'Live Frida logs'})
|
||||
except Exception:
|
||||
logger.exception('Frida log streaming')
|
||||
err = 'Error in Frida log streaming'
|
||||
return print_n_send_error_response(request, err, api)
|
||||
|
||||
|
||||
def decode_base64(data, altchars=b'+/'):
|
||||
"""Decode base64, padding being optional.
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""Shared Frida Views."""
|
||||
import logging
|
||||
import glob
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.shortcuts import render
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from mobsf.DynamicAnalyzer.views.common.shared import (
|
||||
@@ -11,8 +13,15 @@ from mobsf.DynamicAnalyzer.views.common.shared import (
|
||||
)
|
||||
from mobsf.MobSF.utils import (
|
||||
is_file_exists,
|
||||
is_md5,
|
||||
is_safe_path,
|
||||
print_n_send_error_response,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# AJAX
|
||||
|
||||
|
||||
@@ -65,3 +74,45 @@ def get_script(request, api=False):
|
||||
except Exception:
|
||||
pass
|
||||
return send_response(data, api)
|
||||
# AJAX + HTML
|
||||
|
||||
|
||||
def frida_logs(request, api=False):
|
||||
try:
|
||||
data = {
|
||||
'status': 'failed',
|
||||
'message': 'Data does not exist.'}
|
||||
if api:
|
||||
apphash = request.POST['hash']
|
||||
stream = True
|
||||
else:
|
||||
apphash = request.GET.get('hash', '')
|
||||
stream = request.GET.get('stream', '')
|
||||
if not is_md5(apphash):
|
||||
data['message'] = 'Invalid hash'
|
||||
return send_response(data, api)
|
||||
if stream:
|
||||
apk_dir = os.path.join(settings.UPLD_DIR, apphash + '/')
|
||||
frida_logs = os.path.join(apk_dir, 'mobsf_frida_out.txt')
|
||||
if not is_file_exists(frida_logs):
|
||||
return send_response(data, api)
|
||||
with open(frida_logs, 'r',
|
||||
encoding='utf8',
|
||||
errors='ignore') as flip:
|
||||
data = {
|
||||
'status': 'ok',
|
||||
'message': flip.read(),
|
||||
}
|
||||
return send_response(data, api)
|
||||
logger.info('Frida Logs live streaming')
|
||||
template = 'dynamic_analysis/android/frida_logs.html'
|
||||
return render(request,
|
||||
template,
|
||||
{'hash': apphash,
|
||||
'package': request.GET.get('package', ''),
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': 'Live Frida logs'})
|
||||
except Exception:
|
||||
logger.exception('Frida log streaming')
|
||||
err = 'Error in Frida log streaming'
|
||||
return print_n_send_error_response(request, err, api)
|
||||
|
||||
@@ -262,13 +262,20 @@ class CorelliumInstanceAPI:
|
||||
|
||||
def screenshot(self):
|
||||
"""Take screenshot inside VM."""
|
||||
r = requests.get(
|
||||
f'{self.api}/instances/{self.instance_id}/screenshot.png?scale=1',
|
||||
headers=self.headers,
|
||||
stream=True)
|
||||
if r.status_code == 200:
|
||||
return r.content
|
||||
logger.error('Failed to take a screenshot. %s', r.json()['error'])
|
||||
r = None
|
||||
err = ''
|
||||
try:
|
||||
r = requests.get(
|
||||
(f'{self.api}/instances/{self.instance_id}'
|
||||
'/screenshot.png?scale=1'),
|
||||
headers=self.headers,
|
||||
stream=True)
|
||||
if r.status_code == 200:
|
||||
return r.content
|
||||
except Exception:
|
||||
if r and r.json().get('error'):
|
||||
err = r.json()['error']
|
||||
logger.error('Failed to take a screenshot. %s', err)
|
||||
return False
|
||||
|
||||
def start_network_capture(self):
|
||||
|
||||
@@ -719,9 +719,9 @@ def touch(request, api=False):
|
||||
'message': '',
|
||||
}
|
||||
try:
|
||||
x_axis = request.POST['x']
|
||||
y_axis = request.POST['y']
|
||||
event = request.POST['event']
|
||||
x_axis = request.POST.get('x')
|
||||
y_axis = request.POST.get('y')
|
||||
event = request.POST.get('event')
|
||||
|
||||
max_x = request.POST.get('max_x', 0)
|
||||
max_y = request.POST.get('max_y', 0)
|
||||
|
||||
@@ -168,12 +168,15 @@ class Frida:
|
||||
return
|
||||
except frida.ServerNotRunningError:
|
||||
self.frida_ssh_forward()
|
||||
_PID = None
|
||||
if not _PID:
|
||||
_PID = frida.get_remote_device().spawn([self.bundle_id])
|
||||
logger.info('Spawning %s', self.bundle_id)
|
||||
time.sleep(2)
|
||||
except frida.TimedOutError:
|
||||
logger.error('Timed out while waiting for device to appear')
|
||||
except frida.ServerNotRunningError:
|
||||
logger.error('Frida Server is not running')
|
||||
except frida.NotSupportedError:
|
||||
logger.error(self.not_supported_text)
|
||||
return
|
||||
@@ -194,19 +197,21 @@ class Frida:
|
||||
if pid and bundle_id:
|
||||
_PID = pid
|
||||
self.bundle_id = bundle_id
|
||||
front = device.get_frontmost_application()
|
||||
if not front or front.pid != _PID:
|
||||
# No front most app, spawn the app or
|
||||
# pid is not the front most app
|
||||
_PID = device.spawn([self.bundle_id])
|
||||
logger.info('Spawning %s', self.bundle_id)
|
||||
# pid is the fornt most app
|
||||
try:
|
||||
front = device.get_frontmost_application()
|
||||
if front or front.pid != _PID:
|
||||
# Not the front most app.
|
||||
# Get the pid of the front most app
|
||||
logger.warning('Front most app has PID %s', front.pid)
|
||||
_PID = front.pid
|
||||
except Exception:
|
||||
pass
|
||||
session = device.attach(_PID)
|
||||
except frida.NotSupportedError:
|
||||
logger.error(self.not_supported_text)
|
||||
return
|
||||
except Exception:
|
||||
logger.warning('Cannot attach to pid, spawning again')
|
||||
logger.warning('Cannot attach to pid, spawning again.')
|
||||
self.spawn()
|
||||
session = device.attach(_PID)
|
||||
if session and device and _PID:
|
||||
@@ -215,8 +220,7 @@ class Frida:
|
||||
script.load()
|
||||
api = script.exports_sync
|
||||
device.resume(_PID)
|
||||
self.app_container = api.get_container()
|
||||
self.container_file.write_text(self.app_container)
|
||||
self.api_handler(api)
|
||||
sys.stdin.read()
|
||||
script.unload()
|
||||
session.detach()
|
||||
@@ -253,6 +257,52 @@ class Frida:
|
||||
logger.exception('Failed to enumerate running applications')
|
||||
return ps_dict
|
||||
|
||||
def api_handler(self, api):
|
||||
"""Call Frida rpc functions."""
|
||||
loaded_classes = []
|
||||
loaded_class_methods = []
|
||||
implementations = []
|
||||
try:
|
||||
try:
|
||||
self.app_container = api.get_container()
|
||||
self.container_file.write_text(self.app_container)
|
||||
except frida.InvalidOperationError:
|
||||
pass
|
||||
raction = self.extras.get('rclass_action')
|
||||
rclass = self.extras.get('rclass_name')
|
||||
rclass_pattern = self.extras.get('rclass_pattern')
|
||||
rmethod = self.extras.get('rmethod_name')
|
||||
rmethod_pattern = self.extras.get('rmethod_pattern')
|
||||
if raction == 'raction':
|
||||
loaded_classes = api.getLoadedClasses()
|
||||
elif raction == 'getclasses' and rclass_pattern:
|
||||
loaded_classes = api.getLoadedClasses(f'/{rclass_pattern}/i')
|
||||
elif raction == 'getmethods' and rclass and rmethod:
|
||||
loaded_class_methods = api.getMethods(rclass)
|
||||
elif raction == 'getmethods' and rclass and rmethod_pattern:
|
||||
loaded_class_methods = api.getMethods(
|
||||
rclass,
|
||||
f'/{rmethod_pattern}/i')
|
||||
elif raction == 'getimplementations' and rclass and rmethod:
|
||||
implementations = api.getImplementations(rclass, rmethod)
|
||||
except Exception:
|
||||
logger.exception('Error while calling Frida RPC functions')
|
||||
if loaded_classes:
|
||||
loaded_classes = sorted(loaded_classes)
|
||||
rpc_classes = self.ipa_dir / 'mobsf_rpc_classes.txt'
|
||||
rpc_classes.write_text('\n'.join(
|
||||
loaded_classes), 'utf-8')
|
||||
if loaded_class_methods:
|
||||
loaded_class_methods = sorted(loaded_class_methods)
|
||||
rpc_methods = self.ipa_dir / 'mobsf_rpc_methods.txt'
|
||||
rpc_methods.write_text('\n'.join(
|
||||
loaded_class_methods), 'utf-8')
|
||||
if implementations:
|
||||
implementations = sorted(implementations)
|
||||
rpc_impl = self.ipa_dir / 'mobsf_rpc_impl.txt'
|
||||
rpc_impl.write_text('\n'.join(
|
||||
implementations), 'utf-8')
|
||||
|
||||
def clean_up(self):
|
||||
if self.frida_log.exists():
|
||||
self.frida_log.unlink()
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ from mobsf.install.windows.setup import windows_config_local
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
VERSION = '3.8.4'
|
||||
VERSION = '3.8.5'
|
||||
BANNER = """
|
||||
__ __ _ ____ _____ _____ ___
|
||||
| \/ | ___ | |__/ ___|| ___|_ _|___ / ( _ )
|
||||
|
||||
+1
-1
@@ -194,7 +194,7 @@ if settings.API_ONLY == '0':
|
||||
tests_frida.live_api,
|
||||
name='live_api'),
|
||||
re_path(r'^frida_logs/$',
|
||||
tests_frida.frida_logs,
|
||||
frida.frida_logs,
|
||||
name='frida_logs'),
|
||||
re_path(r'^get_dependencies/$', tests_frida.get_runtime_dependencies),
|
||||
# Report
|
||||
|
||||
@@ -228,6 +228,8 @@ def find_between(s, first, last):
|
||||
|
||||
|
||||
def is_number(s):
|
||||
if not s:
|
||||
return False
|
||||
if s == 'NaN':
|
||||
return False
|
||||
try:
|
||||
|
||||
@@ -222,7 +222,7 @@ def api_frida_logs(request):
|
||||
if 'hash' not in request.POST:
|
||||
return make_api_response(
|
||||
{'error': 'Missing Parameters'}, 422)
|
||||
resp = tests_frida.frida_logs(request, True)
|
||||
resp = frida.frida_logs(request, True)
|
||||
# frida logs can be json or html
|
||||
if resp.get('data'):
|
||||
return make_api_response(resp, 200)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
|
||||
::selection {
|
||||
background: #FF5E99;
|
||||
}
|
||||
output {
|
||||
color: #d2d2d2;
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
|
||||
::selection {
|
||||
background: #FF5E99;
|
||||
}
|
||||
output {
|
||||
color: #d2d2d2;
|
||||
}
|
||||
#shell {
|
||||
padding: .1em 1.5em 1em 1em;
|
||||
color: #d2d2d2;
|
||||
background: black;
|
||||
border-radius: 12px;
|
||||
}
|
||||
#shell output {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
#shell output h3 {
|
||||
margin: 0;
|
||||
}
|
||||
#shell output pre {
|
||||
margin: 0;
|
||||
}
|
||||
.input-line {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-align: stretch;
|
||||
display: -moz-box;
|
||||
-moz-box-orient: horizontal;
|
||||
-moz-box-align: stretch;
|
||||
display: box;
|
||||
box-orient: horizontal;
|
||||
box-align: stretch;
|
||||
clear: both;
|
||||
}
|
||||
.input-line > div:nth-child(2) {
|
||||
-webkit-box-flex: 1;
|
||||
-moz-box-flex: 1;
|
||||
box-flex: 1;
|
||||
}
|
||||
.prompt {
|
||||
white-space: nowrap;
|
||||
color: #96b38a;
|
||||
margin-right: 7px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-box-orient: vertical;
|
||||
display: -moz-box;
|
||||
-moz-box-pack: center;
|
||||
-moz-box-orient: vertical;
|
||||
display: box;
|
||||
box-pack: center;
|
||||
box-orient: vertical;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.cmdline {
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
font: inherit;
|
||||
border: none;
|
||||
color: inherit;
|
||||
}
|
||||
.ls-files {
|
||||
-webkit-column-width: 100px;
|
||||
-moz-column-width: 100px;
|
||||
-o-column-width: 100px;
|
||||
column-width: 100px;
|
||||
}
|
||||
|
||||
.clean-text {
|
||||
background-color: none;
|
||||
background: none;
|
||||
color: #ccc;
|
||||
}
|
||||
@@ -241,7 +241,7 @@
|
||||
<!-- /.box-body -->
|
||||
<div class="box-footer">
|
||||
<button id="frida_spawn" type="submit" class="btn btn-success btn-sm"><i class="far fa-play-circle"></i> Spawn & Inject</button>
|
||||
<button id="frida_session" type="submit" class="btn btn-success btn-sm"><i class="fas fa-redo"></i> Inject </button>
|
||||
<button id="frida_session" type="submit" class="btn btn-success btn-sm" disabled><i class="fas fa-redo"></i> Inject </button>
|
||||
<button id="frida_attach" type="submit" class="btn btn-success btn-sm"><i class="fas fa-bug"></i> Attach </button>
|
||||
<button id="frida_get" class="btn btn-primary btn-sm" hidden><i class="fas fa-code"></i> Injected Code</button>
|
||||
</div>
|
||||
@@ -847,11 +847,15 @@ print_status("Start Instrumentation or Run the application and navigate through
|
||||
|
||||
function get_logs(){
|
||||
$.ajax({
|
||||
url : '/frida_logs/?hash={{ hash }}&stream=1',
|
||||
url : '{% url 'frida_logs' %}?hash={{ hash }}&stream=1',
|
||||
type : "GET",
|
||||
dataType: "json",
|
||||
success : function(json){
|
||||
$('#frida-logs').text(json.data);
|
||||
if (json.status==="ok"){
|
||||
$('#frida-logs').text(json.message);
|
||||
} else {
|
||||
$('#frida-logs').text('')
|
||||
}
|
||||
},
|
||||
error : function(xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr.responseText);
|
||||
@@ -1232,6 +1236,7 @@ function frida_instrument(frida_action, pid=null, new_pkg=null){
|
||||
});
|
||||
|
||||
if (frida_action === 'spawn'){
|
||||
document.getElementById('frida_session').disabled = false;
|
||||
print_status("Instrumenting the application with Frida.");
|
||||
} else if (frida_action === 'session' && pid === null){
|
||||
print_status("Injecting Frida script to existing session.");
|
||||
|
||||
@@ -31,7 +31,7 @@ $(document).ready( function () {
|
||||
type : "GET",
|
||||
dataType: "json",
|
||||
success : function(json){
|
||||
$('#logs').text(json.data);
|
||||
$('#logs').text(json.message);
|
||||
},
|
||||
error : function(xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr.responseText);
|
||||
|
||||
@@ -802,9 +802,8 @@ function upload_and_install(url){
|
||||
'IPA Installed',
|
||||
'The IPA is successfully installed',
|
||||
'success'
|
||||
).then(function () {
|
||||
location.reload();
|
||||
})
|
||||
);
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error : function(xhr,errmsg,err) {
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
<div class="box-footer">
|
||||
<button id="run" type="submit" class="btn btn-success btn-sm"><i class="fas fa-play"></i> Run</button>
|
||||
<button id="frida_spawn" type="submit" class="btn btn-success btn-sm"><i class="far fa-play-circle"></i> Spawn & Inject</button>
|
||||
<button id="frida_session" type="submit" class="btn btn-success btn-sm"><i class="fas fa-redo"></i> Inject </button>
|
||||
<button id="frida_session" type="submit" class="btn btn-success btn-sm" disabled><i class="fas fa-redo"></i> Inject </button>
|
||||
<button id="frida_attach" type="submit" class="btn btn-success btn-sm"><i class="fas fa-bug"></i> Attach </button>
|
||||
<button id="frida_get" class="btn btn-primary btn-sm" hidden><i class="fas fa-code"></i> Injected Code</button>
|
||||
</div>
|
||||
@@ -774,11 +774,15 @@ print_status("Environment is ready for Dynamic Analysis.");
|
||||
// Frida Logs Tab
|
||||
setInterval( function () {
|
||||
$.ajax({
|
||||
url : '/frida_logs/?hash={{ hash }}&stream=1',
|
||||
url : '{% url 'frida_logs' %}?hash={{ hash }}&stream=1',
|
||||
type : "GET",
|
||||
dataType: "json",
|
||||
success : function(json){
|
||||
$('#frida-logs').text(json.data);
|
||||
if (json.status==="ok"){
|
||||
$('#frida-logs').text(json.message);
|
||||
} else {
|
||||
$('#frida-logs').text('')
|
||||
}
|
||||
},
|
||||
error : function(xhr, ajaxOptions, thrownError) {
|
||||
console.log(xhr.responseText);
|
||||
@@ -1077,6 +1081,7 @@ function frida_instrument(frida_action, pid=null, new_bundle_id=null){
|
||||
});
|
||||
|
||||
if (frida_action === 'spawn'){
|
||||
document.getElementById('frida_session').disabled = false;
|
||||
print_status("Instrumenting the application with Frida.");
|
||||
} else if (frida_action === 'session' && pid === null){
|
||||
print_status("Injecting Frida script to existing session.");
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "mobsf"
|
||||
version = "3.8.4"
|
||||
version = "3.8.5"
|
||||
description = "Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis."
|
||||
keywords = ["mobsf", "mobile security framework", "mobile security", "security tool", "static analysis", "dynamic analysis", "malware analysis"]
|
||||
authors = ["Ajin Abraham <[email protected]>"]
|
||||
|
||||
Reference in New Issue
Block a user