Beispiel #1
0
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 + '/')
                toolsdir = os.path.join(base_dir,
                                        'DynamicAnalyzer/tools/')  # TOOLS DIR
                adb = getADB(toolsdir)
                # 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")
                subprocess.call([
                    adb, "-s",
                    get_identifier(), "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")
                subprocess.call([
                    adb, "-s",
                    get_identifier(), "shell", "am", "force-stop", package
                ])
                print("\n[INFO] Stopping Application")

                subprocess.call([
                    adb, "-s",
                    get_identifier(), "shell", "am", "force-stop",
                    "opensecurity.screencast"
                ])
                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 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 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']
            toolsdir = os.path.join(
                settings.BASE_DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
            adb = getADB(toolsdir)
            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 = [adb,
                        "-s",
                        get_identifier(),
                        "shell",
                        "am",
                        "startservice",
                        "-a",
                        ip_address + ":" + port,
                        "opensecurity.screencast/.StartScreenCast"]
                data = {'status': 'on'}
                TCP_SERVER_MODE = "on"
            elif mode == "off":
                args = [adb,
                        "-s",
                        get_identifier(),
                        "shell",
                        "am",
                        "force-stop",
                        "opensecurity.screencast"]
                data = {'status': 'off'}
                TCP_SERVER_MODE = "off"
            if (mode in ["on", "off"]):
                try:
                    subprocess.call(args)
                    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/')
Beispiel #4
0
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 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 getPidByPackage(adb, package):
    params = [adb, "-s", get_identifier(), "shell", "ps", "|grep", package]
    findPid = None
    retry = 0

    def tryOnce():
        pid_result = str(subprocess.check_output(params), encoding="utf-8")
        pid_result = pid_result.split("\n")
        for ps_item in pid_result:
            ps_item = ps_item.strip().split()
            #['u0_a19', '2396', '295', '580112', '51832', 'ffffffff', '94cca347', 'R', 'com.kuxuexi.math.high']
            if (len(ps_item) < 5):
                continue
            pid = ps_item[1]
            packagename = ps_item[-1]
            if (packagename == package):
                return pid
        return None

    for retry in range(0, 3):
        findPid = tryOnce()
        if (findPid is not None):
            break
        time.sleep(3)

    if (findPid is not None):
        print("package: %s ==> pid: %s" % (package, findPid))
        return findPid
    raise Exception("pid not found by packageName: %s", package)
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
Beispiel #8
0
def auto_app_test(adb, app_info):
    print(u'\n[INFO] 开始自动化测试...')

    # monkey script 测试,用于进入初始化界面
    monkey_script_test(adb, app_info)

    packagename = app_info['packagename']
    # monkey 测试,输出太多,重定向输出
    p = subprocess.Popen([
        adb, '-s',
        get_identifier(), 'shell', 'monkey', '-p', packagename,
        '--ignore-crashes', '--ignore-timeouts', '--monitor-native-crashes',
        '-v', '-v', '-v', '1000'
    ],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    # 设置超时检查
    start_time = time.time()
    while True:
        if p.poll() is not None:
            #useless_out, useless_err = p.communicate()
            break
        if time.time() - start_time > 60:
            p.terminate()
            break
        time.sleep(0.5)

    # TODO: 添加其他测试方法
    return
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 auto_app_test(app_info):
    base_dir = settings.BASE_DIR
    toolsdir = os.path.join(base_dir, 'DynamicAnalyzer/tools/')  # TOOLS DIR
    adb = getADB(toolsdir)

    print(u'\n[INFO] 开始自动化测试...')

    # monkey script 测试,用于进入初始化界面
    monkey_script_test(adb, app_info)

    packagename = app_info['packagename']
    # monkey 测试,输出太多,重定向输出
    p = subprocess.Popen([
        adb, '-s',
        get_identifier(), 'shell', 'monkey', '-p', packagename,
        '--ignore-crashes', '--ignore-timeouts', '--monitor-native-crashes',
        '-v', '-v', '-v', '300'
    ],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    # 设置超时检查
    start_time = time.time()
    while True:
        if p.poll() is not None:
            #useless_out, useless_err = p.communicate()
            break
        if time.time() - start_time > 60:
            p.terminate()
            break
        time.sleep(0.5)

    # TODO: 添加其他测试方法
    return
def execute_adb(request):
    """Execute ADB Commands"""
    print("\n[INFO] Executing ADB Commands")
    try:
        if request.method == 'POST':
            data = {}
            cmd = request.POST['cmd']
            '''
            Allow dangerous chars as it's functional
            TODO: Deal with it.
            '''
            adb = getADB()
            args = [adb, "-s", get_identifier()] + cmd.split(' ')
            resp = "error"
            try:
                resp = adb
            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"""
    print("\n[INFO] Executing ADB Commands")
    try:
        if request.method == 'POST':
            data = {}
            cmd = request.POST['cmd']
            '''
            Allow dangerous chars as it's functional
            TODO: Deal with it.
            '''
            toolsdir = os.path.join(
                settings.BASE_DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
            adb = getADB(toolsdir)
            args = [adb,
                    "-s",
                    get_identifier()] + cmd.split(' ')
            resp = "error"
            try:
                resp = subprocess.check_output(args)
            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 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']
            toolsdir = os.path.join(
                settings.BASE_DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
            adb = getADB(toolsdir)
            args = [adb,
                    "-s",
                    get_identifier(),
                    "shell",
                    "input",
                    "tap",
                    x_axis,
                    y_axis]
            data = {'status': 'success'}
            try:
                subprocess.call(args)
            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 clip_dump(request):
    """Dump Android ClipBoard"""
    print("\n[INFO] Starting Clipboard Dump Service in VM/Device")
    try:
        data = {}
        if request.method == 'POST':
            toolsdir = os.path.join(
                settings.BASE_DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
            adb = getADB(toolsdir)
            args = [adb,
                    "-s",
                    get_identifier(),
                    "shell",
                    "am",
                    "startservice",
                    "opensecurity.clipdump/.ClipDumper"]
            try:
                subprocess.call(args)
                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 getPidByPackage(adb, package):
    params = [adb, "-s", get_identifier(), "shell", "ps"]
    findPid = None
    retry = 0
    while retry < 3 and findPid is None:
        retry = retry + 1
        pid_result = subprocess.check_output(params)
        pid_result = pid_result.split("\n")
        for ps_item in pid_result:
            ps_item = ps_item.strip().split()
            #['u0_a19', '2396', '295', '580112', '51832', 'ffffffff', '94cca347', 'R', 'com.kuxuexi.math.high']
            if (len(ps_item) < 5):
                continue
            pid = ps_item[1]
            packagename = ps_item[-1]
            if (packagename == package):
                findPid = pid
                break
        if findPid is None:
            time.sleep(1)
    if findPid is not None:
        print("package: %s ==> pid: %s" % (package, findPid))
        return findPid
    raise Exception("pid not found by packageName: %s", package)

    raise Exception("pid not found by packageName")
def download_logs(adb, download_dir):
    subprocess.call([
        adb, "-s",
        get_identifier(), "pull",
        "/data/data/de.robv.android.xposed.installer/log/error.log",
        download_dir + "x_logcat_temp.txt"
    ])
    print("\n[INFO] Downloading Droidmon API Monitor Logcat logs")
    return
Beispiel #17
0
def stop_avd(adb):
    """Stop AVD"""
    print("\n[INFO] Stopping MobSF Emulator")
    try:
        # adb -s emulator-xxxx emu kill
        FNULL = open(os.devnull, 'w')
        args = [adb, '-s', get_identifier(), 'emu', 'kill']
        subprocess.call(args, stderr=FNULL)
    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)
                toolsdir = os.path.join(
                    base_dir, 'DynamicAnalyzer/tools/')  # TOOLS DIR
                adb = getADB(toolsdir)
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "shell",
                                 "screencap",
                                 "-p",
                                 "/data/local/screen.png"])
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "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/')
Beispiel #19
0
def download_logs(adb, download_dir):
    log_temp_path = os.path.join(download_dir, 'x_logcat_temp.txt')
    subprocess.call([
        adb, "-s",
        get_identifier(), "pull",
        "/data/data/de.robv.android.xposed.installer/log/error.log",
        log_temp_path
    ])
    print(time.time(), "[INFO] Downloading Droidmon API Monitor Logcat logs",
          log_temp_path)
    # TODO: 下载其他有用文件
    return
def clean():
    base_dir = settings.BASE_DIR
    toolsdir = os.path.join(base_dir, 'DynamicAnalyzer/tools/')  # TOOLS DIR
    adb = getADB(toolsdir)

    print("\n[INFO] Stopping ADB")
    subprocess.call([adb, "-s", get_identifier(), "kill-server"])
    # Close VM
    args = [settings.VBOX, 'controlvm', settings.UUID, 'poweroff']
    subprocess.call(args)
    print("\n[INFO] VM Closed")
    return
def download_logs_thread(adb, download_dir, package):
    #change to strace the pid
    '''
        step1: get pid by ps  | grep packageName
        step2: adb shell strace -T -tt -e trace=all -p pid > to windows_file
    '''
    if not os.path.isdir(download_dir):
        os.makedirs(download_dir)

    pid = getPidByPackage(adb, package)
    print("package: %s ==> pid: %s" % (package, pid))

    start_time = time.asctime(time.localtime(time.time()))
    print("strace start at: %s" % start_time)
    params = [
        adb, "-s",
        get_identifier(), "shell", "strace", "-T", "-tt", "-e", "trace=all",
        "-p", pid
    ]
    strace = subprocess.Popen(params,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
    strace_file = os.path.join(download_dir, 'systemcall.txt')
    with open(strace_file, 'w') as sc_file:
        try:
            # strace for 60 seconds
            outs, errs = strace.communicate(timeout=60)
        except subprocess.TimeoutExpired:
            strace.kill()
            outs, errs = strace.communicate()
        sinfo = str(outs.read())
        end_time = time.asctime(time.localtime(time.time()))
        print("strace end at: %s" % end_time)
        print("sinfo len: %s" % len(sinfo))
        if (Is_Downloading):
            sc_file.write(sinfo)

    # global Is_Downloading
    # while Is_Downloading:
    #     download_logs(adb, download_dir)
    #     log_path = os.path.join(download_dir, 'x_logcat.txt')
    #     log_temp_path = os.path.join(download_dir, 'x_logcat_temp.txt')
    #     if os.path.exists(log_path):
    #         log_size = os.path.getsize(log_path)
    #         log_temp_size = os.path.getsize(log_temp_path)
    #         if log_size < log_temp_size:
    #             shutil.copy(log_temp_path, log_path)
    #     else:
    #         shutil.copy(log_temp_path, log_path)
    #     os.remove(log_temp_path)
    #     time.sleep(10)
    return
def download_logs_thread(adb, download_dir, package):
    #change to strace the pid
    '''
        step1: get pid by ps  | grep packageName
        step2: strace, result store on vm 
            adb shell strace -T -tt -e trace=all -f -F -o /data/local/tmp/strace -p 2395
        step3: pull to pc
    '''
    if not os.path.isdir(download_dir):
        os.makedirs(download_dir)

    #step 1
    pid = getPidByPackage(adb, package)

    #step 2
    params = [adb, "-s", get_identifier(), "shell",\
        "strace", "-T", "-tt", "-e", "trace=all", "-f", "-F", "-o", "/data/local/tmp/strace",\
        "-p", pid]
    strace = subprocess.Popen(params)
    t_start = time.time()
    print("strace start: %s" % time.asctime(time.localtime(time.time())))
    try:
        # strace for 60 seconds
        _, _ = strace.communicate(timeout=100)
    except subprocess.TimeoutExpired:
        strace.kill()
    end_time = time.asctime(time.localtime(time.time()))
    print("strace end at: %s" % end_time)

    #step3
    strace_file = os.path.join(download_dir, 'systemcall.txt')
    subprocess.call([
        adb, "-s",
        get_identifier(), "pull", "/data/local/tmp/strace", strace_file
    ])
    return
Beispiel #23
0
def avd_load_wait(adb):
    """Wait for AVD Load"""

    emulator = get_identifier()

    print("[INFO] Wait for emulator to load")
    args = [adb, "-s", emulator, "wait-for-device"]
    subprocess.call(args)

    print("[INFO] Wait for dev.boot_complete loop")
    while True:
        args = [adb, "-s", emulator, "shell", "getprop", "dev.bootcomplete"]
        try:
            result = subprocess.check_output(args)
        except:
            result = None
        if result is not None and result.strip() == "1":
            break
        else:
            time.sleep(1)

    print("[INFO] Wait for sys.boot_complete loop")
    while True:
        args = [adb, "-s", emulator, "shell", "getprop", "sys.boot_completed"]
        try:
            result = subprocess.check_output(args)
        except:
            result = None
        if result is not None and result.strip() == "1":
            break
        else:
            time.sleep(1)

    print("[INFO] Wait for svc.boot_complete loop")
    while True:
        args = [adb, "-s", emulator, "shell", "getprop", "init.svc.bootanim"]
        try:
            result = subprocess.check_output(args)
        except:
            result = None
        if result is not None and result.strip() == "stopped":
            break
        else:
            time.sleep(1)
    time.sleep(5)
    # Remount the partitions for RW
    subprocess.call([adb, "-s", emulator, "remount"])
def monkey_test(adb, app_info):
    welcome_jump(adb, app_info)

    packagename = app_info['packagename']
    p = subprocess.Popen([
        adb, '-s',
        get_identifier(), 'shell', 'monkey', '-p', packagename,
        '--ignore-crashes', '--ignore-timeouts', '--monitor-native-crashes',
        '-v', '-v', '-v', '1000'
    ],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    start_time = time.time()
    while check_run_state():
        if p.poll() is not None:
            #useless_out, useless_err = p.communicate()
            break
        if time.time() - start_time > 60:
            break
        time.sleep(0.5)
    p.terminate()
    return
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 + '/')
                toolsdir = os.path.join(
                    base_dir, 'DynamicAnalyzer/tools/')  # TOOLS DIR
                adb = getADB(toolsdir)
                # 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")
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "shell",
                                 "rm",
                                 "/sdcard/mobsec_status"])
                print("\n[INFO] Creating TAR of Application Files.")
                if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD":
                    # tar -cvf /data/local/"+pkg+".tar /data/data/"+pkg+"/",
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "/data/local/tmp/tar.sh",
                                     package])
                else:
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "am",
                                     "startservice",
                                     "-a",
                                     package,
                                     "opensecurity.ajin.datapusher/.GetPackageLocation"])
                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 subprocess.check_output([adb,
                                                                         "-s",
                                                                         get_identifier(),
                                                                         "shell",
                                                                         "cat",
                                                                         "/sdcard/mobsec_status"]):
                        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")
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "pull",
                                 "/data/local/" + package + ".tar",
                                 apk_dir + package + ".tar"])
                if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD":
                    stop_avd(adb)
                print("\n[INFO] Stopping ADB")
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "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()
            toolsdir = os.path.join(
                settings.BASE_DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
            adb = getADB(toolsdir)
            if act == "install":
                print("\n[INFO] Installing RootCA")
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "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
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "/data/local/tmp/busybox",
                                     "cp",
                                     "/data/local/tmp/" + settings.ROOT_CA,
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "chmod",
                                     "644",
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                else:
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "su",
                                     "-c",
                                     "cp",
                                     "/data/local/tmp/" + settings.ROOT_CA,
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "su",
                                     "-c",
                                     "chmod",
                                     "644",
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                subprocess.call([adb,
                                 "-s",
                                 get_identifier(),
                                 "shell",
                                 "rm",
                                 "/data/local/tmp/" + settings.ROOT_CA])
                data = {'ca': 'installed'}
            elif act == "remove":
                print("\n[INFO] Removing RootCA")
                if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD":
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "rm",
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                else:
                    subprocess.call([adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "su",
                                     "-c",
                                     "rm",
                                     "/system/etc/security/cacerts/" + settings.ROOT_CA])
                data = {'ca': 'removed'}
            return HttpResponse(json.dumps(data), content_type='application/json')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] RootCA Handler")
        return HttpResponseRedirect('/error/')
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 + '/')
                toolsdir = os.path.join(
                    base_dir, 'DynamicAnalyzer/tools/')  # TOOLS DIR
                screen_dir = os.path.join(app_dir, 'screenshots-apk/')
                if not os.path.exists(screen_dir):
                    os.makedirs(screen_dir)
                data = {}
                adb = getADB(toolsdir)
                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)
                                subprocess.call(
                                    [adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "am",
                                     "start",
                                     "-n",
                                     package + "/" + line])
                                # AVD is much slower, it should get extra time
                                if settings.ANDROID_DYNAMIC_ANALYZER == "MobSF_AVD":
                                    wait(8)
                                else:
                                    wait(4)
                                subprocess.call(
                                    [adb,
                                     "-s",
                                     get_identifier(),
                                     "shell",
                                     "screencap",
                                     "-p",
                                     "/data/local/screen.png"])
                                #? get appended from Air :-() if activity names are used
                                subprocess.call(
                                    [adb,
                                     "-s",
                                     get_identifier(),
                                     "pull",
                                     "/data/local/screen.png",
                                     screen_dir + "act-" + str(act_no) + ".png"])
                                print("\n[INFO] Activity Screenshot Taken")
                                subprocess.call([adb,
                                                 "-s",
                                                 get_identifier(),
                                                 "shell",
                                                 "am",
                                                 "force-stop",
                                                 package])
                                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 monkey_script_test(adb, app_info):
    monkey_script_pattern = '''
    type=user
    count=10
    speed=1.0
    start data >>
    captureDispatchPointer(0,0,0,200,600,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,200,600,1,1,-1,1,1,0,0)
    UserWait(1000)
    captureDispatchPointer(0,0,0,400,600,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,400,600,1,1,-1,1,1,0,0)
    UserWait(1000)
    captureDispatchPointer(0,0,0,600,600,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,600,600,1,1,-1,1,1,0,0)
    UserWait(1000)
    captureDispatchPointer(0,0,0,200,800,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,200,800,1,1,-1,1,1,0,0)
    UserWait(1000)
    captureDispatchPointer(0,0,0,600,1000,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,600,1000,1,1,-1,1,1,0,0)
    UserWait(3000)
    LaunchActivity({packagename}, {mainactivity})
    UserWait(5000)
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    Drag({screen_x_right},{screen_y_middle},{screen_x_left},{screen_y_middle},70)
    UserWait({drag_wait})
    captureDispatchPointer(0,0,0,{screen_x_middle},100,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},100,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},200,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},200,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},300,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},300,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},400,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},400,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},500,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},500,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},600,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},600,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},700,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},700,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},800,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},800,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},900,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},900,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},1000,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},1000,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},1100,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},1100,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,0,{screen_x_middle},1200,1,1,-1,1,1,0,0)
    captureDispatchPointer(0,0,1,{screen_x_middle},1200,1,1,-1,1,1,0,0)
    UserWait(1000)
    captureDispatchPress(4)
    captureDispatchPress(4)
    captureDispatchPress(4)
    '''
    drag_wait = 750
    packagename = app_info['packagename']
    mainactivity = app_info['mainactivity']
    if mainactivity.startswith('.'):
        mainactivity = packagename + mainactivity
    screen_x_right = 750
    screen_y_middle = 640
    screen_x_left = 50
    screen_x_middle = 400

    monkey_script_data = monkey_script_pattern.format(
        drag_wait=drag_wait,
        packagename=packagename,
        mainactivity=mainactivity,
        screen_x_right=screen_x_right,
        screen_y_middle=screen_y_middle,
        screen_x_left=screen_x_left,
        screen_x_middle=screen_x_middle)

    UPLOAD_DIR = settings.UPLD_DIR
    monkey_script_file_name = os.path.join(
        os.path.join(UPLOAD_DIR, app_info['file_md5']), 'monkey_script.txt')
    with open(monkey_script_file_name, 'w') as f:
        f.write(monkey_script_data)

    subprocess.call([
        adb, "-s",
        get_identifier(), "push", monkey_script_file_name, "/data/local/tmp"
    ])
    subprocess.call([
        adb, "-s",
        get_identifier(), "shell", "monkey", "-f",
        "/data/local/tmp/monkey_script.txt", "1"
    ])
    print(u'\n[INFO] 跳过初始化界面')
    return