def touch(request): """Sending Touch Events.""" logger.info('Sending Touch Events') try: data = {} if (request.method == 'POST' and is_number(request.POST['x']) and is_number(request.POST['y'])): x_axis = request.POST['x'] y_axis = request.POST['y'] args = ['input', 'tap', x_axis, y_axis] data = {'status': 'success'} try: adb_command(args, True) except Exception: data = {'status': 'error'} logger.exception('Performing Touch Action') else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except Exception: logger.exception('Sending Touch Events') return print_n_send_error_response(request, 'Error Sending Touch Events', True)
def take_screenshot(request): """Take Screenshot""" print("\n[INFO] Taking Screenshot") try: if request.method == 'POST': md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): data = {} rand_int = random.randint(1, 1000000) base_dir = settings.BASE_DIR # make sure that list only png from this directory screen_dir = os.path.join( settings.UPLD_DIR, md5_hash + '/screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) adb_command( ["screencap", "-p", "/data/local/screen.png"], True) adb_command(["pull", "/data/local/screen.png", screen_dir + "screenshot-" + str(rand_int) + ".png"]) print("\n[INFO] Screenshot Taken") data = {'screenshot': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Taking Screenshot") return HttpResponseRedirect('/error/')
def mobsf_ca(request): """Install and Remove MobSF Proxy RootCA.""" try: if request.method == 'POST': data = {} act = request.POST['action'] rootca = get_ca_dir() if act == 'install': logger.info('Installing MobSF RootCA') adb_command( ['push', rootca, '/data/local/tmp/' + settings.ROOT_CA]) ca_file = '/system/etc/security/cacerts/' + settings.ROOT_CA adb_command([ 'su', '-c', 'cp', '/data/local/tmp/' + settings.ROOT_CA, ca_file ], True) adb_command(['su', '-c', 'chmod', '644', ca_file], True) adb_command(['rm', '/data/local/tmp/' + settings.ROOT_CA], True) data = {'ca': 'installed'} elif act == 'remove': logger.info('Removing MobSF RootCA') adb_command(['su', '-c', 'rm', ca_file], True) data = {'ca': 'removed'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, 'Only POST allowed', True) except Exception: logger.exception('MobSF RootCA Handler') return print_n_send_error_response(request, 'Error in RootCA Handler', True)
def take_screenshot(request): """Take Screenshot.""" logger.info('Taking Screenshot') try: if request.method == 'POST': md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): data = {} rand_int = random.randint(1, 1000000) # make sure that list only png from this directory screen_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) adb_command(['screencap', '-p', '/data/local/screen.png'], True) adb_command([ 'pull', '/data/local/screen.png', '{}creenshot-{}.png'.fomat(screen_dir, str(rand_int)) ]) logger.info('Screenshot Taken') data = {'screenshot': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, 'Invalid Scan Hash', True) else: return print_n_send_error_response(request, 'Only POST allowed', True) except Exception: logger.exception('Taking Screenshot') return print_n_send_error_response(request, 'Error Taking Screenshot', True)
def touch(request): """Sending Touch Events""" print("\n[INFO] Sending Touch Events") try: data = {} if (request.method == 'POST') and (is_number(request.POST['x'])) and (is_number(request.POST['y'])): x_axis = request.POST['x'] y_axis = request.POST['y'] adb = getADB() args = ["input", "tap", x_axis, y_axis] data = {'status': 'success'} try: adb_command(args, True) except: data = {'status': 'error'} PrintException("[ERROR] Performing Touch Action") else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("[ERROR] Sending Touch Events") return HttpResponseRedirect('/error/')
def stop_avd(): """Stop AVD""" print("\n[INFO] Stopping MobSF Emulator") try: adb_command(['emu', 'kill'], silent=True) except: PrintException("[ERROR] Stopping MobSF Emulator")
def take_screenshot(request): """Take Screenshot""" print("\n[INFO] Taking Screenshot") try: if request.method == 'POST': md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): data = {} rand_int = random.randint(1, 1000000) base_dir = settings.BASE_DIR # make sure that list only png from this directory screen_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) adb_command(["screencap", "-p", "/data/local/screen.png"], True) adb_command([ "pull", "/data/local/screen.png", screen_dir + "screenshot-" + str(rand_int) + ".png" ]) print("\n[INFO] Screenshot Taken") data = {'screenshot': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Taking Screenshot") return HttpResponseRedirect('/error/')
def touch(request): """Sending Touch Events""" logger.info("Sending Touch Events") try: data = {} if (request.method == 'POST') and (is_number(request.POST['x'])) and (is_number(request.POST['y'])): x_axis = request.POST['x'] y_axis = request.POST['y'] adb = getADB() args = ["input", "tap", x_axis, y_axis] data = {'status': 'success'} try: adb_command(args, True) except: data = {'status': 'error'} PrintException("Performing Touch Action") else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("Sending Touch Events") return print_n_send_error_response(request, "Error Sending Touch Events", True)
def stop_avd(): """Stop AVD""" logger.info("Stopping MobSF Emulator") try: adb_command(['emu', 'kill'], silent=True) except: PrintException("Stopping MobSF Emulator")
def dump_data(request): """Downloading Application Data from Device.""" logger.info('Downloading Application Data from Device') try: if request.method == 'POST': data = {} package = request.POST['pkg'] md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r';|\$\(|\|\||&&', package): return print_n_send_error_response(request, 'Possible RCE Attack', True) apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') # Let's try to close Proxy a bit early as we don't have much # control on the order of thread execution stop_capfuzz(settings.PORT) logger.info('Deleting Dump Status File') adb_command(['rm', '/sdcard/mobsec_status'], True) logger.info('Creating TAR of Application Files.') dp = 'opensecurity.ajin.datapusher/.GetPackageLocation' adb_command(['am', 'startservice', '-a', package, dp], True) logger.info('Waiting for TAR dump to complete...') if settings.ANDROID_DYNAMIC_ANALYZER == 'MobSF_REAL_DEVICE': timeout = settings.DEVICE_TIMEOUT else: timeout = settings.VM_TIMEOUT start_time = time.time() while True: current_time = time.time() out = adb_command(['cat', '/sdcard/mobsec_status'], shell=True) if b'MOBSEC-TAR-CREATED' in out: break if (current_time - start_time) > timeout: logger.error( 'TAR Generation Failed. Process timed out.') break logger.info('Dumping Application Files from Device/VM') adb_command([ 'pull', '/data/local/' + package + '.tar', apk_dir + package + '.tar' ]) logger.info('Stopping ADB') adb_command(['kill-server']) data = {'dump': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, 'Invalid Scan Hash', True) else: return print_n_send_error_response(request, 'Only POST allowed', True) except Exception: logger.exception('Downloading Application Data from Device') err = 'Application Data Dump from Device failed' return print_n_send_error_response(request, err, True)
def help_boot_avd(): try: emulator = get_identifier() # Wait for the adb to answer args = [settings.ADB_BINARY, "-s", emulator, "wait-for-device"] logger.info("help_boot_avd: wait-for-device") subprocess.call(args) # Make sure adb running as root logger.info("help_boot_avd: root") adb_command(['root']) # Make sure adb running as root logger.info("help_boot_avd: remount") adb_command(['remount']) # Make sure the system verity feature is disabled (Obviously, modified the system partition) logger.info("help_boot_avd: disable-verity") adb_command(['disable-verity']) # Make SELinux permissive - in case SuperSu/Xposed didn't patch things right logger.info("help_boot_avd: setenforce") adb_command(['setenforce', '0'], shell=True) logger.info("help_boot_avd: finished!") return True except: PrintException("help_boot_avd") return False
def help_boot_avd(): try: emulator = get_identifier() # Wait for the adb to answer args = [settings.ADB_BINARY, "-s", emulator, "wait-for-device"] print("[INFO] help_boot_avd: wait-for-device") subprocess.call(args) # Make sure adb running as root print("[INFO] help_boot_avd: root") adb_command(['root']) # Make sure adb running as root print("[INFO] help_boot_avd: remount") adb_command(['remount']) # Make sure the system verity feature is disabled (Obviously, modified the system partition) print("[INFO] help_boot_avd: disable-verity") adb_command(['disable-verity']) # Make SELinux permissive - in case SuperSu/Xposed didn't patch things right print("[INFO] help_boot_avd: setenforce") adb_command(['setenforce', '0'], shell=True) print("[INFO] help_boot_avd: finished!") return True except: PrintException("[ERROR] help_boot_avd") return False
def screen_cast(request): """Start or Stop ScreenCast Feature.""" logger.info('Invoking ScreenCast Service in VM/Device') try: global TCP_SERVER_MODE data = {} if request.method == 'POST': mode = request.POST['mode'] ip_address = settings.SCREEN_IP port = str(settings.SCREEN_PORT) if mode == 'on': args = ['am', 'startservice', '-a', ip_address + ':' + port, 'opensecurity.screencast/.StartScreenCast'] data = {'status': 'on'} TCP_SERVER_MODE = 'on' elif mode == 'off': args = ['am', 'force-stop', 'opensecurity.screencast'] data = {'status': 'off'} TCP_SERVER_MODE = 'off' if (mode in ['on', 'off']): try: adb_command(args, True) screen_trd = threading.Thread(target=screencast_service) screen_trd.setDaemon(True) screen_trd.start() except Exception: logger.exception('Casting Screen') data = {'status': 'error'} return HttpResponse(json.dumps(data), content_type='application/json') else: data = {'status': 'failed'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except Exception: logger.exception('Casting Screen') return print_n_send_error_response(request, 'Error Casting Screen', True)
def screen_cast(request): """Start or Stop ScreenCast Feature""" print("\n[INFO] Invoking ScreenCast Service in VM/Device") try: global TCP_SERVER_MODE data = {} if request.method == 'POST': mode = request.POST['mode'] if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": ip_address = '10.0.2.2' else: ip_address = settings.SCREEN_IP port = str(settings.SCREEN_PORT) if mode == "on": args = ["am", "startservice", "-a", ip_address + ":" + port, "opensecurity.screencast/.StartScreenCast"] data = {'status': 'on'} TCP_SERVER_MODE = "on" elif mode == "off": args = ["am", "force-stop", "opensecurity.screencast"] data = {'status': 'off'} TCP_SERVER_MODE = "off" if (mode in ["on", "off"]): try: adb_command(args, True) screen_trd = threading.Thread(target=screencast_service) screen_trd.setDaemon(True) screen_trd.start() except: PrintException("[ERROR] Casting Screen") data = {'status': 'error'} return HttpResponse(json.dumps(data), content_type='application/json') else: data = {'status': 'failed'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("[ERROR] Casting Screen") return HttpResponseRedirect('/error/')
def clip_dump(request): """Dump Android Clipboard.""" logger.info('Starting Clipboard Dump Service in VM/Device') try: data = {} if request.method == 'POST': args = ['am', 'startservice', 'opensecurity.clipdump/.ClipDumper'] try: adb_command(args, True) data = {'status': 'success'} except Exception: logger.exception('Dumping Clipboard') data = {'status': 'error'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except Exception: logger.exception('Dumping Clipboard') return print_n_send_error_response(request, 'Error Dumping Clipboard', True)
def clip_dump(request): """Dump Android ClipBoard""" print("\n[INFO] Starting Clipboard Dump Service in VM/Device") try: data = {} if request.method == 'POST': adb = getADB() args = ["am", "startservice", "opensecurity.clipdump/.ClipDumper"] try: adb_command(args, True) data = {'status': 'success'} except: PrintException("[ERROR] Dumping Clipboard") data = {'status': 'error'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("[ERROR] Dumping Clipboard") return HttpResponseRedirect('/error/')
def clip_dump(request): """Dump Android ClipBoard""" logger.info("Starting Clipboard Dump Service in VM/Device") try: data = {} if request.method == 'POST': adb = getADB() args = ["am", "startservice", "opensecurity.clipdump/.ClipDumper"] try: adb_command(args, True) data = {'status': 'success'} except: PrintException("Dumping Clipboard") data = {'status': 'error'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("Dumping Clipboard") return print_n_send_error_response(request, "Error Dumping Clipboard", True)
def start_avd_from_snapshot(): """Start AVD""" print("\n[INFO] Starting MobSF Emulator") try: if platform.system() == 'Darwin': # There is a strage error in mac with the dyld one in a while.. # this should fix it.. if 'DYLD_FALLBACK_LIBRARY_PATH' in list(os.environ.keys()): del os.environ['DYLD_FALLBACK_LIBRARY_PATH'] args = [ settings.AVD_EMULATOR, '-avd', settings.AVD_NAME, "-writable-system", "-snapshot", settings.AVD_SNAPSHOT, "-netspeed", "full", "-netdelay", "none", "-port", str(settings.AVD_ADB_PORT), ] subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Give a few seconds and check if the snapshot load succeed time.sleep(5) result = adb_command(["getprop", "init.svc.bootanim"], True) if result: if result.strip() == b"stopped": return True # Snapshot failed, stop the avd and return an error adb_command(["emu", "kill"]) return False except: PrintException("[ERROR] Starting MobSF Emulator") return False
def clip_dump(request): """Dump Android ClipBoard""" print("\n[INFO] Starting Clipboard Dump Service in VM/Device") try: data = {} if request.method == 'POST': adb = getADB() args = ["am", "startservice", "opensecurity.clipdump/.ClipDumper"] try: adb_command(args, True) data = {'status': 'success'} except: PrintException("[ERROR] Dumping Clipboard") data = {'status': 'error'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("[ERROR] Dumping Clipboard") return HttpResponseRedirect('/error/')
def clip_dump(request): """Dump Android ClipBoard""" logger.info("Starting Clipboard Dump Service in VM/Device") try: data = {} if request.method == 'POST': adb = getADB() args = ["am", "startservice", "opensecurity.clipdump/.ClipDumper"] try: adb_command(args, True) data = {'status': 'success'} except: PrintException("Dumping Clipboard") data = {'status': 'error'} else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("Dumping Clipboard") return print_n_send_error_response(request, "Error Dumping Clipboard", True)
def touch(request): """Sending Touch Events""" logger.info("Sending Touch Events") try: data = {} if (request.method == 'POST') and (is_number( request.POST['x'])) and (is_number(request.POST['y'])): x_axis = request.POST['x'] y_axis = request.POST['y'] adb = getADB() args = ["input", "tap", x_axis, y_axis] data = {'status': 'success'} try: adb_command(args, True) except: data = {'status': 'error'} PrintException("Performing Touch Action") else: data = {'status': 'failed'} return HttpResponse(json.dumps(data), content_type='application/json') except: PrintException("Sending Touch Events") return print_n_send_error_response(request, "Error Sending Touch Events", True)
def final_test(request): """Collecting Data and Cleanup""" global TCP_SERVER_MODE logger.info("Collecting Data and Cleaning Up") try: if request.method == 'POST': data = {} md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.findall(r";|\$\(|\|\||&&", package): return print_n_send_error_response(request, "Possible RCE Attack", True) if re.match('^[0-9a-f]{32}$', md5_hash): # Stop ScreenCast Client if it is running TCP_SERVER_MODE = "off" base_dir = settings.BASE_DIR apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') adb = getADB() # Change to check output of subprocess when analysis is done # Can't RCE os.system(adb + ' -s ' + get_identifier() + ' logcat -d dalvikvm:W ActivityManager:I > "' + apk_dir + 'logcat.txt"') logger.info("Downloading Logcat logs") adb_command([ "pull", "/data/data/de.robv.android.xposed.installer/log/error.log", apk_dir + "x_logcat.txt" ]) logger.info("Downloading Droidmon API Monitor Logcat logs") # Can't RCE os.system(adb + ' -s ' + get_identifier() + ' shell dumpsys > "' + apk_dir + 'dump.txt"') logger.info("Downloading Dumpsys logs") adb_command(["am", "force-stop", package], True) logger.info("Stopping Application") adb_command(["am", "force-stop", "opensecurity.screencast"], True) logger.info("Stopping ScreenCast Service") data = {'final': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, "Invalid Scan Hash", True) else: return print_n_send_error_response(request, "Only POST allowed", True) except: PrintException("Data Collection & Clean Up") return print_n_send_error_response( request, "Data Collection & Clean Up failed", True)
def final_test(request): """Collecting Data and Cleanup.""" global TCP_SERVER_MODE logger.info('Collecting Data and Cleaning Up') try: if request.method == 'POST': data = {} md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.findall(r';|\$\(|\|\||&&', package): return print_n_send_error_response(request, 'Possible RCE Attack', True) if re.match('^[0-9a-f]{32}$', md5_hash): # Stop ScreenCast Client if it is running TCP_SERVER_MODE = 'off' apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') adb = get_adb() # Change to check output of subprocess when analysis is done # Can't RCE cmd = ('{} -s {} logcat -d dalvikvm:' 'W ActivityManager:I > "{}logact.txt"').format( adb, get_identifier(), apk_dir) os.system(cmd) logger.info('Downloading Logcat logs') xposed_out = ('/data/data/' 'de.robv.android.xposed.installer' '/log/error.log') adb_command(['pull', xposed_out, apk_dir + 'x_logcat.txt']) logger.info('Downloading Droidmon API Monitor Logcat logs') # Can't RCE cmd = '{} -s {} shell dumpsys > "{}dump.txt"'.format( adb, get_identifier(), apk_dir) os.system(cmd) logger.info('Downloading Dumpsys logs') adb_command(['am', 'force-stop', package], True) logger.info('Stopping Application') adb_command(['am', 'force-stop', 'opensecurity.screencast'], True) logger.info('Stopping ScreenCast Service') data = {'final': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, 'Invalid Scan Hash', True) else: return print_n_send_error_response(request, 'Only POST allowed', True) except Exception: err = 'Data Collection & Clean Up failed' logger.exception(err) return print_n_send_error_response(request, err, True)
def execute_adb(request): """Execute ADB Commands""" print("\n[INFO] Executing ADB Commands") try: if request.method == 'POST': data = {} cmd = request.POST['cmd'] resp = "error" try: resp = adb_command(cmd.split(' ')) except: PrintException("[ERROR] Executing ADB Commands") data = {'cmd': 'yes', 'resp': resp.decode("utf8", "ignore")} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Executing ADB Commands") return HttpResponseRedirect('/error/')
def execute_adb(request): """Execute ADB Commands""" logger.info("Executing ADB Commands") try: if request.method == 'POST': data = {} cmd = request.POST['cmd'] resp = "error" try: resp = adb_command(cmd.split(' ')) except: PrintException("Executing ADB Commands") data = {'cmd': 'yes', 'resp': resp.decode("utf8", "ignore")} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, "Only POST allowed", True) except: PrintException("Executing ADB Commands") return print_n_send_error_response(request, "Error running ADB commands", True)
def final_test(request): """Collecting Data and Cleanup""" global TCP_SERVER_MODE print("\n[INFO] Collecting Data and Cleaning Up") try: if request.method == 'POST': data = {} md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.findall(r";|\$\(|\|\||&&", package): print("[ATTACK] Possible RCE") return HttpResponseRedirect('/error/') if re.match('^[0-9a-f]{32}$', md5_hash): # Stop ScreenCast Client if it is running TCP_SERVER_MODE = "off" base_dir = settings.BASE_DIR apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') adb = getADB() # Change to check output of subprocess when analysis is done # Can't RCE os.system(adb + ' -s ' + get_identifier() + ' logcat -d dalvikvm:W ActivityManager:I > "' + apk_dir + 'logcat.txt"') print("\n[INFO] Downloading Logcat logs") adb_command(["pull", "/data/data/de.robv.android.xposed.installer/log/error.log", apk_dir + "x_logcat.txt"]) print("\n[INFO] Downloading Droidmon API Monitor Logcat logs") # Can't RCE os.system(adb + ' -s ' + get_identifier() + ' shell dumpsys > "' + apk_dir + 'dump.txt"') print("\n[INFO] Downloading Dumpsys logs") adb_command(["am", "force-stop", package], True) print("\n[INFO] Stopping Application") adb_command( ["am", "force-stop", "opensecurity.screencast"], True) print("\n[INFO] Stopping ScreenCast Service") data = {'final': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Clean Up") return HttpResponseRedirect('/error/')
def execute_adb(request): """Execute ADB Commands""" logger.info("Executing ADB Commands") try: if request.method == 'POST': data = {} cmd = request.POST['cmd'] resp = "error" try: resp = adb_command(cmd.split(' ')) except: PrintException("Executing ADB Commands") data = {'cmd': 'yes', 'resp': resp.decode("utf8", "ignore")} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, "Only POST allowed", True) except: PrintException("Executing ADB Commands") return print_n_send_error_response(request, "Error running ADB commands", True)
def execute_adb(request): """Execute ADB Commands.""" logger.info('Executing ADB Commands') try: if request.method == 'POST': data = {} cmd = request.POST['cmd'] resp = 'error' try: resp = adb_command(cmd.split(' ')) except Exception: logger.exception('Executing ADB Commands') data = {'cmd': 'yes', 'resp': resp.decode('utf8', 'ignore')} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, 'Only POST allowed', True) except Exception: logger.exception('Executing ADB Commands') return print_n_send_error_response(request, 'Error running ADB commands', True)
def activity_tester(request): """Activity Tester""" print("\n[INFO] Activity Tester") try: md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): print("[ATTACK] Possible RCE") return HttpResponseRedirect('/error/') if request.method == 'POST': base_dir = settings.BASE_DIR app_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') screen_dir = os.path.join(app_dir, 'screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) data = {} adb = getADB() static_android_db = StaticAnalyzerAndroid.objects.filter( MD5=md5_hash) if static_android_db.exists(): print("\n[INFO] Fetching Activity List from DB") activities = python_list(static_android_db[0].ACTIVITIES) if activities: act_no = 0 print("\n[INFO] Starting Activity Tester...") print("\n[INFO] " + str(len(activities)) + " Activities Identified") for line in activities: try: act_no += 1 print("\n[INFO] Launching Activity - " + str(act_no) + ". " + line) adb_command([ "am", "start", "-n", package + "/" + line ], True) # AVD is much slower, it should get extra time if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": wait(8) else: wait(4) adb_command([ "screencap", "-p", "/data/local/screen.png" ], True) #? get appended from Air :-() if activity names are used adb_command([ "pull", "/data/local/screen.png", screen_dir + "act-" + str(act_no) + ".png" ]) print("\n[INFO] Activity Screenshot Taken") adb_command(["am", "force-stop", package], True) print("\n[INFO] Stopping App") except: PrintException("Activity Tester") data = {'acttest': 'done'} else: print("\n[INFO] Activity Tester - No Activity Found!") data = {'acttest': 'noact'} return HttpResponse(json.dumps(data), content_type='application/json') else: print("\n[ERROR] Entry does not exist in DB.") return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Activity Tester") return HttpResponseRedirect('/error/')
def dump_data(request): """Downloading Application Data from Device""" print("\n[INFO] Downloading Application Data from Device") try: if request.method == 'POST': data = {} package = request.POST['pkg'] md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): print("[ATTACK] Possible RCE") return HttpResponseRedirect('/error/') base_dir = settings.BASE_DIR apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') # Let's try to close Proxy a bit early as we don't have much # control on the order of thread execution stop_capfuzz(settings.PORT) print("\n[INFO] Deleting Dump Status File") adb_command(["rm", "/sdcard/mobsec_status"], True) print("\n[INFO] Creating TAR of Application Files.") adb_command([ "am", "startservice", "-a", package, "opensecurity.ajin.datapusher/.GetPackageLocation" ], True) print("\n[INFO] Waiting for TAR dump to complete...") if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_REAL_DEVICE": timeout = settings.DEVICE_TIMEOUT else: timeout = settings.VM_TIMEOUT start_time = time.time() while True: current_time = time.time() if b"MOBSEC-TAR-CREATED" in adb_command( ["cat", "/sdcard/mobsec_status"], shell=True): break if (current_time - start_time) > timeout: print( "\n[ERROR] TAR Generation Failed. Process timed out." ) break print("\n[INFO] Dumping Application Files from Device/VM") adb_command([ "pull", "/data/local/" + package + ".tar", apk_dir + package + ".tar" ]) if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": print("\n[INFO] Removing package") adb_command(["uninstall", package]) stop_avd() print("\n[INFO] Stopping ADB") adb_command(["kill-server"]) data = {'dump': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Downloading Application Data from Device") return HttpResponseRedirect('/error/')
def mobsf_ca(request): """Install and Remove MobSF Proxy RootCA""" try: if request.method == 'POST': data = {} act = request.POST['action'] rootca = get_ca_dir() adb = getADB() if act == "install": print("\n[INFO] Installing MobSF RootCA") adb_command( ["push", rootca, "/data/local/tmp/" + settings.ROOT_CA]) if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": # For some reason, avd emulator does not have cp binary adb_command([ "/data/local/tmp/busybox", "cp", "/data/local/tmp/" + settings.ROOT_CA, "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) adb_command([ "chmod", "644", "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) else: adb_command([ "su", "-c", "cp", "/data/local/tmp/" + settings.ROOT_CA, "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) adb_command([ "su", "-c", "chmod", "644", "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) adb_command(["rm", "/data/local/tmp/" + settings.ROOT_CA], True) data = {'ca': 'installed'} elif act == "remove": print("\n[INFO] Removing MobSF RootCA") if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": adb_command([ "rm", "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) else: adb_command([ "su", "-c", "rm", "/system/etc/security/cacerts/" + settings.ROOT_CA ], True) data = {'ca': 'removed'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] MobSF RootCA Handler") return HttpResponseRedirect('/error/')
def exported_activity_tester(request): """Exported Activity Tester""" logger.info("Exported Activity Tester") try: md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): return print_n_send_error_response(request, "Possible RCE Attack", True) if request.method == 'POST': base_dir = settings.BASE_DIR app_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') screen_dir = os.path.join(app_dir, 'screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) data = {} adb = getADB() static_android_db = StaticAnalyzerAndroid.objects.filter( MD5=md5_hash) if static_android_db.exists(): logger.info("Fetching Exported Activity List from DB") exported_act = python_list( static_android_db[0].EXPORTED_ACT) if exported_act: exp_act_no = 0 logger.info("Starting Exported Activity Tester...") logger.info("" + str(len(exported_act)) + " Exported Activities Identified") for line in exported_act: try: exp_act_no += 1 logger.info("Launching Exported Activity - " + str(exp_act_no) + ". " + line) adb_command([ "am", "start", "-n", package + "/" + line ], True) # AVD is much slower, it should get extra time if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": wait(8) else: wait(4) adb_command([ "screencap", "-p", "/data/local/screen.png" ], True) #? get appended from Air :-() if activity names are used adb_command([ "pull", "/data/local/screen.png", screen_dir + "expact-" + str(exp_act_no) + ".png" ]) logger.info("Activity Screenshot Taken") adb_command(["am", "force-stop", package], True) logger.info("Stopping App") except: PrintException("Exported Activity Tester") data = {'expacttest': 'done'} else: logger.info( "Exported Activity Tester - No Activity Found!") data = {'expacttest': 'noact'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response( request, "Entry does not exist in DB", True) else: return print_n_send_error_response(request, "Only POST allowed", True) else: return print_n_send_error_response(request, "Invalid Scan Hash", True) except: PrintException("ERROR] Exported Activity Tester") return print_n_send_error_response( request, "Error Running Exported Activity Tests", True)
def exported_activity_tester(request): """Exported Activity Tester""" logger.info("Exported Activity Tester") try: md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): return print_n_send_error_response(request, "Possible RCE Attack", True) if request.method == 'POST': base_dir = settings.BASE_DIR app_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') screen_dir = os.path.join(app_dir, 'screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) data = {} adb = getADB() static_android_db = StaticAnalyzerAndroid.objects.filter( MD5=md5_hash) if static_android_db.exists(): logger.info("Fetching Exported Activity List from DB") exported_act = python_list( static_android_db[0].EXPORTED_ACT) if exported_act: exp_act_no = 0 logger.info("Starting Exported Activity Tester...") logger.info("" + str(len(exported_act)) + " Exported Activities Identified") for line in exported_act: try: exp_act_no += 1 logger.info("Launching Exported Activity - " + str(exp_act_no) + ". " + line) adb_command( ["am", "start", "-n", package + "/" + line], True) # AVD is much slower, it should get extra time if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": wait(8) else: wait(4) adb_command( ["screencap", "-p", "/data/local/screen.png"], True) #? get appended from Air :-() if activity names are used adb_command(["pull", "/data/local/screen.png", screen_dir + "expact-" + str(exp_act_no) + ".png"]) logger.info("Activity Screenshot Taken") adb_command( ["am", "force-stop", package], True) logger.info("Stopping App") except: PrintException( "Exported Activity Tester") data = {'expacttest': 'done'} else: logger.info( "Exported Activity Tester - No Activity Found!") data = {'expacttest': 'noact'} return HttpResponse(json.dumps(data), content_type='application/json') else: return print_n_send_error_response(request, "Entry does not exist in DB", True) else: return print_n_send_error_response(request, "Only POST allowed", True) else: return print_n_send_error_response(request, "Invalid Scan Hash", True) except: PrintException("ERROR] Exported Activity Tester") return print_n_send_error_response(request, "Error Running Exported Activity Tests", True)
def activity_tester(request): """Activity Tester""" print("\n[INFO] Activity Tester") try: md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): print("[ATTACK] Possible RCE") return HttpResponseRedirect('/error/') if request.method == 'POST': base_dir = settings.BASE_DIR app_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') screen_dir = os.path.join(app_dir, 'screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) data = {} adb = getADB() static_android_db = StaticAnalyzerAndroid.objects.filter( MD5=md5_hash) if static_android_db.exists(): print("\n[INFO] Fetching Activity List from DB") activities = python_list(static_android_db[0].ACTIVITIES) if activities: act_no = 0 print("\n[INFO] Starting Activity Tester...") print("\n[INFO] " + str(len(activities)) + " Activities Identified") for line in activities: try: act_no += 1 print("\n[INFO] Launching Activity - " + str(act_no) + ". " + line) adb_command( ["am", "start", "-n", package + "/" + line], True) # AVD is much slower, it should get extra time if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": wait(8) else: wait(4) adb_command( ["screencap", "-p", "/data/local/screen.png"], True) #? get appended from Air :-() if activity names are used adb_command(["pull", "/data/local/screen.png", screen_dir + "act-" + str(act_no) + ".png"]) print("\n[INFO] Activity Screenshot Taken") adb_command( ["am", "force-stop", package], True) print("\n[INFO] Stopping App") except: PrintException("Activity Tester") data = {'acttest': 'done'} else: print("\n[INFO] Activity Tester - No Activity Found!") data = {'acttest': 'noact'} return HttpResponse(json.dumps(data), content_type='application/json') else: print("\n[ERROR] Entry does not exist in DB.") return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Activity Tester") return HttpResponseRedirect('/error/')
def dump_data(request): """Downloading Application Data from Device""" print("\n[INFO] Downloading Application Data from Device") try: if request.method == 'POST': data = {} package = request.POST['pkg'] md5_hash = request.POST['md5'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r";|\$\(|\|\||&&", package): print("[ATTACK] Possible RCE") return HttpResponseRedirect('/error/') base_dir = settings.BASE_DIR apk_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') # Let's try to close Proxy a bit early as we don't have much # control on the order of thread execution stop_capfuzz(settings.PORT) print("\n[INFO] Deleting Dump Status File") adb_command(["rm", "/sdcard/mobsec_status"], True) print("\n[INFO] Creating TAR of Application Files.") adb_command(["am", "startservice", "-a", package, "opensecurity.ajin.datapusher/.GetPackageLocation"], True) print("\n[INFO] Waiting for TAR dump to complete...") if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_REAL_DEVICE": timeout = settings.DEVICE_TIMEOUT else: timeout = settings.VM_TIMEOUT start_time = time.time() while True: current_time = time.time() if b"MOBSEC-TAR-CREATED" in adb_command(["cat", "/sdcard/mobsec_status"], shell=True): break if (current_time - start_time) > timeout: print( "\n[ERROR] TAR Generation Failed. Process timed out.") break print("\n[INFO] Dumping Application Files from Device/VM") adb_command(["pull", "/data/local/" + package + ".tar", apk_dir + package + ".tar"]) if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": print("\n[INFO] Removing package") adb_command(["uninstall", package]) stop_avd() print("\n[INFO] Stopping ADB") adb_command(["kill-server"]) data = {'dump': 'yes'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] Downloading Application Data from Device") return HttpResponseRedirect('/error/')
def activity_tester(request): """Activity Tester.""" logger.info('Activity Tester') try: md5_hash = request.POST['md5'] package = request.POST['pkg'] if re.match('^[0-9a-f]{32}$', md5_hash): if re.findall(r';|\$\(|\|\||&&', package): return print_n_send_error_response(request, 'Possible RCE Attack', True) if request.method == 'POST': app_dir = os.path.join(settings.UPLD_DIR, md5_hash + '/') screen_dir = os.path.join(app_dir, 'screenshots-apk/') if not os.path.exists(screen_dir): os.makedirs(screen_dir) data = {} static_android_db = StaticAnalyzerAndroid.objects.filter( MD5=md5_hash) if static_android_db.exists(): logger.info('Fetching Activity List from DB') activities = python_list(static_android_db[0].ACTIVITIES) if activities: act_no = 0 logger.info('Starting Activity Tester...') logger.info('%s Activities Identified', str(len(activities))) for line in activities: try: act_no += 1 logger.info( 'Launching Activity - %s. %s', str(act_no), line) adb_command(['am', 'start', '-n', package + '/' + line], True) wait(4) adb_command( ['screencap', '-p', '/data/local/screen.png'], True) # ? get appended from Air :-() # if activity names are used outfile = ('{}act-{}.png'.format( screen_dir, act_no)) adb_command(['pull', '/data/local/screen.png', outfile]) logger.info('Activity Screenshot Taken') adb_command( ['am', 'force-stop', package], True) logger.info('Stopping App') except Exception: logger.exception('Activity Tester') data = {'acttest': 'done'} else: logger.info('Activity Tester - No Activity Found!') data = {'acttest': 'noact'} return HttpResponse(json.dumps(data), content_type='application/json') else: err = 'Entry does not exist in DB' return print_n_send_error_response(request, err, True) else: return print_n_send_error_response(request, 'Only POST allowed', True) else: return print_n_send_error_response(request, 'Invalid Scan Hash', True) except Exception: logger.exception('Activity Tester') return print_n_send_error_response(request, 'Error Running Activity Tester', True)
def mobsf_ca(request): """Install and Remove MobSF Proxy RootCA""" try: if request.method == 'POST': data = {} act = request.POST['action'] rootca = get_ca_dir() adb = getADB() if act == "install": print("\n[INFO] Installing MobSF RootCA") adb_command( ["push", rootca, "/data/local/tmp/" + settings.ROOT_CA]) if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": # For some reason, avd emulator does not have cp binary adb_command(["/data/local/tmp/busybox", "cp", "/data/local/tmp/" + settings.ROOT_CA, "/system/etc/security/cacerts/" + settings.ROOT_CA], True) adb_command(["chmod", "644", "/system/etc/security/cacerts/" + settings.ROOT_CA], True) else: adb_command(["su", "-c", "cp", "/data/local/tmp/" + settings.ROOT_CA, "/system/etc/security/cacerts/" + settings.ROOT_CA], True) adb_command(["su", "-c", "chmod", "644", "/system/etc/security/cacerts/" + settings.ROOT_CA], True) adb_command( ["rm", "/data/local/tmp/" + settings.ROOT_CA], True) data = {'ca': 'installed'} elif act == "remove": print("\n[INFO] Removing MobSF RootCA") if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD": adb_command( ["rm", "/system/etc/security/cacerts/" + settings.ROOT_CA], True) else: adb_command(["su", "-c", "rm", "/system/etc/security/cacerts/" + settings.ROOT_CA], True) data = {'ca': 'removed'} return HttpResponse(json.dumps(data), content_type='application/json') else: return HttpResponseRedirect('/error/') except: PrintException("[ERROR] MobSF RootCA Handler") return HttpResponseRedirect('/error/')