def get_context_from_db_entry_ipa(db_entry):
    """Return the context for IPA from DB"""
    try:
        print("\n[INFO] Analysis is already Done. Fetching data from the DB...")
        context = {
            'title': db_entry[0].TITLE,
            'file_name': db_entry[0].FILE_NAME,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'plist': db_entry[0].INFOPLIST,
            'bin_name': db_entry[0].BINNAME,
            'id': db_entry[0].IDF,
            'build': db_entry[0].BUILD,
            'version': db_entry[0].VERSION,
            'sdk': db_entry[0].SDK,
            'pltfm': db_entry[0].PLTFM,
            'min': db_entry[0].MINX,
            'bin_anal': python_list(db_entry[0].BIN_ANAL),
            'libs': python_list(db_entry[0].LIBS),
            'files': python_list(db_entry[0].FILES),
            'file_analysis': python_list(db_entry[0].SFILESX),
            'strings': python_list(db_entry[0].STRINGS),
            'permissions': python_list(db_entry[0].PERMISSIONS),
            'insecure_connections': python_list(db_entry[0].INSECCON),
            'bundle_name': db_entry[0].BUNDLE_NAME,
            'bundle_url_types': python_list(db_entry[0].BUNDLE_URL_TYPES),
            'bundle_supported_platforms': python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
            'bundle_localizations': python_list(db_entry[0].BUNDLE_LOCALIZATIONS),

        }
        return context
    except:
        PrintException("[ERROR] Fetching from DB")
def get_context_from_db_entry_ios(db_entry):
    """Return the context for IOS ZIP from DB"""
    try:
        print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
        context = {
            'title': db_entry[0].TITLE,
            'name': db_entry[0].APPNAMEX,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'plist': db_entry[0].INFOPLIST,
            'bin_name': db_entry[0].BINNAME,
            'id': db_entry[0].IDF,
            'ver': db_entry[0].VERSION,
            'sdk': db_entry[0].SDK,
            'pltfm': db_entry[0].PLTFM,
            'min': db_entry[0].MINX,
            'files': python_list(db_entry[0].FILES),
            'file_analysis': db_entry[0].SFILESX,
            'api': python_dict(db_entry[0].API),
            'insecure': python_dict(db_entry[0].CODEANAL),
            'urls': python_list(db_entry[0].URLnFile),
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': python_list(db_entry[0].EmailnFile),
            'permissions': python_list(db_entry[0].PERMISSIONS),
            'insecure_connections': python_list(db_entry[0].INSECCON)
        }
        return context
    except:
        PrintException("[ERROR] Fetching from DB")
def get_context_from_db_entry_ipa(db_entry):
    """Return the context for IPA from DB"""
    try:
        print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
        context = {
            'title': db_entry[0].TITLE,
            'name': db_entry[0].APPNAMEX,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'plist': db_entry[0].INFOPLIST,
            'bin_name': db_entry[0].BINNAME,
            'id': db_entry[0].IDF,
            'ver': db_entry[0].VERSION,
            'sdk': db_entry[0].SDK,
            'pltfm': db_entry[0].PLTFM,
            'min': db_entry[0].MINX,
            'bin_anal': db_entry[0].BIN_ANAL,
            'libs': db_entry[0].LIBS,
            'files': python_list(db_entry[0].FILES),
            'file_analysis': db_entry[0].SFILESX,
            'strings': python_list(db_entry[0].STRINGS),
            'permissions': python_list(db_entry[0].PERMISSIONS),
            'insecure_connections': python_list(db_entry[0].INSECCON)
        }
        return context
    except:
        PrintException("[ERROR] Fetching from DB")
def get_context_from_db_entry(db_entry):
    """Return the context for APK/ZIP from DB"""
    try:
        print "\n[INFO] Analysis is already Done. Fetching data from the DB..."

        context = {
            'title': db_entry[0].TITLE,
            'name': db_entry[0].APP_NAME,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'packagename': db_entry[0].PACKAGENAME,
            'mainactivity': db_entry[0].MAINACTIVITY,
            'targetsdk': db_entry[0].TARGET_SDK,
            'maxsdk': db_entry[0].MAX_SDK,
            'minsdk': db_entry[0].MIN_SDK,
            'androvername': db_entry[0].ANDROVERNAME,
            'androver': db_entry[0].ANDROVER,
            'manifest': python_list(db_entry[0].MANIFEST_ANAL),
            'permissions': python_dict(db_entry[0].PERMISSIONS),
            'binary_analysis': python_list(db_entry[0].BIN_ANALYSIS),
            'files': python_list(db_entry[0].FILES),
            'certz': db_entry[0].CERTZ,
            'activities': python_list(db_entry[0].ACTIVITIES),
            'receivers': python_list(db_entry[0].RECEIVERS),
            'providers': python_list(db_entry[0].PROVIDERS),
            'services': python_list(db_entry[0].SERVICES),
            'libraries': python_list(db_entry[0].LIBRARIES),
            'browsable_activities': python_dict(db_entry[0].BROWSABLE),
            'act_count': db_entry[0].CNT_ACT,
            'prov_count': db_entry[0].CNT_PRO,
            'serv_count': db_entry[0].CNT_SER,
            'bro_count': db_entry[0].CNT_BRO,
            'certinfo': db_entry[0].CERT_INFO,
            'issued': db_entry[0].ISSUED,
            'native': db_entry[0].NATIVE,
            'dynamic': db_entry[0].DYNAMIC,
            'reflection': db_entry[0].REFLECT,
            'crypto': db_entry[0].CRYPTO,
            'obfus': db_entry[0].OBFUS,
            'api': db_entry[0].API,
            'dang': db_entry[0].DANG,
            'urls': db_entry[0].URLS,
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': db_entry[0].EMAILS,
            'strings': python_list(db_entry[0].STRINGS),
            'zipped': db_entry[0].ZIPPED,
            'mani': db_entry[0].MANI,
            'e_act': db_entry[0].E_ACT,
            'e_ser': db_entry[0].E_SER,
            'e_bro': db_entry[0].E_BRO,
            'e_cnt': db_entry[0].E_CNT,
        }
        return context
    except:
        PrintException("[ERROR] Fetching from DB")
def ActivityTester(request):
    print "\n[INFO] Activity Tester"
    try:
        MD5 = request.POST['md5']
        PKG = request.POST['pkg']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            if request.method == 'POST':
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR, MD5 + '/')
                TOOLS_DIR = os.path.join(
                    DIR, 'DynamicAnalyzer/tools/')  # TOOLS DIR
                SCRDIR = os.path.join(APP_DIR, 'screenshots-apk/')
                data = {}
                adb = getADB(TOOLS_DIR)
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching Activity List from DB"
                    ACTIVITIES = python_list(DB[0].ACTIVITIES)
                    if ACTIVITIES:
                        n = 0
                        print "\n[INFO] Starting Activity Tester..."
                        print "\n[INFO] " + str(len(ACTIVITIES)) + " Activities Identified"
                        for line in ACTIVITIES:
                            try:
                                n += 1
                                print "\n[INFO] Launching Activity - " + str(n) + ". " + line
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "shell", "am", "start", "-n", PKG + "/" + line])
                                Wait(4)
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "shell", "screencap", "-p", "/data/local/screen.png"])
                                #? get appended from Air :-() if activity names are used
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "pull", "/data/local/screen.png", SCRDIR + "act-" + str(n) + ".png"])
                                print "\n[INFO] Activity Screenshot Taken"
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "shell", "am", "force-stop", PKG])
                                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 get_context_from_db_entry_ios(db_entry):
    """Return the context for IOS ZIP from DB"""
    try:
        logger.info("Analysis is already Done. Fetching data from the DB...")
        context = {
            'title': db_entry[0].TITLE,
            'file_name': db_entry[0].FILE_NAME,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'plist': db_entry[0].INFOPLIST,
            'bin_name': db_entry[0].BINNAME,
            'id': db_entry[0].IDF,
            'build': db_entry[0].BUILD,
            'version': db_entry[0].VERSION,
            'sdk': db_entry[0].SDK,
            'pltfm': db_entry[0].PLTFM,
            'min': db_entry[0].MINX,
            'files': python_list(db_entry[0].FILES),
            'file_analysis': python_list(db_entry[0].SFILESX),
            'api': python_dict(db_entry[0].API),
            'insecure': python_dict(db_entry[0].CODEANAL),
            'urls': python_list(db_entry[0].URLnFile),
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': python_list(db_entry[0].EmailnFile),
            'permissions': python_list(db_entry[0].PERMISSIONS),
            'insecure_connections': python_list(db_entry[0].INSECCON),
            'bundle_name': db_entry[0].BUNDLE_NAME,
            'bundle_url_types': python_list(db_entry[0].BUNDLE_URL_TYPES),
            'bundle_supported_platforms': python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
            'bundle_localizations': python_list(db_entry[0].BUNDLE_LOCALIZATIONS),
            'appstore_details': python_dict(db_entry[0].APPSTORE_DETAILS),
            'firebase': python_list(db_entry[0].FIREBASE),
        }
        return context
    except:
        PrintException("Fetching from DB")
예제 #7
0
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)
예제 #8
0
def get_context_from_db_entry_ipa(db_entry):
    """Return the context for IPA from DB."""
    try:
        logger.info('Analysis is already Done. Fetching data from the DB...')
        context = {
            'title':
            db_entry[0].TITLE,
            'file_name':
            db_entry[0].FILE_NAME,
            'size':
            db_entry[0].SIZE,
            'md5':
            db_entry[0].MD5,
            'sha1':
            db_entry[0].SHA1,
            'sha256':
            db_entry[0].SHA256,
            'plist':
            db_entry[0].INFOPLIST,
            'bin_name':
            db_entry[0].BINNAME,
            'id':
            db_entry[0].IDF,
            'build':
            db_entry[0].BUILD,
            'version':
            db_entry[0].VERSION,
            'sdk':
            db_entry[0].SDK,
            'pltfm':
            db_entry[0].PLTFM,
            'min':
            db_entry[0].MINX,
            'bin_anal':
            python_list(db_entry[0].BIN_ANAL),
            'libs':
            python_list(db_entry[0].LIBS),
            'files':
            python_list(db_entry[0].FILES),
            'file_analysis':
            python_list(db_entry[0].SFILESX),
            'strings':
            python_list(db_entry[0].STRINGS),
            'permissions':
            python_list(db_entry[0].PERMISSIONS),
            'insecure_connections':
            python_list(db_entry[0].INSECCON),
            'bundle_name':
            db_entry[0].BUNDLE_NAME,
            'bundle_url_types':
            python_list(db_entry[0].BUNDLE_URL_TYPES),
            'bundle_supported_platforms':
            python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
            'bundle_localizations':
            python_list(db_entry[0].BUNDLE_LOCALIZATIONS),
            'binary_info':
            python_dict(db_entry[0].MACHOINFO),
            'bin_type':
            db_entry[0].BINTYPE,
            'appstore_details':
            python_dict(db_entry[0].APPSTORE_DETAILS),
        }
        return context
    except Exception:
        logger.exception('Fetching from DB')
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = {
                        'title': DB[0].TITLE,
                        'name': DB[0].APP_NAME,
                        'size': DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1': DB[0].SHA1,
                        'sha256': DB[0].SHA256,
                        'packagename': DB[0].PACKAGENAME,
                        'mainactivity': DB[0].MAINACTIVITY,
                        'targetsdk': DB[0].TARGET_SDK,
                        'maxsdk': DB[0].MAX_SDK,
                        'minsdk': DB[0].MIN_SDK,
                        'androvername': DB[0].ANDROVERNAME,
                        'androver': DB[0].ANDROVER,
                        'manifest': DB[0].MANIFEST_ANAL,
                        'permissions': DB[0].PERMISSIONS,
                        'files': python_list(DB[0].FILES),
                        'certz': DB[0].CERTZ,
                        'activities': python_list(DB[0].ACTIVITIES),
                        'receivers': python_list(DB[0].RECEIVERS),
                        'providers': python_list(DB[0].PROVIDERS),
                        'services': python_list(DB[0].SERVICES),
                        'libraries': python_list(DB[0].LIBRARIES),
                        'act_count': DB[0].CNT_ACT,
                        'prov_count': DB[0].CNT_PRO,
                        'serv_count': DB[0].CNT_SER,
                        'bro_count': DB[0].CNT_BRO,
                        'certinfo': DB[0].CERT_INFO,
                        'issued': DB[0].ISSUED,
                        'native': DB[0].NATIVE,
                        'dynamic': DB[0].DYNAMIC,
                        'reflection': DB[0].REFLECT,
                        'crypto': DB[0].CRYPTO,
                        'obfus': DB[0].OBFUS,
                        'api': DB[0].API,
                        'dang': DB[0].DANG,
                        'urls': DB[0].URLS,
                        'domains': python_dict(DB[0].DOMAINS),
                        'emails': DB[0].EMAILS,
                        'strings': python_list(DB[0].STRINGS),
                        'zipped': DB[0].ZIPPED,
                        'mani': DB[0].MANI
                    }
                    if TYP == 'APK':
                        template = get_template("static_analysis_pdf.html")
                    else:
                        template = get_template("static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(json.dumps({"report": "Report not Found"}),
                                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'strings': DB[0].STRINGS
                        }
                        template = get_template("ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'api': DB[0].HTML,
                            'insecure': DB[0].CODEANAL,
                            'urls': DB[0].URLnFile,
                            'domains': python_dict(DB[0].DOMAINS),
                            'emails': DB[0].EmailnFile
                        }
                        template = get_template("ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX',TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter( # pylint: disable-msg=E1101
                        MD5=MD5
                    )
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"
                        context = {
                            'title' : db_entry[0].TITLE,
                            'name' : db_entry[0].APP_NAME,
                            'pub_name' : db_entry[0].PUB_NAME,
                            'size' : db_entry[0].SIZE,
                            'md5': db_entry[0].MD5,
                            'sha1' : db_entry[0].SHA1,
                            'sha256' : db_entry[0].SHA256,
                            'bin_name' : db_entry[0].BINNAME,
                            'version' :  db_entry[0].VERSION,
                            'arch' :  db_entry[0].ARCH,
                            'compiler_version' :  db_entry[0].COMPILER_VERSION,
                            'visual_studio_version' :  db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition' :  db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os' :  db_entry[0].TARGET_OS,
                            'appx_dll_version' :  db_entry[0].APPX_DLL_VERSION,
                            'proj_guid' :  db_entry[0].PROJ_GUID,
                            'opti_tool' :  db_entry[0].OPTI_TOOL,
                            'target_run' :  db_entry[0].TARGET_RUN,
                            'files' :  python_list(db_entry[0].FILES),
                            'strings' : db_entry[0].STRINGS,
                            'bin_an_results' : python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings' : python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template= get_template("windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(json.dumps({"type": "Type is not Allowed"}),
                                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO("{0}".format(
                html.encode('utf-8'))), result, encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(), content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = get_context_from_db_entry(DB)
                    if TYP == 'APK':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(json.dumps({"report": "Report not Found"}),
                                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'strings': python_list(DB[0].STRINGS),
                            'permissions': python_list(DB[0].PERMISSIONS)
                        }
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'api': DB[0].HTML,
                            'insecure': DB[0].CODEANAL,
                            'urls': DB[0].URLnFile,
                            'domains': python_dict(DB[0].DOMAINS),
                            'emails': DB[0].EmailnFile,
                            'permissions': python_list(DB[0].PERMISSIONS)
                        }
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX', TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=MD5
                    )
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"

                        context = {
                            'title': db_entry[0].TITLE,
                            'name': db_entry[0].APP_NAME,
                            'pub_name': db_entry[0].PUB_NAME,
                            'size': db_entry[0].SIZE,
                            'md5': db_entry[0].MD5,
                            'sha1': db_entry[0].SHA1,
                            'sha256': db_entry[0].SHA256,
                            'bin_name': db_entry[0].BINNAME,
                            'version':  db_entry[0].VERSION,
                            'arch':  db_entry[0].ARCH,
                            'compiler_version':  db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':  db_entry[0].TARGET_OS,
                            'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':  db_entry[0].PROJ_GUID,
                            'opti_tool':  db_entry[0].OPTI_TOOL,
                            'target_run':  db_entry[0].TARGET_RUN,
                            'files':  python_list(db_entry[0].FILES),
                            'strings': python_list(db_entry[0].STRINGS),
                            'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(json.dumps({"type": "Type is not Allowed"}),
                                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO("{0}".format(
                html.encode('utf-8'))), result, encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(), content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
예제 #11
0
def get_context_from_db_entry(db_entry):
    """Return the context for IPA/ZIP from DB."""
    try:
        logger.info('Analysis is already Done. Fetching data from the DB...')
        context = {
            'version': settings.MOBSF_VER,
            'title': 'Static Analysis',
            'file_name': db_entry[0].FILE_NAME,
            'app_name': db_entry[0].APP_NAME,
            'app_type': db_entry[0].APP_TYPE,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'build': db_entry[0].BUILD,
            'app_version': db_entry[0].APP_VERSION,
            'sdk_name': db_entry[0].SDK_NAME,
            'platform': db_entry[0].PLATFORM,
            'min_os_version': db_entry[0].MIN_OS_VERSION,
            'bundle_id': db_entry[0].BUNDLE_ID,
            'bundle_url_types': python_list(db_entry[0].BUNDLE_URL_TYPES),
            'bundle_supported_platforms':
                python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
            'info_plist': db_entry[0].INFO_PLIST,
            'binary_info': python_dict(db_entry[0].MACHO_INFO),
            'permissions': python_list(db_entry[0].PERMISSIONS),
            'ats_analysis': python_list(db_entry[0].ATS_ANALYSIS),
            'binary_analysis': python_list(db_entry[0].BINARY_ANALYSIS),
            'ios_api': python_dict(db_entry[0].IOS_API),
            'code_analysis': python_dict(db_entry[0].CODE_ANALYSIS),
            'file_analysis': python_list(db_entry[0].FILE_ANALYSIS),
            'libraries': python_list(db_entry[0].LIBRARIES),
            'files': python_list(db_entry[0].FILES),
            'urls': python_list(db_entry[0].URLS),
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': python_list(db_entry[0].EMAILS),
            'strings': python_list(db_entry[0].STRINGS),
            'firebase_urls': python_list(db_entry[0].FIREBASE_URLS),
            'appstore_details': python_dict(db_entry[0].APPSTORE_DETAILS),

        }
        return context
    except Exception:
        logger.exception('Fetching from DB')
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 PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = get_context_from_db_entry(DB)
                    if TYP == 'APK':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(
                        json.dumps({"report": "Report not Found"}),
                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = get_context_from_db_entry_ipa(DB)
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = get_context_from_db_entry_ios(DB)
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX', TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=MD5)
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"

                        context = {
                            'title':
                            db_entry[0].TITLE,
                            'name':
                            db_entry[0].APP_NAME,
                            'pub_name':
                            db_entry[0].PUB_NAME,
                            'size':
                            db_entry[0].SIZE,
                            'md5':
                            db_entry[0].MD5,
                            'sha1':
                            db_entry[0].SHA1,
                            'sha256':
                            db_entry[0].SHA256,
                            'bin_name':
                            db_entry[0].BINNAME,
                            'version':
                            db_entry[0].VERSION,
                            'arch':
                            db_entry[0].ARCH,
                            'compiler_version':
                            db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':
                            db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':
                            db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':
                            db_entry[0].TARGET_OS,
                            'appx_dll_version':
                            db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':
                            db_entry[0].PROJ_GUID,
                            'opti_tool':
                            db_entry[0].OPTI_TOOL,
                            'target_run':
                            db_entry[0].TARGET_RUN,
                            'files':
                            python_list(db_entry[0].FILES),
                            'strings':
                            python_list(db_entry[0].STRINGS),
                            'bin_an_results':
                            python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings':
                            python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(
                    json.dumps({"type": "Type is not Allowed"}),
                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            try:
                options = {
                    'page-size': 'A4',
                    'quiet': '',
                    'no-collate': '',
                    'margin-top': '0.50in',
                    'margin-right': '0.50in',
                    'margin-bottom': '0.50in',
                    'margin-left': '0.50in',
                    'encoding': "UTF-8",
                    'custom-header': [('Accept-Encoding', 'gzip')],
                    'no-outline': None
                }
                pdf = pdfkit.from_string(html, False, options=options)
                return HttpResponse(pdf, content_type='application/pdf')
            except Exception as exp:
                return HttpResponse(
                    json.dumps({
                        "pdf_error": "Cannot Generate PDF",
                        "err_details": str(exp)
                    }),
                    content_type="application/json; charset=utf-8")

        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def staticanalyzer_windows(request, api=False):
    """Analyse a windows app."""
    try:
        # Input validation
        logger.info("Windows Static Analysis Started")
        app_dic = {}  # Dict to store the binary attributes
        if api:
            typ = request.POST['scan_type']
            rescan = str(request.POST.get('re_scan', 0))
            checksum = request.POST['hash']
            filename = request.POST['file_name']
        else:
            typ = request.GET['type']
            rescan = str(request.GET.get('rescan', 0))
            checksum = request.GET['checksum']
            filename = request.GET['name']
        md5_regex = re.match('^[0-9a-f]{32}$', checksum)
        if (md5_regex) and (typ in ['appx']):
            app_dic['app_name'] = filename  # APP ORGINAL NAME
            app_dic['md5'] = checksum
            app_dic['app_dir'] = os.path.join(
                settings.UPLD_DIR, app_dic['md5'] + '/')
            app_dic['tools_dir'] = os.path.join(
                settings.BASE_DIR, 'StaticAnalyzer/tools/windows/')
            if typ == 'appx':
                # DB
                db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                    MD5=app_dic['md5']
                )
                if db_entry.exists() and rescan == '0':
                    logger.info("Analysis is already Done. Fetching data from the DB...")
                    context = {
                        'title': db_entry[0].TITLE,
                        'name': db_entry[0].APP_NAME,
                        'pub_name': db_entry[0].PUB_NAME,
                        'size': db_entry[0].SIZE,
                        'md5': db_entry[0].MD5,
                        'sha1': db_entry[0].SHA1,
                        'sha256': db_entry[0].SHA256,
                        'bin_name': db_entry[0].BINNAME,
                        'version':  db_entry[0].VERSION,
                        'arch':  db_entry[0].ARCH,
                        'compiler_version':  db_entry[0].COMPILER_VERSION,
                        'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                        'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                        'target_os':  db_entry[0].TARGET_OS,
                        'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                        'proj_guid':  db_entry[0].PROJ_GUID,
                        'opti_tool':  db_entry[0].OPTI_TOOL,
                        'target_run':  db_entry[0].TARGET_RUN,
                        'files': python_list(db_entry[0].FILES),
                        'strings': python_list(db_entry[0].STRINGS),
                        'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                        'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                    }
                else:
                    logger.info("Windows Binary Analysis Started")
                    app_dic['app_path'] = os.path.join(
                        app_dic['app_dir'], app_dic['md5'] + '.appx')
                    # ANALYSIS BEGINS
                    app_dic['size'] = str(file_size(app_dic['app_path'])) + 'MB'
                    # Generate hashes
                    app_dic['sha1'], app_dic[
                        'sha256'] = hash_gen(app_dic['app_path'])
                    # EXTRACT APPX
                    logger.info("Extracting APPX")
                    app_dic['files'] = unzip(
                        app_dic['app_path'], app_dic['app_dir'])
                    xml_dic = _parse_xml(app_dic['app_dir'])
                    bin_an_dic = _binary_analysis(app_dic)
                    # Saving to db
                    logger.info("Connecting to DB")
                    if rescan == '1':
                        logger.info("Updating Database...")
                        StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                            MD5=app_dic['md5']
                        ).update(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                    elif rescan == '0':
                        logger.info("Saving to Database")
                        db_item = StaticAnalyzerWindows(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                        db_item.save()
                    context = {
                        'title': 'Static Analysis',
                        'name': app_dic['app_name'],
                        'pub_name': xml_dic['pub_name'],
                        'size': app_dic['size'],
                        'md5': app_dic['md5'],
                        'sha1': app_dic['sha1'],
                        'sha256': app_dic['sha256'],
                        'bin_name': bin_an_dic['bin_name'],
                        'version': xml_dic['version'],
                        'arch': xml_dic['arch'],
                        'compiler_version': xml_dic['compiler_version'],
                        'visual_studio_version': xml_dic['visual_studio_version'],
                        'visual_studio_edition': xml_dic['visual_studio_edition'],
                        'target_os': xml_dic['target_os'],
                        'appx_dll_version': xml_dic['appx_dll_version'],
                        'proj_guid': xml_dic['proj_guid'],
                        'opti_tool': xml_dic['opti_tool'],
                        'target_run': xml_dic['target_run'],
                        'files': app_dic['files'],
                        'strings': bin_an_dic['strings'],
                        'bin_an_results': bin_an_dic['results'],
                        'bin_an_warnings': bin_an_dic['warnings'],
                    }
                template = "static_analysis/windows_binary_analysis.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            else:
                msg = "File type not supported"
                if api:
                    return print_n_send_error_response(request, msg, True)
                else:
                    return print_n_send_error_response(request, msg, False)
        else:
            msg = "Hash match failed or Invalid file extension"
            if api:
                return print_n_send_error_response(request, msg, True)
            else:
                return print_n_send_error_response(request, msg, False)
    except Exception as exception:
        msg = str(exception)
        exp_doc = exception.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp_doc)
        else:
            return print_n_send_error_response(request, msg, False, exp_doc)
예제 #15
0
def APIAnalysis(PKG, LOCATION):
    print "\n[INFO] Dynamic API Analysis"
    dat = ""
    API_BASE64 = []
    API_FILEIO = []
    API_RELECT = []
    API_SYSPROP = []
    API_CNTRSLVR = []
    API_CNTVAL = []
    API_BINDER = []
    API_CRYPTO = []
    API_ACNTMNGER = []
    API_DEVICEINFO = []
    API_NET = []
    API_DEXLOADER = []
    API_CMD = []
    API_SMS = []
    try:
        with open(LOCATION, "r") as f:
            dat = f.readlines()
        ID = "Droidmon-apimonitor-" + PKG + ":"
        for line in dat:
            line = line.decode('utf8', 'ignore')
            if (ID) in line:
                #print "LINE: " + line
                param, value = line.split(ID, 1)
                #print "PARAM is :" + param
                #print "Value is :"+ value
                try:
                    APIs = json.loads(value, strict=False)
                    RET = ''
                    CLS = ''
                    MTD = ''
                    ARGS = ''
                    MTD = str(APIs["method"])
                    CLS = str(APIs["class"])
                    #print "Called Class: " + CLS
                    #print "Called Method: " + MTD
                    if APIs.get('return'):
                        RET = str(APIs["return"])
                        #print "Return Data: " + RET
                    else:
                        #print "No Return Data"
                        RET = "No Return Data"
                    if APIs.get('args'):
                        ARGS = str(APIs["args"])
                        #print "Passed Arguments" + ARGS
                    else:
                        #print "No Arguments Passed"
                        ARGS = "No Arguments Passed"
                    #XSS Safe
                    D = "</br>METHOD: " + escape(
                        MTD) + "</br>ARGUMENTS: " + escape(
                            ARGS) + "</br>RETURN DATA: " + escape(RET)

                    if re.findall("android.util.Base64", CLS):
                        #Base64 Decode
                        if ("decode" in MTD):
                            args_list = python_list(ARGS)
                            if isBase64(args_list[0]):
                                D += '</br><span class="label label-info">Decoded String:</span> ' + escape(
                                    base64.b64decode(args_list[0]))
                        API_BASE64.append(D)
                    if re.findall(
                            'libcore.io|android.app.SharedPreferencesImpl$EditorImpl',
                            CLS):
                        API_FILEIO.append(D)
                    if re.findall('java.lang.reflect', CLS):
                        API_RELECT.append(D)
                    if re.findall(
                            'android.content.ContentResolver|android.location.Location|android.media.AudioRecord|android.media.MediaRecorder|android.os.SystemProperties',
                            CLS):
                        API_SYSPROP.append(D)
                    if re.findall(
                            'android.app.Activity|android.app.ContextImpl|android.app.ActivityThread',
                            CLS):
                        API_BINDER.append(D)
                    if re.findall(
                            'javax.crypto.spec.SecretKeySpec|javax.crypto.Cipher|javax.crypto.Mac',
                            CLS):
                        API_CRYPTO.append(D)
                    if re.findall(
                            'android.accounts.AccountManager|android.app.ApplicationPackageManager|android.app.NotificationManager|android.net.ConnectivityManager|android.content.BroadcastReceiver',
                            CLS):
                        API_ACNTMNGER.append(D)
                    if re.findall(
                            'android.telephony.TelephonyManager|android.net.wifi.WifiInfo|android.os.Debug',
                            CLS):
                        API_DEVICEINFO.append(D)
                    if re.findall(
                            'dalvik.system.BaseDexClassLoader|dalvik.system.DexFile|dalvik.system.DexClassLoader|dalvik.system.PathClassLoader',
                            CLS):
                        API_DEXLOADER.append(D)
                    if re.findall(
                            'java.lang.Runtime|java.lang.ProcessBuilder|java.io.FileOutputStream|java.io.FileInputStream|android.os.Process',
                            CLS):
                        API_CMD.append(D)
                    if re.findall('android.content.ContentValues', CLS):
                        API_CNTVAL.append(D)
                    if re.findall('android.telephony.SmsManager', CLS):
                        API_SMS.append(D)
                    if re.findall(
                            'java.net.URL|org.apache.http.impl.client.AbstractHttpClient',
                            CLS):
                        API_NET.append(D)
                except:
                    PrintException("[ERROR] Parsing JSON Failed for: " + value)
    except:
        PrintException("[ERROR] Dynamic API Analysis")
        pass
    return list(set(API_NET)), list(set(API_BASE64)), list(
        set(API_FILEIO)), list(set(API_BINDER)), list(set(API_CRYPTO)), list(
            set(API_DEVICEINFO)), list(set(API_CNTVAL)), list(
                set(API_SMS)), list(set(API_SYSPROP)), list(
                    set(API_DEXLOADER)), list(set(API_RELECT)), list(
                        set(API_ACNTMNGER)), list(set(API_CMD))
예제 #16
0
def Report(request):
    print "\n[INFO] Dynamic Analysis Report Generation"
    try:
        if request.method == 'GET':
            MD5 = request.GET['md5']
            PKG = request.GET['pkg']
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            m = re.match('^[0-9a-f]{32}$', MD5)
            if m:
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR,
                                       MD5 + '/')  #APP DIRECTORY
                DWD_DIR = settings.DWD_DIR
                DRDMONAPISLOC = os.path.join(
                    APP_DIR, 'x_logcat.txt')  #Use check_outputs instead later.
                API_NET, API_BASE64, API_FILEIO, API_BINDER, API_CRYPTO, API_DEVICEINFO, API_CNTVL, API_SMS, API_SYSPROP, API_DEXLOADER, API_RELECT, API_ACNTMNGER, API_CMD = APIAnalysis(
                    PKG, DRDMONAPISLOC)
                URL, DOMAINS, EMAIL, HTTP, XML, SQLiteDB, OtherFiles = RunAnalysis(
                    APP_DIR, MD5, PKG)
                Download(MD5, DWD_DIR, APP_DIR, PKG)
                #Only After Download Process is Done
                IMGS = []
                ACTIMGS = []
                ACT = {}
                EXPACTIMGS = []
                EXPACT = {}
                if os.path.exists(
                        os.path.join(DWD_DIR, MD5 + "-screenshots-apk/")):
                    try:
                        for img in os.listdir(
                                os.path.join(DWD_DIR,
                                             MD5 + "-screenshots-apk/")):
                            if img.endswith(".png"):
                                if img.startswith("act"):
                                    ACTIMGS.append(img)
                                elif img.startswith("expact"):
                                    EXPACTIMGS.append(img)
                                else:
                                    IMGS.append(img)
                        DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                        if DB.exists():
                            print "\n[INFO] Fetching Exported Activity & Activity List from DB"
                            EXPORTED_ACT = python_list(DB[0].EXPORTED_ACT)
                            ACTDESC = python_list(DB[0].ACTIVITIES)
                            if len(ACTIMGS) > 0:
                                if len(ACTIMGS) == len(ACTDESC):
                                    ACT = dict(zip(ACTIMGS, ACTDESC))
                            if len(EXPACTIMGS) > 0:
                                if len(EXPACTIMGS) == len(EXPORTED_ACT):
                                    EXPACT = dict(zip(EXPACTIMGS,
                                                      EXPORTED_ACT))
                        else:
                            print "\n[WARNING] Entry does not exists in the DB."
                    except:
                        PrintException("[ERROR] Screenshot Sorting")

                context = {
                    'emails': EMAIL,
                    'urls': URL,
                    'domains': DOMAINS,
                    'md5': MD5,
                    'http': HTTP,
                    'xml': XML,
                    'sqlite': SQLiteDB,
                    'others': OtherFiles,
                    'imgs': IMGS,
                    'acttest': ACT,
                    'expacttest': EXPACT,
                    'net': API_NET,
                    'base64': API_BASE64,
                    'crypto': API_CRYPTO,
                    'fileio': API_FILEIO,
                    'binder': API_BINDER,
                    'divinfo': API_DEVICEINFO,
                    'cntval': API_CNTVL,
                    'sms': API_SMS,
                    'sysprop': API_SYSPROP,
                    'dexload': API_DEXLOADER,
                    'reflect': API_RELECT,
                    'sysman': API_ACNTMNGER,
                    'process': API_CMD,
                    'pkg': PKG,
                    'title': 'Dynamic Analysis'
                }
                template = "dynamic_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Dynamic Analysis Report Generation")
        return HttpResponseRedirect('/error/')
예제 #17
0
def ActivityTester(request):
    print "\n[INFO] Activity Tester"
    try:
        MD5 = request.POST['md5']
        PKG = request.POST['pkg']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            if request.method == 'POST':
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR, MD5 + '/')
                TOOLS_DIR = os.path.join(DIR,
                                         'DynamicAnalyzer/tools/')  #TOOLS DIR
                SCRDIR = os.path.join(APP_DIR, 'screenshots-apk/')
                data = {}
                adb = getADB(TOOLS_DIR)
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching Activity List from DB"
                    ACTIVITIES = python_list(DB[0].ACTIVITIES)
                    if len(ACTIVITIES) > 0:
                        n = 0
                        print "\n[INFO] Starting Activity Tester..."
                        print "\n[INFO] " + str(
                            len(ACTIVITIES)) + " Activities Identified"
                        for line in ACTIVITIES:
                            try:
                                n += 1
                                print "\n[INFO] Launching Activity - " + str(
                                    n) + ". " + line
                                subprocess.call([
                                    adb, "-s",
                                    getIdentifier(), "shell", "am", "start",
                                    "-n", PKG + "/" + line
                                ])
                                Wait(4)
                                subprocess.call([
                                    adb, "-s",
                                    getIdentifier(), "shell", "screencap",
                                    "-p", "/data/local/screen.png"
                                ])
                                #? get appended from Air :-() if activity names are used
                                subprocess.call([
                                    adb, "-s",
                                    getIdentifier(), "pull",
                                    "/data/local/screen.png",
                                    SCRDIR + "act-" + str(n) + ".png"
                                ])
                                print "\n[INFO] Activity Screenshot Taken"
                                subprocess.call([
                                    adb, "-s",
                                    getIdentifier(), "shell", "am",
                                    "force-stop", PKG
                                ])
                                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/')
예제 #18
0
def pdf(request, api=False):
    try:
        if api:
            checksum = request.POST['hash']
            scan_type = request.POST['scan_type']
        else:
            checksum = request.GET['md5']
            scan_type = request.GET['type']
        hash_match = re.match('^[0-9a-f]{32}$', checksum)
        if hash_match:
            if scan_type.lower() in ['apk', 'andzip']:
                static_db = StaticAnalyzerAndroid.objects.filter(MD5=checksum)
                if static_db.exists():
                    print(
                        "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    )
                    context = get_context_from_db_entry(static_db)
                    if scan_type.lower() == 'apk':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    if api:
                        return {"report": "Report not Found"}
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8",
                            status=500)
            elif re.findall('ipa|ioszip', scan_type.lower()):
                if scan_type.lower() == 'ipa':
                    static_db = StaticAnalyzerIPA.objects.filter(MD5=checksum)
                    if static_db.exists():
                        print(
                            "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        )
                        context = get_context_from_db_entry_ipa(static_db)
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        if api:
                            return {"report": "Report not Found"}
                        else:
                            return HttpResponse(
                                json.dumps({"report": "Report not Found"}),
                                content_type="application/json; charset=utf-8",
                                status=500)
                elif scan_type.lower() == 'ioszip':
                    static_db = StaticAnalyzerIOSZIP.objects.filter(
                        MD5=checksum)
                    if static_db.exists():
                        print(
                            "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        )
                        context = get_context_from_db_entry_ios(static_db)
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        if api:
                            return {"report": "Report not Found"}
                        else:
                            return HttpResponse(
                                json.dumps({"report": "Report not Found"}),
                                content_type="application/json; charset=utf-8",
                                status=500)
            elif re.findall('appx', scan_type.lower()):
                if scan_type.lower() == 'appx':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=checksum)
                    if db_entry.exists():
                        print(
                            "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"
                        )

                        context = {
                            'title':
                            db_entry[0].TITLE,
                            'name':
                            db_entry[0].APP_NAME,
                            'pub_name':
                            db_entry[0].PUB_NAME,
                            'size':
                            db_entry[0].SIZE,
                            'md5':
                            db_entry[0].MD5,
                            'sha1':
                            db_entry[0].SHA1,
                            'sha256':
                            db_entry[0].SHA256,
                            'bin_name':
                            db_entry[0].BINNAME,
                            'version':
                            db_entry[0].VERSION,
                            'arch':
                            db_entry[0].ARCH,
                            'compiler_version':
                            db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':
                            db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':
                            db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':
                            db_entry[0].TARGET_OS,
                            'appx_dll_version':
                            db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':
                            db_entry[0].PROJ_GUID,
                            'opti_tool':
                            db_entry[0].OPTI_TOOL,
                            'target_run':
                            db_entry[0].TARGET_RUN,
                            'files':
                            python_list(db_entry[0].FILES),
                            'strings':
                            python_list(db_entry[0].STRINGS),
                            'bin_an_results':
                            python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings':
                            python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                if api:
                    return {"scan_type": "Type is not Allowed"}
                else:
                    return HttpResponse(
                        json.dumps({"type": "Type is not Allowed"}),
                        content_type="application/json; charset=utf-8",
                        status=500)

            context['VT_RESULT'] = None
            if settings.VT_ENABLED:
                app_dir = os.path.join(settings.UPLD_DIR, checksum + '/')
                vt = VirusTotal.VirusTotal()
                if "zip" in scan_type.lower():
                    context['VT_RESULT'] = None
                else:
                    context['VT_RESULT'] = vt.get_result(
                        os.path.join(app_dir, checksum) + '.' +
                        scan_type.lower(), checksum)

            html = template.render(context)
            try:
                options = {
                    'page-size': 'A4',
                    'quiet': '',
                    'no-collate': '',
                    'margin-top': '0.50in',
                    'margin-right': '0.50in',
                    'margin-bottom': '0.50in',
                    'margin-left': '0.50in',
                    'encoding': "UTF-8",
                    'custom-header': [('Accept-Encoding', 'gzip')],
                    'no-outline': None
                }
                pdf_dat = pdfkit.from_string(html, False, options=options)
                if api:
                    return {"pdf_dat": pdf_dat, "report_dat": context}
                else:
                    return HttpResponse(pdf_dat,
                                        content_type='application/pdf')
            except Exception as exp:
                if api:
                    return {
                        "error": "Cannot Generate PDF",
                        "err_details": str(exp)
                    }
                else:
                    return HttpResponse(
                        json.dumps({
                            "pdf_error": "Cannot Generate PDF",
                            "err_details": str(exp)
                        }),
                        content_type="application/json; charset=utf-8",
                        status=500)

        else:
            if api:
                return {"error": "Invalid scan hash"}
            else:
                return HttpResponse(
                    json.dumps({"md5": "Invalid MD5"}),
                    content_type="application/json; charset=utf-8",
                    status=500)
    except Exception as exp:
        msg = str(exp)
        exp = exp.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp)
        else:
            return print_n_send_error_response(request, msg, False, exp)
예제 #19
0
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = {
                        'title': DB[0].TITLE,
                        'name': DB[0].APP_NAME,
                        'size': DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1': DB[0].SHA1,
                        'sha256': DB[0].SHA256,
                        'packagename': DB[0].PACKAGENAME,
                        'mainactivity': DB[0].MAINACTIVITY,
                        'targetsdk': DB[0].TARGET_SDK,
                        'maxsdk': DB[0].MAX_SDK,
                        'minsdk': DB[0].MIN_SDK,
                        'androvername': DB[0].ANDROVERNAME,
                        'androver': DB[0].ANDROVER,
                        'manifest': DB[0].MANIFEST_ANAL,
                        'permissions': DB[0].PERMISSIONS,
                        'files': python_list(DB[0].FILES),
                        'certz': DB[0].CERTZ,
                        'activities': python_list(DB[0].ACTIVITIES),
                        'receivers': python_list(DB[0].RECEIVERS),
                        'providers': python_list(DB[0].PROVIDERS),
                        'services': python_list(DB[0].SERVICES),
                        'libraries': python_list(DB[0].LIBRARIES),
                        'act_count': DB[0].CNT_ACT,
                        'prov_count': DB[0].CNT_PRO,
                        'serv_count': DB[0].CNT_SER,
                        'bro_count': DB[0].CNT_BRO,
                        'certinfo': DB[0].CERT_INFO,
                        'issued': DB[0].ISSUED,
                        'native': DB[0].NATIVE,
                        'dynamic': DB[0].DYNAMIC,
                        'reflection': DB[0].REFLECT,
                        'crypto': DB[0].CRYPTO,
                        'obfus': DB[0].OBFUS,
                        'api': DB[0].API,
                        'dang': DB[0].DANG,
                        'urls': DB[0].URLS,
                        'domains': python_dict(DB[0].DOMAINS),
                        'emails': DB[0].EMAILS,
                        'strings': python_list(DB[0].STRINGS),
                        'zipped': DB[0].ZIPPED,
                        'mani': DB[0].MANI
                    }
                    if TYP == 'APK':
                        template = get_template("static_analysis_pdf.html")
                    else:
                        template = get_template("static_analysis_zip_pdf.html")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'strings': DB[0].STRINGS
                        }
                        template = get_template("ios_binary_analysis_pdf.html")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'api': DB[0].HTML,
                            'insecure': DB[0].CODEANAL,
                            'urls': DB[0].URLnFile,
                            'domains': python_dict(DB[0].DOMAINS),
                            'emails': DB[0].EmailnFile
                        }
                        template = get_template("ios_source_analysis_pdf.html")
            else:
                return HttpResponseRedirect('/error/')
            html = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO("{0}".format(
                html.encode('utf-8'))),
                                    result,
                                    encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(),
                                    content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
예제 #20
0
def report(request):
    """Dynamic Analysis Report Generation."""
    logger.info('Dynamic Analysis Report Generation')
    try:
        if request.method == 'GET':
            md5_hash = request.GET['md5']
            package = request.GET['pkg']
            if re.findall(r';|\$\(|\|\||&&', package):
                return print_n_send_error_response(request,
                                                   'Possible RCE Attack')
            if re.match('^[0-9a-f]{32}$', md5_hash):
                app_dir = os.path.join(settings.UPLD_DIR,
                                       md5_hash + '/')  # APP DIRECTORY
                download_dir = settings.DWD_DIR
                droidmon_api_loc = os.path.join(app_dir, 'x_logcat.txt')
                api_analysis_result = api_analysis(package, droidmon_api_loc)
                analysis_result = run_analysis(app_dir, md5_hash, package)
                download(md5_hash, download_dir, app_dir, package)
                # Only After Download Process is Done
                imgs = []
                act_imgs = []
                act = {}
                expact_imgs = []
                exp_act = {}
                if os.path.exists(
                        os.path.join(download_dir,
                                     md5_hash + '-screenshots-apk/')):
                    try:
                        imp_path = os.path.join(download_dir,
                                                md5_hash + '-screenshots-apk/')
                        for img in os.listdir(imp_path):
                            if img.endswith('.png'):
                                if img.startswith('act'):
                                    act_imgs.append(img)
                                elif img.startswith('expact'):
                                    expact_imgs.append(img)
                                else:
                                    imgs.append(img)
                        sadb = StaticAnalyzerAndroid.objects.filter(
                            MD5=md5_hash)
                        if sadb.exists():
                            logger.info('\nFetching Exported Activity'
                                        ' & Activity List from DB')
                            exported_act = python_list(sadb[0].EXPORTED_ACT)
                            act_desc = python_list(sadb[0].ACTIVITIES)
                            if act_imgs:
                                if len(act_imgs) == len(act_desc):
                                    act = dict(list(zip(act_imgs, act_desc)))
                            if expact_imgs:
                                if len(expact_imgs) == len(exported_act):
                                    exp_act = dict(
                                        list(zip(expact_imgs, exported_act)))
                        else:
                            logger.warning('Entry does not exists in the DB.')
                    except Exception:
                        logger.exception('Screenshot Sorting')
                context = {
                    'md5': md5_hash,
                    'emails': analysis_result['emails'],
                    'urls': analysis_result['urls'],
                    'domains': analysis_result['domains'],
                    'clipboard': analysis_result['clipboard'],
                    'http': analysis_result['web_data'],
                    'xml': analysis_result['xmlfiles'],
                    'sqlite': analysis_result['sqlite_db'],
                    'others': analysis_result['other_files'],
                    'imgs': imgs,
                    'acttest': act,
                    'expacttest': exp_act,
                    'net': api_analysis_result['api_net'],
                    'base64': api_analysis_result['api_base64'],
                    'crypto': api_analysis_result['api_crypto'],
                    'fileio': api_analysis_result['api_fileio'],
                    'binder': api_analysis_result['api_binder'],
                    'divinfo': api_analysis_result['api_deviceinfo'],
                    'cntval': api_analysis_result['api_cntvl'],
                    'sms': api_analysis_result['api_sms'],
                    'sysprop': api_analysis_result['api_sysprop'],
                    'dexload': api_analysis_result['api_dexloader'],
                    'reflect': api_analysis_result['api_reflect'],
                    'sysman': api_analysis_result['api_acntmnger'],
                    'process': api_analysis_result['api_cmd'],
                    'pkg': package,
                    'title': 'Dynamic Analysis'
                }
                template = 'dynamic_analysis/dynamic_analysis.html'
                return render(request, template, context)
            else:
                return print_n_send_error_response(request,
                                                   'Invalid Scan Hash')
        else:
            return print_n_send_error_response(request, 'Only GET allowed')
    except Exception:
        logger.exception('Dynamic Analysis Report Generation')
        err = 'Error Geneating Dynamic Analysis Report'
        return print_n_send_error_response(request, err)
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)
예제 #22
0
def get_context_from_db_entry(db_entry: QuerySet) -> dict:
    """Return the context for APK/ZIP from DB"""
    try:
        logger.info("Analysis is already Done. Fetching data from the DB...")

        context = {
            'title': db_entry[0].TITLE,
            'name': db_entry[0].APP_NAME,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'packagename': db_entry[0].PACKAGENAME,
            'mainactivity': db_entry[0].MAINACTIVITY,
            'targetsdk': db_entry[0].TARGET_SDK,
            'maxsdk': db_entry[0].MAX_SDK,
            'minsdk': db_entry[0].MIN_SDK,
            'androvername': db_entry[0].ANDROVERNAME,
            'androver': db_entry[0].ANDROVER,
            'manifest': python_list(db_entry[0].MANIFEST_ANAL),
            'permissions': python_dict(db_entry[0].PERMISSIONS),
            'binary_analysis': python_list(db_entry[0].BIN_ANALYSIS),
            'files': python_list(db_entry[0].FILES),
            'certz': db_entry[0].CERTZ,
            'icon_hidden': db_entry[0].ICON_HIDDEN,
            'icon_found': db_entry[0].ICON_FOUND,
            'activities': python_list(db_entry[0].ACTIVITIES),
            'receivers': python_list(db_entry[0].RECEIVERS),
            'providers': python_list(db_entry[0].PROVIDERS),
            'services': python_list(db_entry[0].SERVICES),
            'libraries': python_list(db_entry[0].LIBRARIES),
            'browsable_activities': python_dict(db_entry[0].BROWSABLE),
            'act_count': db_entry[0].CNT_ACT,
            'prov_count': db_entry[0].CNT_PRO,
            'serv_count': db_entry[0].CNT_SER,
            'bro_count': db_entry[0].CNT_BRO,
            'certinfo': db_entry[0].CERT_INFO,
            'issued': db_entry[0].ISSUED,
            'sha256Digest': db_entry[0].SHA256DIGEST,
            'api': python_dict(db_entry[0].API),
            'findings': python_dict(db_entry[0].DANG),
            'urls': python_list(db_entry[0].URLS),
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': python_list(db_entry[0].EMAILS),
            'strings': python_list(db_entry[0].STRINGS),
            'zipped': db_entry[0].ZIPPED,
            'mani': db_entry[0].MANI,
            'e_act': db_entry[0].E_ACT,
            'e_ser': db_entry[0].E_SER,
            'e_bro': db_entry[0].E_BRO,
            'e_cnt': db_entry[0].E_CNT,
            'apkid': python_dict(db_entry[0].APK_ID),
            'play_details': python_dict(db_entry[0].PLAY_DETAILS),
            'firebase': python_list(db_entry[0].FIREBASE),
        }
        return context
    except:
        PrintException("Fetching from DB")
예제 #23
0
def staticanalyzer_windows(request):
    """Analyse a windows app."""
    try:
        # Input validation
        print "[INFO] Windows Static Analysis Started"
        app_dic = {}  # Dict to store the binary attributes
        typ = request.GET['type']
        rescan = str(request.GET.get('rescan', 0))
        md5_regex = re.match('^[0-9a-f]{32}$', request.GET['checksum'])
        if (md5_regex) and (typ in ['appx']):
            app_dic['app_name'] = request.GET['name']  # APP ORGINAL NAME
            app_dic['md5'] = request.GET['checksum']
            app_dic['app_dir'] = os.path.join(
                settings.UPLD_DIR, app_dic['md5'] + '/')
            app_dic['tools_dir'] = os.path.join(
                settings.BASE_DIR, 'StaticAnalyzer/tools/windows/')
            if typ == 'appx':
                # DB
                db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                    MD5=app_dic['md5']
                )
                if db_entry.exists() and rescan == '0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                        'title': db_entry[0].TITLE,
                        'name': db_entry[0].APP_NAME,
                        'pub_name': db_entry[0].PUB_NAME,
                        'size': db_entry[0].SIZE,
                        'md5': db_entry[0].MD5,
                        'sha1': db_entry[0].SHA1,
                        'sha256': db_entry[0].SHA256,
                        'bin_name': db_entry[0].BINNAME,
                        'version':  db_entry[0].VERSION,
                        'arch':  db_entry[0].ARCH,
                        'compiler_version':  db_entry[0].COMPILER_VERSION,
                        'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                        'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                        'target_os':  db_entry[0].TARGET_OS,
                        'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                        'proj_guid':  db_entry[0].PROJ_GUID,
                        'opti_tool':  db_entry[0].OPTI_TOOL,
                        'target_run':  db_entry[0].TARGET_RUN,
                        'files': python_list(db_entry[0].FILES),
                        'strings': python_list(db_entry[0].STRINGS),
                        'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                        'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                    }
                else:
                    print "[INFO] Windows Binary Analysis Started"
                    app_dic['app_path'] = os.path.join(
                        app_dic['app_dir'], app_dic['md5'] + '.appx')
                    # ANALYSIS BEGINS
                    app_dic['size'] = str(FileSize(app_dic['app_path'])) + 'MB'
                    # Generate hashes
                    app_dic['sha1'], app_dic[
                        'sha256'] = HashGen(app_dic['app_path'])
                    # EXTRACT APPX
                    print "[INFO] Extracting APPX"
                    app_dic['files'] = Unzip(
                        app_dic['app_path'], app_dic['app_dir'])
                    xml_dic = _parse_xml(app_dic['app_dir'])
                    bin_an_dic = _binary_analysis(app_dic)
                    # Saving to db
                    print "\n[INFO] Connecting to DB"
                    if rescan == '1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                            MD5=app_dic['md5']
                        ).update(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                    elif rescan == '0':
                        print "\n[INFO] Saving to Database"
                        db_item = StaticAnalyzerWindows(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                        db_item.save()
                    context = {
                        'title': 'Static Analysis',
                        'name': app_dic['app_name'],
                        'pub_name': xml_dic['pub_name'],
                        'size': app_dic['size'],
                        'md5': app_dic['md5'],
                        'sha1': app_dic['sha1'],
                        'sha256': app_dic['sha256'],
                        'bin_name': bin_an_dic['bin_name'],
                        'version': xml_dic['version'],
                        'arch': xml_dic['arch'],
                        'compiler_version': xml_dic['compiler_version'],
                        'visual_studio_version': xml_dic['visual_studio_version'],
                        'visual_studio_edition': xml_dic['visual_studio_edition'],
                        'target_os': xml_dic['target_os'],
                        'appx_dll_version': xml_dic['appx_dll_version'],
                        'proj_guid': xml_dic['proj_guid'],
                        'opti_tool': xml_dic['opti_tool'],
                        'target_run': xml_dic['target_run'],
                        'files': app_dic['files'],
                        'strings': bin_an_dic['strings'],
                        'bin_an_results': bin_an_dic['results'],
                        'bin_an_warnings': bin_an_dic['warnings'],
                    }
                template = "static_analysis/windows_binary_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except Exception as exception:
        PrintException("[ERROR] Static Analyzer Windows")
        context = {
            'title': 'Error',
            'exp': exception.message,
            'doc': exception.__doc__
        }
        template = "general/error.html"
        return render(request, template, context)
def api_analysis(package, location):
    """API Analysis"""
    api_analysis_result = {}
    logger.info("Dynamic API Analysis")
    dat = ""
    api_base64 = []
    api_fileio = []
    api_reflect = []
    api_sysprop = []
    api_cntvl = []
    api_binder = []
    api_crypto = []
    api_acntmnger = []
    api_deviceinfo = []
    api_net = []
    api_dexloader = []
    api_cmd = []
    api_sms = []
    try:
        with open(location, "r", encoding="utf-8") as flip:
            dat = flip.readlines()
        res_id = "Droidmon-apimonitor-" + package + ":"
        for line in dat:
            if res_id in line:
                # print "LINE: " + line
                _, value = line.split(res_id, 1)
                # print "PARAM is :" + param
                # print "Value is :"+ value
                try:
                    apis = json.loads(value, strict=False)
                    ret = ''
                    args = ''
                    mtd = str(apis["method"])
                    clss = str(apis["class"])
                    # print "Called Class: " + CLS
                    # print "Called Method: " + MTD
                    if apis.get('return'):
                        ret = str(apis["return"])
                        # print "Return Data: " + RET
                    else:
                        # print "No Return Data"
                        ret = "No Return Data"
                    if apis.get('args'):
                        args = str(apis["args"])
                        # print "Passed Arguments" + ARGS
                    else:
                        # print "No Arguments Passed"
                        args = "No Arguments Passed"
                    # XSS Safe
                    call_data = "</br>METHOD: " + \
                        escape(mtd) + "</br>ARGUMENTS: " + escape(args) + \
                        "</br>RETURN DATA: " + escape(ret)

                    if re.findall("android.util.Base64", clss):
                        # Base64 Decode
                        if "decode" in mtd:
                            args_list = python_list(args)
                            if isBase64(args_list[0]):
                                call_data += '</br><span class="label label-info">' +\
                                    'Decoded String:</span> ' + \
                                    escape(base64.b64decode(args_list[0]))
                        api_base64.append(call_data)
                    if re.findall('libcore.io|android.app.SharedPreferencesImpl\$EditorImpl', clss):
                        api_fileio.append(call_data)
                    if re.findall('java.lang.reflect', clss):
                        api_reflect.append(call_data)
                    if re.findall('android.content.ContentResolver|android.location.Location|android.media.AudioRecord|android.media.MediaRecorder|android.os.SystemProperties', clss):
                        api_sysprop.append(call_data)
                    if re.findall('android.app.Activity|android.app.ContextImpl|android.app.ActivityThread', clss):
                        api_binder.append(call_data)
                    if re.findall('javax.crypto.spec.SecretKeySpec|javax.crypto.Cipher|javax.crypto.Mac', clss):
                        api_crypto.append(call_data)
                    if re.findall('android.accounts.AccountManager|android.app.ApplicationPackageManager|android.app.NotificationManager|android.net.ConnectivityManager|android.content.BroadcastReceiver', clss):
                        api_acntmnger.append(call_data)
                    if re.findall('android.telephony.TelephonyManager|android.net.wifi.WifiInfo|android.os.Debug', clss):
                        api_deviceinfo.append(call_data)
                    if re.findall('dalvik.system.BaseDexClassLoader|dalvik.system.DexFile|dalvik.system.DexClassLoader|dalvik.system.PathClassLoader', clss):
                        api_dexloader.append(call_data)
                    if re.findall('java.lang.Runtime|java.lang.ProcessBuilder|java.io.FileOutputStream|java.io.FileInputStream|android.os.Process', clss):
                        api_cmd.append(call_data)
                    if re.findall('android.content.ContentValues', clss):
                        api_cntvl.append(call_data)
                    if re.findall('android.telephony.SmsManager', clss):
                        api_sms.append(call_data)
                    if re.findall('java.net.URL|org.apache.http.impl.client.AbstractHttpClient', clss):
                        api_net.append(call_data)
                except:
                    PrintException("Parsing JSON Failed for: " + value)
    except:
        PrintException("Dynamic API Analysis")
    api_analysis_result["api_net"] = list(set(api_net))
    api_analysis_result["api_base64"] = list(set(api_base64))
    api_analysis_result["api_fileio"] = list(set(api_fileio))
    api_analysis_result["api_binder"] = list(set(api_binder))
    api_analysis_result["api_crypto"] = list(set(api_crypto))
    api_analysis_result["api_deviceinfo"] = list(set(api_deviceinfo))
    api_analysis_result["api_cntvl"] = list(set(api_cntvl))
    api_analysis_result["api_sms"] = list(set(api_sms))
    api_analysis_result["api_sysprop"] = list(set(api_sysprop))
    api_analysis_result["api_dexloader"] = list(set(api_dexloader))
    api_analysis_result["api_reflect"] = list(set(api_reflect))
    api_analysis_result["api_acntmnger"] = list(set(api_acntmnger))
    api_analysis_result["api_cmd"] = list(set(api_cmd))
    return api_analysis_result
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = get_context_from_db_entry(DB)
                    if TYP == 'APK':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(json.dumps({"report": "Report not Found"}),
                                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = get_context_from_db_entry_ipa(DB)
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = get_context_from_db_entry_ios(DB)
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX', TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=MD5
                    )
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"

                        context = {
                            'title': db_entry[0].TITLE,
                            'name': db_entry[0].APP_NAME,
                            'pub_name': db_entry[0].PUB_NAME,
                            'size': db_entry[0].SIZE,
                            'md5': db_entry[0].MD5,
                            'sha1': db_entry[0].SHA1,
                            'sha256': db_entry[0].SHA256,
                            'bin_name': db_entry[0].BINNAME,
                            'version':  db_entry[0].VERSION,
                            'arch':  db_entry[0].ARCH,
                            'compiler_version':  db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':  db_entry[0].TARGET_OS,
                            'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':  db_entry[0].PROJ_GUID,
                            'opti_tool':  db_entry[0].OPTI_TOOL,
                            'target_run':  db_entry[0].TARGET_RUN,
                            'files':  python_list(db_entry[0].FILES),
                            'strings': python_list(db_entry[0].STRINGS),
                            'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(json.dumps({"type": "Type is not Allowed"}),
                                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            try:
                options = {
                    'page-size': 'A4',
                    'quiet': '',
                    'no-collate': '',
                    'margin-top': '0.50in',
                    'margin-right': '0.50in',
                    'margin-bottom': '0.50in',
                    'margin-left': '0.50in',
                    'encoding': "UTF-8",
                    'custom-header': [
                        ('Accept-Encoding', 'gzip')
                    ],
                    'no-outline': None
                }
                pdf = pdfkit.from_string(html, False, options=options)
                return HttpResponse(pdf, content_type='application/pdf')
            except Exception as exp:
                return HttpResponse(json.dumps({"pdf_error": "Cannot Generate PDF",
                                                "err_details": str(exp)}),
                                    content_type="application/json; charset=utf-8")

        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def report(request):
    """Dynamic Analysis Report Generation"""
    print("\n[INFO] Dynamic Analysis Report Generation")
    try:
        if request.method == 'GET':
            md5_hash = request.GET['md5']
            package = request.GET['pkg']
            if re.findall(r";|\$\(|\|\||&&", package):
                print("[ATTACK] Possible RCE")
                return HttpResponseRedirect('/error/')
            if re.match('^[0-9a-f]{32}$', md5_hash):
                app_dir = os.path.join(
                    settings.UPLD_DIR, md5_hash + '/')  # APP DIRECTORY
                download_dir = settings.DWD_DIR
                droidmon_api_loc = os.path.join(app_dir, 'x_logcat.txt')
                api_analysis_result = api_analysis(package, droidmon_api_loc)
                analysis_result = run_analysis(app_dir, md5_hash, package)
                download(md5_hash, download_dir, app_dir, package)
                # Only After Download Process is Done
                imgs = []
                act_imgs = []
                act = {}
                expact_imgs = []
                exp_act = {}
                if os.path.exists(os.path.join(download_dir, md5_hash + "-screenshots-apk/")):
                    try:
                        imp_path = os.path.join(
                            download_dir, md5_hash + "-screenshots-apk/")
                        for img in os.listdir(imp_path):
                            if img.endswith(".png"):
                                if img.startswith("act"):
                                    act_imgs.append(img)
                                elif img.startswith("expact"):
                                    expact_imgs.append(img)
                                else:
                                    imgs.append(img)
                        static_android_db = StaticAnalyzerAndroid.objects.filter(
                            MD5=md5_hash)
                        if static_android_db.exists():
                            print(
                                "\n[INFO] Fetching Exported Activity & Activity List from DB")
                            exported_act = python_list(
                                static_android_db[0].EXPORTED_ACT)
                            act_desc = python_list(
                                static_android_db[0].ACTIVITIES)
                            if act_imgs:
                                if len(act_imgs) == len(act_desc):
                                    act = dict(list(zip(act_imgs, act_desc)))
                            if expact_imgs:
                                if len(expact_imgs) == len(exported_act):
                                    exp_act = dict(
                                        list(zip(expact_imgs, exported_act)))
                        else:
                            print(
                                "\n[WARNING] Entry does not exists in the DB.")
                    except:
                        PrintException("[ERROR] Screenshot Sorting")
                context = {'md5': md5_hash,
                           'emails': analysis_result["emails"],
                           'urls': analysis_result["urls"],
                           'domains': analysis_result["domains"],
                           'clipboard': analysis_result["clipboard"],
                           'http': analysis_result["web_data"],
                           'xml': analysis_result["xmlfiles"],
                           'sqlite': analysis_result["sqlite_db"],
                           'others': analysis_result["other_files"],
                           'imgs': imgs,
                           'acttest': act,
                           'expacttest': exp_act,
                           'net': api_analysis_result["api_net"],
                           'base64': api_analysis_result["api_base64"],
                           'crypto': api_analysis_result["api_crypto"],
                           'fileio': api_analysis_result["api_fileio"],
                           'binder': api_analysis_result["api_binder"],
                           'divinfo': api_analysis_result["api_deviceinfo"],
                           'cntval': api_analysis_result["api_cntvl"],
                           'sms': api_analysis_result["api_sms"],
                           'sysprop': api_analysis_result["api_sysprop"],
                           'dexload': api_analysis_result["api_dexloader"],
                           'reflect': api_analysis_result["api_reflect"],
                           'sysman': api_analysis_result["api_acntmnger"],
                           'process': api_analysis_result["api_cmd"],
                           'pkg': package,
                           'title': 'Dynamic Analysis'}
                template = "dynamic_analysis/dynamic_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Dynamic Analysis Report Generation")
        return HttpResponseRedirect('/error/')
예제 #27
0
def get_context_from_db_entry(db_entry: QuerySet) -> dict:
    """Return the context for APK/ZIP from DB."""
    try:
        logger.info('Analysis is already Done. Fetching data from the DB...')
        context = {
            'version': settings.MOBSF_VER,
            'title': 'Static Analysis',
            'file_name': db_entry[0].FILE_NAME,
            'app_name': db_entry[0].APP_NAME,
            'app_type': db_entry[0].APP_TYPE,
            'size': db_entry[0].SIZE,
            'md5': db_entry[0].MD5,
            'sha1': db_entry[0].SHA1,
            'sha256': db_entry[0].SHA256,
            'package_name': db_entry[0].PACKAGE_NAME,
            'main_activity': db_entry[0].MAIN_ACTIVITY,
            'exported_activities': db_entry[0].EXPORTED_ACTIVITIES,
            'browsable_activities': python_dict(
                db_entry[0].BROWSABLE_ACTIVITIES),
            'activities': python_list(db_entry[0].ACTIVITIES),
            'receivers': python_list(db_entry[0].RECEIVERS),
            'providers': python_list(db_entry[0].PROVIDERS),
            'services': python_list(db_entry[0].SERVICES),
            'libraries': python_list(db_entry[0].LIBRARIES),
            'target_sdk': db_entry[0].TARGET_SDK,
            'max_sdk': db_entry[0].MAX_SDK,
            'min_sdk': db_entry[0].MIN_SDK,
            'version_name': db_entry[0].VERSION_NAME,
            'version_code': db_entry[0].VERSION_CODE,
            'icon_hidden': db_entry[0].ICON_HIDDEN,
            'icon_found': db_entry[0].ICON_FOUND,
            'permissions': python_dict(db_entry[0].PERMISSIONS),
            'certificate_analysis': python_dict(
                db_entry[0].CERTIFICATE_ANALYSIS),
            'manifest_analysis': python_list(db_entry[0].MANIFEST_ANALYSIS),
            'network_security': python_list(db_entry[0].NETWORK_SECURITY),
            'binary_analysis': python_list(db_entry[0].BINARY_ANALYSIS),
            'file_analysis': python_list(db_entry[0].FILE_ANALYSIS),
            'android_api': python_dict(db_entry[0].ANDROID_API),
            'code_analysis': python_dict(db_entry[0].CODE_ANALYSIS),
            'urls': python_list(db_entry[0].URLS),
            'domains': python_dict(db_entry[0].DOMAINS),
            'emails': python_list(db_entry[0].EMAILS),
            'strings': python_list(db_entry[0].STRINGS),
            'firebase_urls': python_list(db_entry[0].FIREBASE_URLS),
            'files': python_list(db_entry[0].FILES),
            'exported_count': python_dict(db_entry[0].EXPORTED_COUNT),
            'apkid': python_dict(db_entry[0].APKID),
            'trackers': python_dict(db_entry[0].TRACKERS),
            'playstore_details': python_dict(db_entry[0].PLAYSTORE_DETAILS),
        }
        return context
    except Exception:
        logger.exception('Fetching from DB')
def PDF(request):
    try:
        MD5=request.GET['md5']
        TYP=request.GET['type']
        m=re.match('^[0-9a-f]{32}$',MD5)
        if m:
            if TYP in ['APK','ANDZIP']:
                DB=StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = {
                    'title' : DB[0].TITLE,
                    'name' : DB[0].APP_NAME,
                    'size' : DB[0].SIZE,
                    'md5': DB[0].MD5,
                    'sha1' : DB[0].SHA1,
                    'sha256' : DB[0].SHA256,
                    'packagename' : DB[0].PACKAGENAME,
                    'mainactivity' : DB[0].MAINACTIVITY,
                    'targetsdk' : DB[0].TARGET_SDK,
                    'maxsdk' : DB[0].MAX_SDK,
                    'minsdk' : DB[0].MIN_SDK,
                    'androvername' : DB[0].ANDROVERNAME,
                    'androver': DB[0].ANDROVER,
                    'manifest': DB[0].MANIFEST_ANAL,
                    'permissions' : DB[0].PERMISSIONS,
                    'files' : python_list(DB[0].FILES),
                    'certz' : DB[0].CERTZ,
                    'activities' : python_list(DB[0].ACTIVITIES),
                    'receivers' : python_list(DB[0].RECEIVERS),
                    'providers' : python_list(DB[0].PROVIDERS),
                    'services' : python_list(DB[0].SERVICES),
                    'libraries' : python_list(DB[0].LIBRARIES),
                    'act_count' : DB[0].CNT_ACT,
                    'prov_count' : DB[0].CNT_PRO,
                    'serv_count' : DB[0].CNT_SER,
                    'bro_count' : DB[0].CNT_BRO,
                    'certinfo': DB[0].CERT_INFO,
                    'issued':DB[0].ISSUED,
                    'native' : DB[0].NATIVE,
                    'dynamic' : DB[0].DYNAMIC,
                    'reflection' : DB[0].REFLECT,
                    'crypto': DB[0].CRYPTO,
                    'obfus': DB[0].OBFUS,
                    'api': DB[0].API,
                    'dang': DB[0].DANG,
                    'urls': DB[0].URLS,
                    'domains': python_dict(DB[0].DOMAINS),
                    'emails': DB[0].EMAILS,
                    'strings': python_list(DB[0].STRINGS),
                    'zipped' : DB[0].ZIPPED,
                    'mani': DB[0].MANI
                    }
                    if TYP=='APK':
                        template= get_template("static_analysis_pdf.html")
                    else:
                        template= get_template("static_analysis_zip_pdf.html")
            elif re.findall('IPA|IOSZIP',TYP):
                if TYP=='IPA':
                    DB=StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                        'title' : DB[0].TITLE,
                        'name' : DB[0].APPNAMEX,
                        'size' : DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1' : DB[0].SHA1,
                        'sha256' : DB[0].SHA256,
                        'plist' : DB[0].INFOPLIST,
                        'bin_name' : DB[0].BINNAME,
                        'id' : DB[0].IDF,
                        'ver' : DB[0].VERSION,
                        'sdk' : DB[0].SDK,
                        'pltfm' : DB[0].PLTFM,
                        'min' : DB[0].MINX,
                        'bin_anal' : DB[0].BIN_ANAL,
                        'libs' : DB[0].LIBS,
                        'files' : python_list(DB[0].FILES),
                        'file_analysis' : DB[0].SFILESX,
                        'strings' : DB[0].STRINGS
                        }
                        template= get_template("ios_binary_analysis_pdf.html")
                elif TYP=='IOSZIP':
                    DB=StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                        'title' : DB[0].TITLE,
                        'name' : DB[0].APPNAMEX,
                        'size' : DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1' : DB[0].SHA1,
                        'sha256' : DB[0].SHA256,
                        'plist' : DB[0].INFOPLIST,
                        'bin_name' : DB[0].BINNAME,
                        'id' : DB[0].IDF,
                        'ver' : DB[0].VERSION,
                        'sdk' : DB[0].SDK,
                        'pltfm' : DB[0].PLTFM,
                        'min' : DB[0].MINX,
                        'bin_anal' : DB[0].BIN_ANAL,
                        'libs' : DB[0].LIBS,
                        'files' : python_list(DB[0].FILES),
                        'file_analysis' : DB[0].SFILESX,
                        'api' : DB[0].HTML,
                        'insecure' : DB[0].CODEANAL,
                        'urls' : DB[0].URLnFile,
                        'domains': python_dict(DB[0].DOMAINS),
                        'emails' : DB[0].EmailnFile
                        }
                        template= get_template("ios_source_analysis_pdf.html")
            else:
                return HttpResponseRedirect('/error/')
            html  = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO( "{0}".format(html.encode('utf-8'))), result, encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(), content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def Report(request):
    print "\n[INFO] Dynamic Analysis Report Generation"
    try:
        if request.method == "GET":
            MD5 = request.GET["md5"]
            PKG = request.GET["pkg"]
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect("/error/")
            m = re.match("^[0-9a-f]{32}$", MD5)
            if m:
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR, MD5 + "/")  # APP DIRECTORY
                DWD_DIR = settings.DWD_DIR
                DRDMONAPISLOC = os.path.join(APP_DIR, "x_logcat.txt")  # Use check_outputs instead later.
                API_NET, API_BASE64, API_FILEIO, API_BINDER, API_CRYPTO, API_DEVICEINFO, API_CNTVL, API_SMS, API_SYSPROP, API_DEXLOADER, API_RELECT, API_ACNTMNGER, API_CMD = APIAnalysis(
                    PKG, DRDMONAPISLOC
                )
                URL, DOMAINS, EMAIL, HTTP, XML, SQLiteDB, OtherFiles = RunAnalysis(APP_DIR, MD5, PKG)
                Download(MD5, DWD_DIR, APP_DIR, PKG)
                # Only After Download Process is Done
                IMGS = []
                ACTIMGS = []
                ACT = {}
                EXPACTIMGS = []
                EXPACT = {}
                if os.path.exists(os.path.join(DWD_DIR, MD5 + "-screenshots-apk/")):
                    try:
                        for img in os.listdir(os.path.join(DWD_DIR, MD5 + "-screenshots-apk/")):
                            if img.endswith(".png"):
                                if img.startswith("act"):
                                    ACTIMGS.append(img)
                                elif img.startswith("expact"):
                                    EXPACTIMGS.append(img)
                                else:
                                    IMGS.append(img)
                        DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                        if DB.exists():
                            print "\n[INFO] Fetching Exported Activity & Activity List from DB"
                            EXPORTED_ACT = python_list(DB[0].EXPORTED_ACT)
                            ACTDESC = python_list(DB[0].ACTIVITIES)
                            if ACTIMGS:
                                if len(ACTIMGS) == len(ACTDESC):
                                    ACT = dict(zip(ACTIMGS, ACTDESC))
                            if EXPACTIMGS:
                                if len(EXPACTIMGS) == len(EXPORTED_ACT):
                                    EXPACT = dict(zip(EXPACTIMGS, EXPORTED_ACT))
                        else:
                            print "\n[WARNING] Entry does not exists in the DB."
                    except:
                        PrintException("[ERROR] Screenshot Sorting")

                context = {
                    "emails": EMAIL,
                    "urls": URL,
                    "domains": DOMAINS,
                    "md5": MD5,
                    "http": HTTP,
                    "xml": XML,
                    "sqlite": SQLiteDB,
                    "others": OtherFiles,
                    "imgs": IMGS,
                    "acttest": ACT,
                    "expacttest": EXPACT,
                    "net": API_NET,
                    "base64": API_BASE64,
                    "crypto": API_CRYPTO,
                    "fileio": API_FILEIO,
                    "binder": API_BINDER,
                    "divinfo": API_DEVICEINFO,
                    "cntval": API_CNTVL,
                    "sms": API_SMS,
                    "sysprop": API_SYSPROP,
                    "dexload": API_DEXLOADER,
                    "reflect": API_RELECT,
                    "sysman": API_ACNTMNGER,
                    "process": API_CMD,
                    "pkg": PKG,
                    "title": "Dynamic Analysis",
                }
                template = "dynamic_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect("/error/")
        else:
            return HttpResponseRedirect("/error/")
    except:
        PrintException("[ERROR] Dynamic Analysis Report Generation")
        return HttpResponseRedirect("/error/")
예제 #30
0
파일: analysis.py 프로젝트: ays14/mobsf
def api_analysis(package, location):
    """API Analysis"""
    api_analysis_result = {}
    print("\n[INFO] Dynamic API Analysis")
    dat = ""
    api_base64 = []
    api_fileio = []
    api_reflect = []
    api_sysprop = []
    api_cntvl = []
    api_binder = []
    api_crypto = []
    api_acntmnger = []
    api_deviceinfo = []
    api_net = []
    api_dexloader = []
    api_cmd = []
    api_sms = []
    try:
        with open(location, "r") as flip:
            dat = flip.readlines()
        res_id = "Droidmon-apimonitor-" + package + ":"
        for line in dat:
            if res_id in line:
                # print "LINE: " + line
                _, value = line.split(res_id, 1)
                # print "PARAM is :" + param
                # print "Value is :"+ value
                try:
                    apis = json.loads(value, strict=False)
                    ret = ''
                    args = ''
                    mtd = str(apis["method"])
                    clss = str(apis["class"])
                    # print "Called Class: " + CLS
                    # print "Called Method: " + MTD
                    if apis.get('return'):
                        ret = str(apis["return"])
                        # print "Return Data: " + RET
                    else:
                        # print "No Return Data"
                        ret = "No Return Data"
                    if apis.get('args'):
                        args = str(apis["args"])
                        # print "Passed Arguments" + ARGS
                    else:
                        # print "No Arguments Passed"
                        args = "No Arguments Passed"
                    # XSS Safe
                    call_data = "</br>METHOD: " + \
                        escape(mtd) + "</br>ARGUMENTS: " + escape(args) + \
                        "</br>RETURN DATA: " + escape(ret)

                    if re.findall("android.util.Base64", clss):
                        # Base64 Decode
                        if "decode" in mtd:
                            args_list = python_list(args)
                            if isBase64(args_list[0]):
                                call_data += '</br><span class="label label-info">' +\
                                    'Decoded String:</span> ' + \
                                    escape(base64.b64decode(args_list[0]))
                        api_base64.append(call_data)
                    if re.findall('libcore.io|android.app.SharedPreferencesImpl\$EditorImpl', clss):
                        api_fileio.append(call_data)
                    if re.findall('java.lang.reflect', clss):
                        api_reflect.append(call_data)
                    if re.findall('android.content.ContentResolver|android.location.Location|android.media.AudioRecord|android.media.MediaRecorder|android.os.SystemProperties', clss):
                        api_sysprop.append(call_data)
                    if re.findall('android.app.Activity|android.app.ContextImpl|android.app.ActivityThread', clss):
                        api_binder.append(call_data)
                    if re.findall('javax.crypto.spec.SecretKeySpec|javax.crypto.Cipher|javax.crypto.Mac', clss):
                        api_crypto.append(call_data)
                    if re.findall('android.accounts.AccountManager|android.app.ApplicationPackageManager|android.app.NotificationManager|android.net.ConnectivityManager|android.content.BroadcastReceiver', clss):
                        api_acntmnger.append(call_data)
                    if re.findall('android.telephony.TelephonyManager|android.net.wifi.WifiInfo|android.os.Debug', clss):
                        api_deviceinfo.append(call_data)
                    if re.findall('dalvik.system.BaseDexClassLoader|dalvik.system.DexFile|dalvik.system.DexClassLoader|dalvik.system.PathClassLoader', clss):
                        api_dexloader.append(call_data)
                    if re.findall('java.lang.Runtime|java.lang.ProcessBuilder|java.io.FileOutputStream|java.io.FileInputStream|android.os.Process', clss):
                        api_cmd.append(call_data)
                    if re.findall('android.content.ContentValues', clss):
                        api_cntvl.append(call_data)
                    if re.findall('android.telephony.SmsManager', clss):
                        api_sms.append(call_data)
                    if re.findall('java.net.URL|org.apache.http.impl.client.AbstractHttpClient', clss):
                        api_net.append(call_data)
                except:
                    PrintException("[ERROR] Parsing JSON Failed for: " + value)
    except:
        PrintException("[ERROR] Dynamic API Analysis")
    api_analysis_result["api_net"] = list(set(api_net))
    api_analysis_result["api_base64"] = list(set(api_base64))
    api_analysis_result["api_fileio"] = list(set(api_fileio))
    api_analysis_result["api_binder"] = list(set(api_binder))
    api_analysis_result["api_crypto"] = list(set(api_crypto))
    api_analysis_result["api_deviceinfo"] = list(set(api_deviceinfo))
    api_analysis_result["api_cntvl"] = list(set(api_cntvl))
    api_analysis_result["api_sms"] = list(set(api_sms))
    api_analysis_result["api_sysprop"] = list(set(api_sysprop))
    api_analysis_result["api_dexloader"] = list(set(api_dexloader))
    api_analysis_result["api_reflect"] = list(set(api_reflect))
    api_analysis_result["api_acntmnger"] = list(set(api_acntmnger))
    api_analysis_result["api_cmd"] = list(set(api_cmd))
    return api_analysis_result
def staticanalyzer_windows(request, api=False):
    """Analyse a windows app."""
    try:
        # Input validation
        print "[INFO] Windows Static Analysis Started"
        app_dic = {}  # Dict to store the binary attributes
        if api:
            typ = request.POST['scan_type']
            rescan = str(request.POST.get('re_scan', 0))
            checksum = request.POST['hash']
            filename = request.POST['file_name']
        else:
            typ = request.GET['type']
            rescan = str(request.GET.get('rescan', 0))
            checksum = request.GET['checksum']
            filename = request.GET['name']
        md5_regex = re.match('^[0-9a-f]{32}$', checksum)
        if (md5_regex) and (typ in ['appx']):
            app_dic['app_name'] = filename  # APP ORGINAL NAME
            app_dic['md5'] = checksum
            app_dic['app_dir'] = os.path.join(
                settings.UPLD_DIR, app_dic['md5'] + '/')
            app_dic['tools_dir'] = os.path.join(
                settings.BASE_DIR, 'StaticAnalyzer/tools/windows/')
            if typ == 'appx':
                # DB
                db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                    MD5=app_dic['md5']
                )
                if db_entry.exists() and rescan == '0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                        'title': db_entry[0].TITLE,
                        'name': db_entry[0].APP_NAME,
                        'pub_name': db_entry[0].PUB_NAME,
                        'size': db_entry[0].SIZE,
                        'md5': db_entry[0].MD5,
                        'sha1': db_entry[0].SHA1,
                        'sha256': db_entry[0].SHA256,
                        'bin_name': db_entry[0].BINNAME,
                        'version':  db_entry[0].VERSION,
                        'arch':  db_entry[0].ARCH,
                        'compiler_version':  db_entry[0].COMPILER_VERSION,
                        'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                        'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                        'target_os':  db_entry[0].TARGET_OS,
                        'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                        'proj_guid':  db_entry[0].PROJ_GUID,
                        'opti_tool':  db_entry[0].OPTI_TOOL,
                        'target_run':  db_entry[0].TARGET_RUN,
                        'files': python_list(db_entry[0].FILES),
                        'strings': python_list(db_entry[0].STRINGS),
                        'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                        'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                    }
                else:
                    print "[INFO] Windows Binary Analysis Started"
                    app_dic['app_path'] = os.path.join(
                        app_dic['app_dir'], app_dic['md5'] + '.appx')
                    # ANALYSIS BEGINS
                    app_dic['size'] = str(file_size(app_dic['app_path'])) + 'MB'
                    # Generate hashes
                    app_dic['sha1'], app_dic[
                        'sha256'] = hash_gen(app_dic['app_path'])
                    # EXTRACT APPX
                    print "[INFO] Extracting APPX"
                    app_dic['files'] = unzip(
                        app_dic['app_path'], app_dic['app_dir'])
                    xml_dic = _parse_xml(app_dic['app_dir'])
                    bin_an_dic = _binary_analysis(app_dic)
                    # Saving to db
                    print "\n[INFO] Connecting to DB"
                    if rescan == '1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                            MD5=app_dic['md5']
                        ).update(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                    elif rescan == '0':
                        print "\n[INFO] Saving to Database"
                        db_item = StaticAnalyzerWindows(
                            TITLE='Static Analysis',
                            APP_NAME=app_dic['app_name'],
                            PUB_NAME=xml_dic['pub_name'],
                            SIZE=app_dic['size'],
                            MD5=app_dic['md5'],
                            SHA1=app_dic['sha1'],
                            SHA256=app_dic['sha256'],
                            BINNAME=bin_an_dic['bin_name'],
                            VERSION=xml_dic['version'],
                            ARCH=xml_dic['arch'],
                            COMPILER_VERSION=xml_dic['compiler_version'],
                            VISUAL_STUDIO_VERSION=xml_dic[
                                'visual_studio_version'],
                            VISUAL_STUDIO_EDITION=xml_dic[
                                'visual_studio_edition'],
                            TARGET_OS=xml_dic['target_os'],
                            APPX_DLL_VERSION=xml_dic['appx_dll_version'],
                            PROJ_GUID=xml_dic['proj_guid'],
                            OPTI_TOOL=xml_dic['opti_tool'],
                            TARGET_RUN=xml_dic['target_run'],
                            FILES=app_dic['files'],
                            STRINGS=bin_an_dic['strings'],
                            BIN_AN_RESULTS=bin_an_dic['results'],
                            BIN_AN_WARNINGS=bin_an_dic['warnings'],
                        )
                        db_item.save()
                    context = {
                        'title': 'Static Analysis',
                        'name': app_dic['app_name'],
                        'pub_name': xml_dic['pub_name'],
                        'size': app_dic['size'],
                        'md5': app_dic['md5'],
                        'sha1': app_dic['sha1'],
                        'sha256': app_dic['sha256'],
                        'bin_name': bin_an_dic['bin_name'],
                        'version': xml_dic['version'],
                        'arch': xml_dic['arch'],
                        'compiler_version': xml_dic['compiler_version'],
                        'visual_studio_version': xml_dic['visual_studio_version'],
                        'visual_studio_edition': xml_dic['visual_studio_edition'],
                        'target_os': xml_dic['target_os'],
                        'appx_dll_version': xml_dic['appx_dll_version'],
                        'proj_guid': xml_dic['proj_guid'],
                        'opti_tool': xml_dic['opti_tool'],
                        'target_run': xml_dic['target_run'],
                        'files': app_dic['files'],
                        'strings': bin_an_dic['strings'],
                        'bin_an_results': bin_an_dic['results'],
                        'bin_an_warnings': bin_an_dic['warnings'],
                    }
                template = "static_analysis/windows_binary_analysis.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            else:
                msg = "File type not supported"
                if api:
                    return print_n_send_error_response(request, msg, True)
                else:
                    return print_n_send_error_response(request, msg, False)
        else:
            msg = "Hash match failed or Invalid file extension"
            if api:
                return print_n_send_error_response(request, msg, True)
            else:
                return print_n_send_error_response(request, msg, False)
    except Exception as exception:
        msg = str(exception)
        exp_doc = exception.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp_doc)
        else:
            return print_n_send_error_response(request, msg, False, exp_doc)
def pdf(request, api=False):
    try:
        if api:
            checksum = request.POST['hash']
            scan_type = request.POST['scan_type']
        else:
            checksum = request.GET['md5']
            scan_type = request.GET['type']
        hash_match = re.match('^[0-9a-f]{32}$', checksum)
        if hash_match:
            if scan_type.lower() in ['apk', 'andzip']:
                static_db = StaticAnalyzerAndroid.objects.filter(MD5=checksum)
                if static_db.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = get_context_from_db_entry(static_db)
                    if scan_type.lower() == 'apk':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    if api:
                        return {"report": "Report not Found"}
                    else:
                        return HttpResponse(json.dumps({"report": "Report not Found"}),
                                            content_type="application/json; charset=utf-8", status_code=500)
            elif re.findall('ipa|ioszip', scan_type.lower()):
                if scan_type.lower() == 'ipa':
                    static_db = StaticAnalyzerIPA.objects.filter(MD5=checksum)
                    if static_db.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = get_context_from_db_entry_ipa(static_db)
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        if api:
                            return {"report": "Report not Found"}
                        else:
                            return HttpResponse(json.dumps({"report": "Report not Found"}),
                                                content_type="application/json; charset=utf-8", status_code=500)
                elif scan_type.lower() == 'ioszip':
                    static_db = StaticAnalyzerIOSZIP.objects.filter(MD5=checksum)
                    if static_db.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = get_context_from_db_entry_ios(static_db)
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        if api:
                            return {"report": "Report not Found"}
                        else:
                            return HttpResponse(json.dumps({"report": "Report not Found"}),
                                                content_type="application/json; charset=utf-8", status_code=500)
            elif re.findall('appx', scan_type.lower()):
                if scan_type.lower() == 'appx':
                    db_entry = StaticAnalyzerWindows.objects.filter(# pylint: disable-msg=E1101
                        MD5=checksum
                    )
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"

                        context = {
                            'title': db_entry[0].TITLE,
                            'name': db_entry[0].APP_NAME,
                            'pub_name': db_entry[0].PUB_NAME,
                            'size': db_entry[0].SIZE,
                            'md5': db_entry[0].MD5,
                            'sha1': db_entry[0].SHA1,
                            'sha256': db_entry[0].SHA256,
                            'bin_name': db_entry[0].BINNAME,
                            'version':  db_entry[0].VERSION,
                            'arch':  db_entry[0].ARCH,
                            'compiler_version':  db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':  db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':  db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':  db_entry[0].TARGET_OS,
                            'appx_dll_version':  db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':  db_entry[0].PROJ_GUID,
                            'opti_tool':  db_entry[0].OPTI_TOOL,
                            'target_run':  db_entry[0].TARGET_RUN,
                            'files':  python_list(db_entry[0].FILES),
                            'strings': python_list(db_entry[0].STRINGS),
                            'bin_an_results': python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings': python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                if api:
                    return {"scan_type": "Type is not Allowed"}
                else:
                    return HttpResponse(json.dumps({"type": "Type is not Allowed"}),
                                        content_type="application/json; charset=utf-8", status_code=500)
            html = template.render(context)
            try:
                options = {
                    'page-size': 'A4',
                    'quiet': '',
                    'no-collate': '',
                    'margin-top': '0.50in',
                    'margin-right': '0.50in',
                    'margin-bottom': '0.50in',
                    'margin-left': '0.50in',
                    'encoding': "UTF-8",
                    'custom-header': [
                        ('Accept-Encoding', 'gzip')
                    ],
                    'no-outline': None
                }
                pdf_dat = pdfkit.from_string(html, False, options=options)
                if api:
                    return {"pdf_dat": pdf_dat}
                else:
                    return HttpResponse(pdf_dat, content_type='application/pdf')
            except Exception as exp:
                if api:
                    return {"error": "Cannot Generate PDF", "err_details": str(exp)}
                else:
                    return HttpResponse(json.dumps({"pdf_error": "Cannot Generate PDF",
                                                    "err_details": str(exp)}),
                                        content_type="application/json; charset=utf-8", status_code=500)

        else:
            if api:
                return {"error": "Invalid scan hash"}
            else:
                return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                    content_type="application/json; charset=utf-8", status_code=500)
    except Exception as exp:
        msg = str(exp)
        exp = exp.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp)
        else:
            return print_n_send_error_response(request, msg, False, exp)
def Report(request):
    print "\n[INFO] Dynamic Analysis Report Generation"
    try:
        if request.method == 'GET':
            MD5 = request.GET['md5']
            PKG = request.GET['pkg']
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect('/error/')
            m = re.match('^[0-9a-f]{32}$', MD5)
            if m:
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(
                    settings.UPLD_DIR, MD5 + '/')  # APP DIRECTORY
                DWD_DIR = settings.DWD_DIR
                DRDMONAPISLOC = os.path.join(APP_DIR, 'x_logcat.txt')
                API_NET, API_BASE64, API_FILEIO, API_BINDER, API_CRYPTO, API_DEVICEINFO, API_CNTVL, API_SMS, API_SYSPROP, API_DEXLOADER, API_RELECT, API_ACNTMNGER, API_CMD = APIAnalysis(
                    PKG, DRDMONAPISLOC)
                URL, DOMAINS, EMAIL, CLIPBOARD, HTTP, XML, SQLiteDB, OtherFiles = RunAnalysis(
                    APP_DIR, MD5, PKG)
                Download(MD5, DWD_DIR, APP_DIR, PKG)
                # Only After Download Process is Done
                IMGS = []
                ACTIMGS = []
                ACT = {}
                EXPACTIMGS = []
                EXPACT = {}
                if os.path.exists(os.path.join(DWD_DIR, MD5 + "-screenshots-apk/")):
                    try:
                        for img in os.listdir(os.path.join(DWD_DIR, MD5 + "-screenshots-apk/")):
                            if img.endswith(".png"):
                                if img.startswith("act"):
                                    ACTIMGS.append(img)
                                elif img.startswith("expact"):
                                    EXPACTIMGS.append(img)
                                else:
                                    IMGS.append(img)
                        DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                        if DB.exists():
                            print "\n[INFO] Fetching Exported Activity & Activity List from DB"
                            EXPORTED_ACT = python_list(DB[0].EXPORTED_ACT)
                            ACTDESC = python_list(DB[0].ACTIVITIES)
                            if ACTIMGS:
                                if len(ACTIMGS) == len(ACTDESC):
                                    ACT = dict(zip(ACTIMGS, ACTDESC))
                            if EXPACTIMGS:
                                if len(EXPACTIMGS) == len(EXPORTED_ACT):
                                    EXPACT = dict(
                                        zip(EXPACTIMGS, EXPORTED_ACT))
                        else:
                            print "\n[WARNING] Entry does not exists in the DB."
                    except:
                        PrintException("[ERROR] Screenshot Sorting")

                context = {'emails': EMAIL,
                           'urls': URL,
                           'domains': DOMAINS,
                           'clipboard': CLIPBOARD,
                           'md5': MD5,
                           'http': HTTP,
                           'xml': XML,
                           'sqlite': SQLiteDB,
                           'others': OtherFiles,
                           'imgs': IMGS,
                           'acttest': ACT,
                           'expacttest': EXPACT,
                           'net': API_NET,
                           'base64': API_BASE64,
                           'crypto': API_CRYPTO,
                           'fileio': API_FILEIO,
                           'binder': API_BINDER,
                           'divinfo': API_DEVICEINFO,
                           'cntval': API_CNTVL,
                           'sms': API_SMS,
                           'sysprop': API_SYSPROP,
                           'dexload': API_DEXLOADER,
                           'reflect': API_RELECT,
                           'sysman': API_ACNTMNGER,
                           'process': API_CMD,
                           'pkg': PKG,
                           'title': 'Dynamic Analysis'}
                template = "dynamic_analysis/dynamic_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Dynamic Analysis Report Generation")
        return HttpResponseRedirect('/error/')
예제 #34
0
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):
                logger.info("[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():
                    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("" + str(len(activities)) +
                                    " Activities Identified")
                        for line in activities:
                            try:
                                act_no += 1
                                logger.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"
                                ])
                                logger.info("Activity Screenshot Taken")
                                adb_command(["am", "force-stop", package],
                                            True)
                                logger.info("Stopping App")
                            except:
                                PrintException("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:
                    logger.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/')
예제 #35
0
def get_context_from_db_entry_ios(db_entry):
    """Return the context for IOS ZIP from DB"""
    try:
        print(
            "\n[INFO] Analysis is already Done. Fetching data from the DB...")
        context = {
            'title':
            db_entry[0].TITLE,
            'file_name':
            db_entry[0].FILE_NAME,
            'size':
            db_entry[0].SIZE,
            'md5':
            db_entry[0].MD5,
            'sha1':
            db_entry[0].SHA1,
            'sha256':
            db_entry[0].SHA256,
            'plist':
            db_entry[0].INFOPLIST,
            'bin_name':
            db_entry[0].BINNAME,
            'id':
            db_entry[0].IDF,
            'build':
            db_entry[0].BUILD,
            'version':
            db_entry[0].VERSION,
            'sdk':
            db_entry[0].SDK,
            'pltfm':
            db_entry[0].PLTFM,
            'min':
            db_entry[0].MINX,
            'files':
            python_list(db_entry[0].FILES),
            'file_analysis':
            python_list(db_entry[0].SFILESX),
            'api':
            python_dict(db_entry[0].API),
            'insecure':
            python_dict(db_entry[0].CODEANAL),
            'urls':
            python_list(db_entry[0].URLnFile),
            'domains':
            python_dict(db_entry[0].DOMAINS),
            'emails':
            python_list(db_entry[0].EmailnFile),
            'permissions':
            python_list(db_entry[0].PERMISSIONS),
            'insecure_connections':
            python_list(db_entry[0].INSECCON),
            'bundle_name':
            db_entry[0].BUNDLE_NAME,
            'bundle_url_types':
            python_list(db_entry[0].BUNDLE_URL_TYPES),
            'bundle_supported_platforms':
            python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
            'bundle_localizations':
            python_list(db_entry[0].BUNDLE_LOCALIZATIONS),
        }
        return context
    except:
        PrintException("[ERROR] Fetching from DB")
def ExportedActivityTester(request):
    print "\n[INFO] Exported Activity Tester"
    try:
        MD5 = request.POST["md5"]
        PKG = request.POST["pkg"]
        m = re.match("^[0-9a-f]{32}$", MD5)
        if m:
            if re.findall(";|\$\(|\|\||&&", PKG):
                print "[ATTACK] Possible RCE"
                return HttpResponseRedirect("/error/")
            if request.method == "POST":
                DIR = settings.BASE_DIR
                APP_DIR = os.path.join(settings.UPLD_DIR, MD5 + "/")
                TOOLS_DIR = os.path.join(DIR, "DynamicAnalyzer/tools/")  # TOOLS DIR
                SCRDIR = os.path.join(APP_DIR, "screenshots-apk/")
                data = {}
                adb = getADB(TOOLS_DIR)

                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching Exported Activity List from DB"
                    EXPORTED_ACT = python_list(DB[0].EXPORTED_ACT)
                    if EXPORTED_ACT:
                        n = 0
                        print "\n[INFO] Starting Exported Activity Tester..."
                        print "\n[INFO] " + str(len(EXPORTED_ACT)) + " Exported Activities Identified"
                        for line in EXPORTED_ACT:
                            try:
                                n += 1
                                print "\n[INFO] Launching Exported Activity - " + str(n) + ". " + line
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "shell", "am", "start", "-n", PKG + "/" + line]
                                )
                                Wait(4)
                                subprocess.call(
                                    [adb, "-s", getIdentifier(), "shell", "screencap", "-p", "/data/local/screen.png"]
                                )
                                # ? get appended from Air :-() if activity names are used
                                subprocess.call(
                                    [
                                        adb,
                                        "-s",
                                        getIdentifier(),
                                        "pull",
                                        "/data/local/screen.png",
                                        SCRDIR + "expact-" + str(n) + ".png",
                                    ]
                                )
                                print "\n[INFO] Activity Screenshot Taken"
                                subprocess.call([adb, "-s", getIdentifier(), "shell", "am", "force-stop", PKG])
                                print "\n[INFO] Stopping App"
                            except:
                                PrintException("[ERROR] Exported Activity Tester")
                        data = {"expacttest": "done"}
                    else:
                        print "\n[INFO] Exported Activity Tester - No Activity Found!"
                        data = {"expacttest": "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] Exported Activity Tester")
        return HttpResponseRedirect("/error/")
예제 #37
0
def report(request):
    """Dynamic Analysis Report Generation"""
    logger.info("Dynamic Analysis Report Generation")
    try:
        if request.method == 'GET':
            md5_hash = request.GET['md5']
            package = request.GET['pkg']
            if re.findall(r";|\$\(|\|\||&&", package):
                logger.info("[ATTACK] Possible RCE")
                return HttpResponseRedirect('/error/')
            if re.match('^[0-9a-f]{32}$', md5_hash):
                app_dir = os.path.join(settings.UPLD_DIR,
                                       md5_hash + '/')  # APP DIRECTORY
                download_dir = settings.DWD_DIR
                droidmon_api_loc = os.path.join(app_dir, 'x_logcat.txt')
                api_analysis_result = api_analysis(package, droidmon_api_loc)
                analysis_result = run_analysis(app_dir, md5_hash, package)
                download(md5_hash, download_dir, app_dir, package)
                # Only After Download Process is Done
                imgs = []
                act_imgs = []
                act = {}
                expact_imgs = []
                exp_act = {}
                if os.path.exists(
                        os.path.join(download_dir,
                                     md5_hash + "-screenshots-apk/")):
                    try:
                        imp_path = os.path.join(download_dir,
                                                md5_hash + "-screenshots-apk/")
                        for img in os.listdir(imp_path):
                            if img.endswith(".png"):
                                if img.startswith("act"):
                                    act_imgs.append(img)
                                elif img.startswith("expact"):
                                    expact_imgs.append(img)
                                else:
                                    imgs.append(img)
                        static_android_db = StaticAnalyzerAndroid.objects.filter(
                            MD5=md5_hash)
                        if static_android_db.exists():
                            logger.info(
                                "\n[INFO] Fetching Exported Activity & Activity List from DB"
                            )
                            exported_act = python_list(
                                static_android_db[0].EXPORTED_ACT)
                            act_desc = python_list(
                                static_android_db[0].ACTIVITIES)
                            if act_imgs:
                                if len(act_imgs) == len(act_desc):
                                    act = dict(list(zip(act_imgs, act_desc)))
                            if expact_imgs:
                                if len(expact_imgs) == len(exported_act):
                                    exp_act = dict(
                                        list(zip(expact_imgs, exported_act)))
                        else:
                            logger.warning("Entry does not exists in the DB.")
                    except:
                        PrintException("[ERROR] Screenshot Sorting")
                context = {
                    'md5': md5_hash,
                    'emails': analysis_result["emails"],
                    'urls': analysis_result["urls"],
                    'domains': analysis_result["domains"],
                    'clipboard': analysis_result["clipboard"],
                    'http': analysis_result["web_data"],
                    'xml': analysis_result["xmlfiles"],
                    'sqlite': analysis_result["sqlite_db"],
                    'others': analysis_result["other_files"],
                    'imgs': imgs,
                    'acttest': act,
                    'expacttest': exp_act,
                    'net': api_analysis_result["api_net"],
                    'base64': api_analysis_result["api_base64"],
                    'crypto': api_analysis_result["api_crypto"],
                    'fileio': api_analysis_result["api_fileio"],
                    'binder': api_analysis_result["api_binder"],
                    'divinfo': api_analysis_result["api_deviceinfo"],
                    'cntval': api_analysis_result["api_cntvl"],
                    'sms': api_analysis_result["api_sms"],
                    'sysprop': api_analysis_result["api_sysprop"],
                    'dexload': api_analysis_result["api_dexloader"],
                    'reflect': api_analysis_result["api_reflect"],
                    'sysman': api_analysis_result["api_acntmnger"],
                    'process': api_analysis_result["api_cmd"],
                    'pkg': package,
                    'title': 'Dynamic Analysis'
                }
                template = "dynamic_analysis/dynamic_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except:
        PrintException("[ERROR] Dynamic Analysis Report Generation")
        return HttpResponseRedirect('/error/')
def StaticAnalyzer_iOS(request):
    try:
        #Input validation
        print "[INFO] iOS Static Analysis Started"
        TYP=request.GET['type']
        RESCAN= str(request.GET.get('rescan', 0))
        m=re.match('^[0-9a-f]{32}$',request.GET['checksum'])
        if ((m) and (request.GET['name'].lower().endswith('.ipa') or request.GET['name'].lower().endswith('.zip')) and (TYP in ['ipa', 'ios'])):
            DIR=settings.BASE_DIR        #BASE DIR
            APP_NAME=request.GET['name'] #APP ORGINAL NAME
            MD5=request.GET['checksum']  #MD5
            APP_DIR=os.path.join(settings.UPLD_DIR, MD5+'/') #APP DIRECTORY
            TOOLS_DIR=os.path.join(DIR, 'StaticAnalyzer/tools/mac/')  #TOOLS DIR
            if TYP=='ipa':
                #DB
                DB=StaticAnalyzerIPA.objects.filter(MD5=MD5)
                if DB.exists() and RESCAN=='0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                    'title' : DB[0].TITLE,
                    'name' : DB[0].APPNAMEX,
                    'size' : DB[0].SIZE,
                    'md5': DB[0].MD5,
                    'sha1' : DB[0].SHA1,
                    'sha256' : DB[0].SHA256,
                    'plist' : DB[0].INFOPLIST,
                    'bin_name' : DB[0].BINNAME,
                    'id' : DB[0].IDF,
                    'ver' : DB[0].VERSION,
                    'sdk' : DB[0].SDK,
                    'pltfm' : DB[0].PLTFM,
                    'min' : DB[0].MINX,
                    'bin_anal' : DB[0].BIN_ANAL,
                    'libs' : DB[0].LIBS,
                    'files' : python_list(DB[0].FILES),
                    'file_analysis' : DB[0].SFILESX,
                    'strings' : DB[0].STRINGS,
                    }
                else:
                    print "[INFO] iOS Binary (IPA) Analysis Started"
                    APP_FILE=MD5 + '.ipa'        #NEW FILENAME
                    APP_PATH=APP_DIR+APP_FILE    #APP PATH
                    BIN_DIR=os.path.join(APP_DIR,"Payload/")
                    #ANALYSIS BEGINS
                    SIZE=str(FileSize(APP_PATH)) + 'MB'   #FILE SIZE
                    SHA1, SHA256= HashGen(APP_PATH)       #SHA1 & SHA256 HASHES
                    print "[INFO] Extracting IPA"
                    Unzip(APP_PATH,APP_DIR)               #EXTRACT IPA
                    FILES,SFILES=iOS_ListFiles(BIN_DIR,MD5,True,'ipa')   #Get Files, normalize + to x, and convert binary plist -> xml
                    INFO_PLIST,BIN_NAME,ID,VER,SDK,PLTFM,MIN,LIBS,BIN_ANAL,STRINGS=BinaryAnalysis(BIN_DIR,TOOLS_DIR,APP_DIR)
                    #Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if RESCAN=='1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerIPA.objects.filter(MD5=MD5).update(TITLE='Static Analysis',APPNAMEX=APP_NAME,SIZE=SIZE,MD5=MD5,SHA1=SHA1,SHA256=SHA256,INFOPLIST=INFO_PLIST,BINNAME=BIN_NAME,IDF=ID,VERSION=VER,SDK=SDK,PLTFM=PLTFM,MINX=MIN,BIN_ANAL=BIN_ANAL,LIBS=LIBS,FILES=FILES,SFILESX=SFILES,STRINGS=STRINGS)
                    elif RESCAN=='0':
                        print "\n[INFO] Saving to Database"
                        STATIC_DB=StaticAnalyzerIPA(TITLE='Static Analysis',APPNAMEX=APP_NAME,SIZE=SIZE,MD5=MD5,SHA1=SHA1,SHA256=SHA256,INFOPLIST=INFO_PLIST,BINNAME=BIN_NAME,IDF=ID,VERSION=VER,SDK=SDK,PLTFM=PLTFM,MINX=MIN,BIN_ANAL=BIN_ANAL,LIBS=LIBS,FILES=FILES,SFILESX=SFILES,STRINGS=STRINGS)
                        STATIC_DB.save()
                    context = {
                    'title' : 'Static Analysis',
                    'name' : APP_NAME,
                    'size' : SIZE,
                    'md5': MD5,
                    'sha1' : SHA1,
                    'sha256' : SHA256,
                    'plist' : INFO_PLIST,
                    'bin_name' : BIN_NAME,
                    'id' : ID,
                    'ver' : VER,
                    'sdk' : SDK,
                    'pltfm' : PLTFM,
                    'min' : MIN,
                    'bin_anal' : BIN_ANAL,
                    'libs' : LIBS,
                    'files' : FILES,
                    'file_analysis' : SFILES,
                    'strings' : STRINGS,
                    }
                template="ios_binary_analysis.html"
                return render(request,template,context)
            elif TYP=='ios':
                DB=StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                if DB.exists() and RESCAN=='0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                    'title' : DB[0].TITLE,
                    'name' : DB[0].APPNAMEX,
                    'size' : DB[0].SIZE,
                    'md5': DB[0].MD5,
                    'sha1' : DB[0].SHA1,
                    'sha256' : DB[0].SHA256,
                    'plist' : DB[0].INFOPLIST,
                    'bin_name' : DB[0].BINNAME,
                    'id' : DB[0].IDF,
                    'ver' : DB[0].VERSION,
                    'sdk' : DB[0].SDK,
                    'pltfm' : DB[0].PLTFM,
                    'min' : DB[0].MINX,
                    'bin_anal' : DB[0].BIN_ANAL,
                    'libs' : DB[0].LIBS,
                    'files' : python_list(DB[0].FILES),
                    'file_analysis' : DB[0].SFILESX,
                    'api' : DB[0].HTML,
                    'insecure' : DB[0].CODEANAL,
                    'urls' : DB[0].URLnFile,
                    'domains': python_dict(DB[0].DOMAINS),
                    'emails' : DB[0].EmailnFile,
                    'strings' : DB[0].STRINGS
                    }
                else:
                    print "[INFO] iOS Source Code Analysis Started"
                    APP_FILE=MD5 + '.zip'        #NEW FILENAME
                    APP_PATH=APP_DIR+APP_FILE    #APP PATH
                    #ANALYSIS BEGINS - Already Unzipped
                    print "[INFO] ZIP Already Extracted"
                    SIZE=str(FileSize(APP_PATH)) + 'MB'   #FILE SIZE
                    SHA1, SHA256= HashGen(APP_PATH)       #SHA1 & SHA256 HASHES
                    FILES,SFILES=iOS_ListFiles(APP_DIR,MD5,False,'ios')
                    HTML,CODEANAL,URLnFile,DOMAINS,EmailnFile,INFO_PLIST,BIN_NAME,ID,VER,SDK,PLTFM,MIN=iOS_Source_Analysis(APP_DIR,MD5)
                    LIBS,BIN_ANAL='',''
                    #Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if RESCAN=='1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerIOSZIP.objects.filter(MD5=MD5).update(TITLE = 'Static Analysis',
                        APPNAMEX=APP_NAME,
                        SIZE=SIZE,
                        MD5=MD5,
                        SHA1=SHA1,
                        SHA256=SHA256,
                        INFOPLIST=INFO_PLIST,
                        BINNAME=BIN_NAME,
                        IDF=ID,
                        VERSION=VER,
                        SDK=SDK,
                        PLTFM=PLTFM,
                        MINX=MIN,
                        BIN_ANAL=BIN_ANAL,
                        LIBS=LIBS,
                        FILES=FILES,
                        SFILESX=SFILES,
                        HTML=HTML,
                        CODEANAL=CODEANAL,
                        URLnFile=URLnFile,
                        DOMAINS=DOMAINS,
                        EmailnFile=EmailnFile)
                    elif RESCAN=='0':
                        print "\n[INFO] Saving to Database"
                        STATIC_DB=StaticAnalyzerIOSZIP(TITLE = 'Static Analysis',
                        APPNAMEX=APP_NAME,
                        SIZE=SIZE,
                        MD5=MD5,
                        SHA1=SHA1,
                        SHA256=SHA256,
                        INFOPLIST=INFO_PLIST,
                        BINNAME=BIN_NAME,
                        IDF=ID,
                        VERSION=VER,
                        SDK=SDK,
                        PLTFM=PLTFM,
                        MINX=MIN,
                        BIN_ANAL=BIN_ANAL,
                        LIBS=LIBS,
                        FILES=FILES,
                        SFILESX=SFILES,
                        HTML=HTML,
                        CODEANAL=CODEANAL,
                        URLnFile=URLnFile,
                        DOMAINS=DOMAINS,
                        EmailnFile=EmailnFile)
                        STATIC_DB.save()
                    context = {
                    'title' : 'Static Analysis',
                    'name' : APP_NAME,
                    'size' : SIZE,
                    'md5': MD5,
                    'sha1' : SHA1,
                    'sha256' : SHA256,
                    'plist' : INFO_PLIST,
                    'bin_name' : BIN_NAME,
                    'id' : ID,
                    'ver' : VER,
                    'sdk' : SDK,
                    'pltfm' : PLTFM,
                    'min' : MIN,
                    'bin_anal' : BIN_ANAL,
                    'libs' : LIBS,
                    'files' : FILES,
                    'file_analysis' : SFILES,
                    'api' : HTML,
                    'insecure' : CODEANAL,
                    'urls' : URLnFile,
                    'domains': DOMAINS,
                    'emails' : EmailnFile
                    }
                template="ios_source_analysis.html"
                return render(request,template,context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except Exception as e:
        PrintException("[ERROR] Static Analyzer iOS")
        context = {
        'title' : 'Error',
        'exp' : e.message,
        'doc' : e.__doc__
        }
        template="error.html"
        return render(request,template,context)
예제 #39
0
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = get_context_from_db_entry(DB)
                    if TYP == 'APK':
                        template = get_template("pdf/static_analysis_pdf.html")
                    else:
                        template = get_template(
                            "pdf/static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(
                        json.dumps({"report": "Report not Found"}),
                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'strings': python_list(DB[0].STRINGS),
                            'permissions': python_list(DB[0].PERMISSIONS),
                            'insecure_connections':
                            python_list(DB[0].INSECCON),
                        }
                        template = get_template(
                            "pdf/ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'api': DB[0].HTML,
                            'insecure': DB[0].CODEANAL,
                            'urls': DB[0].URLnFile,
                            'domains': python_dict(DB[0].DOMAINS),
                            'emails': DB[0].EmailnFile,
                            'permissions': python_list(DB[0].PERMISSIONS),
                            'insecure_connections':
                            python_list(DB[0].INSECCON),
                        }
                        template = get_template(
                            "pdf/ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX', TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=MD5)
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"

                        context = {
                            'title':
                            db_entry[0].TITLE,
                            'name':
                            db_entry[0].APP_NAME,
                            'pub_name':
                            db_entry[0].PUB_NAME,
                            'size':
                            db_entry[0].SIZE,
                            'md5':
                            db_entry[0].MD5,
                            'sha1':
                            db_entry[0].SHA1,
                            'sha256':
                            db_entry[0].SHA256,
                            'bin_name':
                            db_entry[0].BINNAME,
                            'version':
                            db_entry[0].VERSION,
                            'arch':
                            db_entry[0].ARCH,
                            'compiler_version':
                            db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':
                            db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':
                            db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':
                            db_entry[0].TARGET_OS,
                            'appx_dll_version':
                            db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':
                            db_entry[0].PROJ_GUID,
                            'opti_tool':
                            db_entry[0].OPTI_TOOL,
                            'target_run':
                            db_entry[0].TARGET_RUN,
                            'files':
                            python_list(db_entry[0].FILES),
                            'strings':
                            python_list(db_entry[0].STRINGS),
                            'bin_an_results':
                            python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings':
                            python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "pdf/windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(
                    json.dumps({"type": "Type is not Allowed"}),
                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO("{0}".format(
                html.encode('utf-8'))),
                                    result,
                                    encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(),
                                    content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def PDF(request):
    try:
        MD5 = request.GET['md5']
        TYP = request.GET['type']
        m = re.match('^[0-9a-f]{32}$', MD5)
        if m:
            if TYP in ['APK', 'ANDZIP']:
                DB = StaticAnalyzerAndroid.objects.filter(MD5=MD5)
                if DB.exists():
                    print "\n[INFO] Fetching data from DB for PDF Report Generation (Android)"
                    context = {
                        'title': DB[0].TITLE,
                        'name': DB[0].APP_NAME,
                        'size': DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1': DB[0].SHA1,
                        'sha256': DB[0].SHA256,
                        'packagename': DB[0].PACKAGENAME,
                        'mainactivity': DB[0].MAINACTIVITY,
                        'targetsdk': DB[0].TARGET_SDK,
                        'maxsdk': DB[0].MAX_SDK,
                        'minsdk': DB[0].MIN_SDK,
                        'androvername': DB[0].ANDROVERNAME,
                        'androver': DB[0].ANDROVER,
                        'manifest': DB[0].MANIFEST_ANAL,
                        'permissions': DB[0].PERMISSIONS,
                        'files': python_list(DB[0].FILES),
                        'certz': DB[0].CERTZ,
                        'activities': python_list(DB[0].ACTIVITIES),
                        'receivers': python_list(DB[0].RECEIVERS),
                        'providers': python_list(DB[0].PROVIDERS),
                        'services': python_list(DB[0].SERVICES),
                        'libraries': python_list(DB[0].LIBRARIES),
                        'act_count': DB[0].CNT_ACT,
                        'prov_count': DB[0].CNT_PRO,
                        'serv_count': DB[0].CNT_SER,
                        'bro_count': DB[0].CNT_BRO,
                        'certinfo': DB[0].CERT_INFO,
                        'issued': DB[0].ISSUED,
                        'native': DB[0].NATIVE,
                        'dynamic': DB[0].DYNAMIC,
                        'reflection': DB[0].REFLECT,
                        'crypto': DB[0].CRYPTO,
                        'obfus': DB[0].OBFUS,
                        'api': DB[0].API,
                        'dang': DB[0].DANG,
                        'urls': DB[0].URLS,
                        'domains': python_dict(DB[0].DOMAINS),
                        'emails': DB[0].EMAILS,
                        'strings': python_list(DB[0].STRINGS),
                        'zipped': DB[0].ZIPPED,
                        'mani': DB[0].MANI
                    }
                    if TYP == 'APK':
                        template = get_template("static_analysis_pdf.html")
                    else:
                        template = get_template("static_analysis_zip_pdf.html")
                else:
                    return HttpResponse(
                        json.dumps({"report": "Report not Found"}),
                        content_type="application/json; charset=utf-8")
            elif re.findall('IPA|IOSZIP', TYP):
                if TYP == 'IPA':
                    DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS IPA)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'strings': DB[0].STRINGS
                        }
                        template = get_template("ios_binary_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
                elif TYP == 'IOSZIP':
                    DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                    if DB.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (IOS ZIP)"
                        context = {
                            'title': DB[0].TITLE,
                            'name': DB[0].APPNAMEX,
                            'size': DB[0].SIZE,
                            'md5': DB[0].MD5,
                            'sha1': DB[0].SHA1,
                            'sha256': DB[0].SHA256,
                            'plist': DB[0].INFOPLIST,
                            'bin_name': DB[0].BINNAME,
                            'id': DB[0].IDF,
                            'ver': DB[0].VERSION,
                            'sdk': DB[0].SDK,
                            'pltfm': DB[0].PLTFM,
                            'min': DB[0].MINX,
                            'bin_anal': DB[0].BIN_ANAL,
                            'libs': DB[0].LIBS,
                            'files': python_list(DB[0].FILES),
                            'file_analysis': DB[0].SFILESX,
                            'api': DB[0].HTML,
                            'insecure': DB[0].CODEANAL,
                            'urls': DB[0].URLnFile,
                            'domains': python_dict(DB[0].DOMAINS),
                            'emails': DB[0].EmailnFile
                        }
                        template = get_template("ios_source_analysis_pdf.html")
                    else:
                        return HttpResponse(
                            json.dumps({"report": "Report not Found"}),
                            content_type="application/json; charset=utf-8")
            elif re.findall('APPX', TYP):
                if TYP == 'APPX':
                    db_entry = StaticAnalyzerWindows.objects.filter(  # pylint: disable-msg=E1101
                        MD5=MD5)
                    if db_entry.exists():
                        print "\n[INFO] Fetching data from DB for PDF Report Generation (APPX)"
                        context = {
                            'title':
                            db_entry[0].TITLE,
                            'name':
                            db_entry[0].APP_NAME,
                            'pub_name':
                            db_entry[0].PUB_NAME,
                            'size':
                            db_entry[0].SIZE,
                            'md5':
                            db_entry[0].MD5,
                            'sha1':
                            db_entry[0].SHA1,
                            'sha256':
                            db_entry[0].SHA256,
                            'bin_name':
                            db_entry[0].BINNAME,
                            'version':
                            db_entry[0].VERSION,
                            'arch':
                            db_entry[0].ARCH,
                            'compiler_version':
                            db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':
                            db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':
                            db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':
                            db_entry[0].TARGET_OS,
                            'appx_dll_version':
                            db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':
                            db_entry[0].PROJ_GUID,
                            'opti_tool':
                            db_entry[0].OPTI_TOOL,
                            'target_run':
                            db_entry[0].TARGET_RUN,
                            'files':
                            python_list(db_entry[0].FILES),
                            'strings':
                            db_entry[0].STRINGS,
                            'bin_an_results':
                            python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings':
                            python_list(db_entry[0].BIN_AN_WARNINGS)
                        }
                        template = get_template(
                            "windows_binary_analysis_pdf.html")
            else:
                return HttpResponse(
                    json.dumps({"type": "Type is not Allowed"}),
                    content_type="application/json; charset=utf-8")
            html = template.render(context)
            result = StringIO()
            pdf = pisa.pisaDocument(StringIO("{0}".format(
                html.encode('utf-8'))),
                                    result,
                                    encoding='utf-8')
            if not pdf.err:
                return HttpResponse(result.getvalue(),
                                    content_type='application/pdf')
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponse(json.dumps({"md5": "Invalid MD5"}),
                                content_type="application/json; charset=utf-8")
    except:

        PrintException("[ERROR] PDF Report Generation Error")
        return HttpResponseRedirect('/error/')
def pdf(request, api=False, jsonres=False):
    try:
        if api:
            checksum = request.POST['hash']
            scan_type = request.POST['scan_type']
        else:
            checksum = request.GET['md5']
            scan_type = request.GET['type']
        hash_match = re.match('^[0-9a-f]{32}$', checksum)
        if hash_match:
            if scan_type.lower() in ['apk', 'andzip']:
                static_db = StaticAnalyzerAndroid.objects.filter(MD5=checksum)
                if static_db.exists():
                    logger.info('Fetching data from DB for '
                                'PDF Report Generation (Android)')
                    context = get_context_from_db_entry(static_db)
                    context['average_cvss'], context['security_score'] = score(
                        context['findings'])
                    if scan_type.lower() == 'apk':
                        template = get_template(
                            'pdf/android_binary_analysis.pdf.html')
                    else:
                        template = get_template(
                            'pdf/android_source_analysis_pdf.html')
                else:
                    if api:
                        return {'report': 'Report not Found'}
                    else:
                        return HttpResponse(
                            json.dumps({'report': 'Report not Found'}),
                            content_type='application/json; charset=utf-8',
                            status=500)
            elif scan_type.lower() in ['ipa', 'ioszip']:
                if scan_type.lower() == 'ipa':
                    static_db = StaticAnalyzerIPA.objects.filter(MD5=checksum)
                    if static_db.exists():
                        logger.info('Fetching data from DB for '
                                    'PDF Report Generation (IOS IPA)')
                        context = get_context_from_db_entry_ipa(static_db)
                        context['average_cvss'], context[
                            'security_score'] = score(context['bin_anal'])
                        template = get_template(
                            'pdf/ios_binary_analysis_pdf.html')
                    else:
                        if api:
                            return {'report': 'Report not Found'}
                        else:
                            return HttpResponse(
                                json.dumps({'report': 'Report not Found'}),
                                content_type='application/json; charset=utf-8',
                                status=500)
                elif scan_type.lower() == 'ioszip':
                    static_db = StaticAnalyzerIOSZIP.objects.filter(
                        MD5=checksum)
                    if static_db.exists():
                        logger.info('Fetching data from DB for '
                                    'PDF Report Generation (IOS ZIP)')
                        context = get_context_from_db_entry_ios(static_db)
                        context['average_cvss'], context[
                            'security_score'] = score(context['insecure'])
                        template = get_template(
                            'pdf/ios_source_analysis_pdf.html')
                    else:
                        if api:
                            return {'report': 'Report not Found'}
                        else:
                            return HttpResponse(
                                json.dumps({'report': 'Report not Found'}),
                                content_type='application/json; charset=utf-8',
                                status=500)
            elif 'appx' == scan_type.lower():
                if scan_type.lower() == 'appx':
                    db_entry = StaticAnalyzerWindows.objects.filter(
                        MD5=checksum, )
                    if db_entry.exists():
                        logger.info('Fetching data from DB for '
                                    'PDF Report Generation (APPX)')

                        context = {
                            'title':
                            db_entry[0].TITLE,
                            'name':
                            db_entry[0].APP_NAME,
                            'pub_name':
                            db_entry[0].PUB_NAME,
                            'size':
                            db_entry[0].SIZE,
                            'md5':
                            db_entry[0].MD5,
                            'sha1':
                            db_entry[0].SHA1,
                            'sha256':
                            db_entry[0].SHA256,
                            'bin_name':
                            db_entry[0].BINNAME,
                            'version':
                            db_entry[0].VERSION,
                            'arch':
                            db_entry[0].ARCH,
                            'compiler_version':
                            db_entry[0].COMPILER_VERSION,
                            'visual_studio_version':
                            db_entry[0].VISUAL_STUDIO_VERSION,
                            'visual_studio_edition':
                            db_entry[0].VISUAL_STUDIO_EDITION,
                            'target_os':
                            db_entry[0].TARGET_OS,
                            'appx_dll_version':
                            db_entry[0].APPX_DLL_VERSION,
                            'proj_guid':
                            db_entry[0].PROJ_GUID,
                            'opti_tool':
                            db_entry[0].OPTI_TOOL,
                            'target_run':
                            db_entry[0].TARGET_RUN,
                            'files':
                            python_list(db_entry[0].FILES),
                            'strings':
                            python_list(db_entry[0].STRINGS),
                            'bin_an_results':
                            python_list(db_entry[0].BIN_AN_RESULTS),
                            'bin_an_warnings':
                            python_list(db_entry[0].BIN_AN_WARNINGS),
                        }
                        template = get_template(
                            'pdf/windows_binary_analysis_pdf.html')
            else:
                if api:
                    return {'scan_type': 'Type is not Allowed'}
                else:
                    return HttpResponse(
                        json.dumps({'type': 'Type is not Allowed'}),
                        content_type='application/json; charset=utf-8',
                        status=500)

            context['VT_RESULT'] = None
            if settings.VT_ENABLED:
                app_dir = os.path.join(settings.UPLD_DIR, checksum + '/')
                vt = VirusTotal.VirusTotal()
                if 'zip' in scan_type.lower():
                    context['VT_RESULT'] = None
                else:
                    context['VT_RESULT'] = vt.get_result(
                        os.path.join(app_dir, checksum) + '.' +
                        scan_type.lower(), checksum)
            try:
                if api and jsonres:
                    return {'report_dat': context}
                else:
                    options = {
                        'page-size': 'A4',
                        'quiet': '',
                        'no-collate': '',
                        'margin-top': '0.50in',
                        'margin-right': '0.50in',
                        'margin-bottom': '0.50in',
                        'margin-left': '0.50in',
                        'encoding': 'UTF-8',
                        'custom-header': [
                            ('Accept-Encoding', 'gzip'),
                        ],
                        'no-outline': None,
                    }
                    html = template.render(context)
                    pdf_dat = pdfkit.from_string(html, False, options=options)
                    if api:
                        return {'pdf_dat': pdf_dat}
                    return HttpResponse(pdf_dat,
                                        content_type='application/pdf')
            except Exception as exp:
                logger.exception('Error Generating PDF Report')
                if api:
                    return {
                        'error': 'Cannot Generate PDF/JSON',
                        'err_details': str(exp)
                    }
                else:
                    return HttpResponse(
                        json.dumps({
                            'pdf_error': 'Cannot Generate PDF',
                            'err_details': str(exp)
                        }),
                        content_type='application/json; charset=utf-8',
                        status=500)

        else:
            if api:
                return {'error': 'Invalid scan hash'}
            else:
                return HttpResponse(
                    json.dumps({'md5': 'Invalid MD5'}),
                    content_type='application/json; charset=utf-8',
                    status=500)
    except Exception as exp:
        logger.exception('Error Generating PDF Report')
        msg = str(exp)
        exp = exp.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp)
        else:
            return print_n_send_error_response(request, msg, False, exp)
def APIAnalysis(PKG, LOCATION):
    print "\n[INFO] Dynamic API Analysis"
    dat = ""
    API_BASE64 = []
    API_FILEIO = []
    API_RELECT = []
    API_SYSPROP = []
    API_CNTRSLVR = []
    API_CNTVAL = []
    API_BINDER = []
    API_CRYPTO = []
    API_ACNTMNGER = []
    API_DEVICEINFO = []
    API_NET = []
    API_DEXLOADER = []
    API_CMD = []
    API_SMS = []
    try:
        with open(LOCATION, "r") as f:
            dat = f.readlines()
        ID = "Droidmon-apimonitor-" + PKG + ":"
        for line in dat:
            line = line.decode('utf8', 'ignore')
            if (ID) in line:
                # print "LINE: " + line
                param, value = line.split(ID, 1)
                # print "PARAM is :" + param
                # print "Value is :"+ value
                try:
                    APIs = json.loads(value, strict=False)
                    RET = ''
                    CLS = ''
                    MTD = ''
                    ARGS = ''
                    MTD = str(APIs["method"])
                    CLS = str(APIs["class"])
                    # print "Called Class: " + CLS
                    # print "Called Method: " + MTD
                    if APIs.get('return'):
                        RET = str(APIs["return"])
                        # print "Return Data: " + RET
                    else:
                        # print "No Return Data"
                        RET = "No Return Data"
                    if APIs.get('args'):
                        ARGS = str(APIs["args"])
                        # print "Passed Arguments" + ARGS
                    else:
                        # print "No Arguments Passed"
                        ARGS = "No Arguments Passed"
                    # XSS Safe
                    D = "</br>METHOD: " + \
                        escape(MTD) + "</br>ARGUMENTS: " + escape(ARGS) + \
                        "</br>RETURN DATA: " + escape(RET)

                    if re.findall("android.util.Base64", CLS):
                        # Base64 Decode
                        if ("decode" in MTD):
                            args_list = python_list(ARGS)
                            if isBase64(args_list[0]):
                                D += '</br><span class="label label-info">Decoded String:</span> ' + \
                                    escape(base64.b64decode(args_list[0]))
                        API_BASE64.append(D)
                    if re.findall('libcore.io|android.app.SharedPreferencesImpl$EditorImpl', CLS):
                        API_FILEIO.append(D)
                    if re.findall('java.lang.reflect', CLS):
                        API_RELECT.append(D)
                    if re.findall('android.content.ContentResolver|android.location.Location|android.media.AudioRecord|android.media.MediaRecorder|android.os.SystemProperties', CLS):
                        API_SYSPROP.append(D)
                    if re.findall('android.app.Activity|android.app.ContextImpl|android.app.ActivityThread', CLS):
                        API_BINDER.append(D)
                    if re.findall('javax.crypto.spec.SecretKeySpec|javax.crypto.Cipher|javax.crypto.Mac', CLS):
                        API_CRYPTO.append(D)
                    if re.findall('android.accounts.AccountManager|android.app.ApplicationPackageManager|android.app.NotificationManager|android.net.ConnectivityManager|android.content.BroadcastReceiver', CLS):
                        API_ACNTMNGER.append(D)
                    if re.findall('android.telephony.TelephonyManager|android.net.wifi.WifiInfo|android.os.Debug', CLS):
                        API_DEVICEINFO.append(D)
                    if re.findall('dalvik.system.BaseDexClassLoader|dalvik.system.DexFile|dalvik.system.DexClassLoader|dalvik.system.PathClassLoader', CLS):
                        API_DEXLOADER.append(D)
                    if re.findall('java.lang.Runtime|java.lang.ProcessBuilder|java.io.FileOutputStream|java.io.FileInputStream|android.os.Process', CLS):
                        API_CMD.append(D)
                    if re.findall('android.content.ContentValues', CLS):
                        API_CNTVAL.append(D)
                    if re.findall('android.telephony.SmsManager', CLS):
                        API_SMS.append(D)
                    if re.findall('java.net.URL|org.apache.http.impl.client.AbstractHttpClient', CLS):
                        API_NET.append(D)
                except:
                    PrintException("[ERROR] Parsing JSON Failed for: " + value)
    except:
        PrintException("[ERROR] Dynamic API Analysis")
        pass
    return list(set(API_NET)), list(set(API_BASE64)), list(set(API_FILEIO)), list(set(API_BINDER)), list(set(API_CRYPTO)), list(set(API_DEVICEINFO)), list(set(API_CNTVAL)), list(set(API_SMS)), list(set(API_SYSPROP)), list(set(API_DEXLOADER)), list(set(API_RELECT)), list(set(API_ACNTMNGER)), list(set(API_CMD))
예제 #43
0
def StaticAnalyzer_iOS(request):
    try:
        # Input validation
        print "[INFO] iOS Static Analysis Started"
        TYP = request.GET['type']
        RESCAN = str(request.GET.get('rescan', 0))
        m = re.match('^[0-9a-f]{32}$', request.GET['checksum'])
        if ((m) and (request.GET['name'].lower().endswith('.ipa')
                     or request.GET['name'].lower().endswith('.zip'))
                and (TYP in ['ipa', 'ios'])):
            DIR = settings.BASE_DIR  # BASE DIR
            APP_NAME = request.GET['name']  # APP ORGINAL NAME
            MD5 = request.GET['checksum']  # MD5
            APP_DIR = os.path.join(settings.UPLD_DIR,
                                   MD5 + '/')  # APP DIRECTORY
            TOOLS_DIR = os.path.join(DIR,
                                     'StaticAnalyzer/tools/mac/')  # TOOLS DIR
            if TYP == 'ipa':
                # DB
                DB = StaticAnalyzerIPA.objects.filter(MD5=MD5)
                if DB.exists() and RESCAN == '0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                        'title': DB[0].TITLE,
                        'name': DB[0].APPNAMEX,
                        'size': DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1': DB[0].SHA1,
                        'sha256': DB[0].SHA256,
                        'plist': DB[0].INFOPLIST,
                        'bin_name': DB[0].BINNAME,
                        'id': DB[0].IDF,
                        'ver': DB[0].VERSION,
                        'sdk': DB[0].SDK,
                        'pltfm': DB[0].PLTFM,
                        'min': DB[0].MINX,
                        'bin_anal': DB[0].BIN_ANAL,
                        'libs': DB[0].LIBS,
                        'files': python_list(DB[0].FILES),
                        'file_analysis': DB[0].SFILESX,
                        'strings': DB[0].STRINGS,
                    }
                else:
                    print "[INFO] iOS Binary (IPA) Analysis Started"
                    APP_FILE = MD5 + '.ipa'  # NEW FILENAME
                    APP_PATH = APP_DIR + APP_FILE  # APP PATH
                    BIN_DIR = os.path.join(APP_DIR, "Payload/")
                    # ANALYSIS BEGINS
                    SIZE = str(FileSize(APP_PATH)) + 'MB'  # FILE SIZE
                    SHA1, SHA256 = HashGen(APP_PATH)  # SHA1 & SHA256 HASHES
                    print "[INFO] Extracting IPA"
                    Unzip(APP_PATH, APP_DIR)  # EXTRACT IPA
                    # Get Files, normalize + to x, and convert binary plist ->
                    # xml
                    FILES, SFILES = iOS_ListFiles(BIN_DIR, MD5, True, 'ipa')
                    INFO_PLIST, BIN_NAME, ID, VER, SDK, PLTFM, MIN, LIBS, BIN_ANAL, STRINGS = BinaryAnalysis(
                        BIN_DIR, TOOLS_DIR, APP_DIR)
                    # Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if RESCAN == '1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerIPA.objects.filter(MD5=MD5).update(
                            TITLE='Static Analysis',
                            APPNAMEX=APP_NAME,
                            SIZE=SIZE,
                            MD5=MD5,
                            SHA1=SHA1,
                            SHA256=SHA256,
                            INFOPLIST=INFO_PLIST,
                            BINNAME=BIN_NAME,
                            IDF=ID,
                            VERSION=VER,
                            SDK=SDK,
                            PLTFM=PLTFM,
                            MINX=MIN,
                            BIN_ANAL=BIN_ANAL,
                            LIBS=LIBS,
                            FILES=FILES,
                            SFILESX=SFILES,
                            STRINGS=STRINGS)
                    elif RESCAN == '0':
                        print "\n[INFO] Saving to Database"
                        STATIC_DB = StaticAnalyzerIPA(TITLE='Static Analysis',
                                                      APPNAMEX=APP_NAME,
                                                      SIZE=SIZE,
                                                      MD5=MD5,
                                                      SHA1=SHA1,
                                                      SHA256=SHA256,
                                                      INFOPLIST=INFO_PLIST,
                                                      BINNAME=BIN_NAME,
                                                      IDF=ID,
                                                      VERSION=VER,
                                                      SDK=SDK,
                                                      PLTFM=PLTFM,
                                                      MINX=MIN,
                                                      BIN_ANAL=BIN_ANAL,
                                                      LIBS=LIBS,
                                                      FILES=FILES,
                                                      SFILESX=SFILES,
                                                      STRINGS=STRINGS)
                        STATIC_DB.save()
                    context = {
                        'title': 'Static Analysis',
                        'name': APP_NAME,
                        'size': SIZE,
                        'md5': MD5,
                        'sha1': SHA1,
                        'sha256': SHA256,
                        'plist': INFO_PLIST,
                        'bin_name': BIN_NAME,
                        'id': ID,
                        'ver': VER,
                        'sdk': SDK,
                        'pltfm': PLTFM,
                        'min': MIN,
                        'bin_anal': BIN_ANAL,
                        'libs': LIBS,
                        'files': FILES,
                        'file_analysis': SFILES,
                        'strings': STRINGS,
                    }
                template = "static_analysis/ios_binary_analysis.html"
                return render(request, template, context)
            elif TYP == 'ios':
                DB = StaticAnalyzerIOSZIP.objects.filter(MD5=MD5)
                if DB.exists() and RESCAN == '0':
                    print "\n[INFO] Analysis is already Done. Fetching data from the DB..."
                    context = {
                        'title': DB[0].TITLE,
                        'name': DB[0].APPNAMEX,
                        'size': DB[0].SIZE,
                        'md5': DB[0].MD5,
                        'sha1': DB[0].SHA1,
                        'sha256': DB[0].SHA256,
                        'plist': DB[0].INFOPLIST,
                        'bin_name': DB[0].BINNAME,
                        'id': DB[0].IDF,
                        'ver': DB[0].VERSION,
                        'sdk': DB[0].SDK,
                        'pltfm': DB[0].PLTFM,
                        'min': DB[0].MINX,
                        'bin_anal': DB[0].BIN_ANAL,
                        'libs': DB[0].LIBS,
                        'files': python_list(DB[0].FILES),
                        'file_analysis': DB[0].SFILESX,
                        'api': DB[0].HTML,
                        'insecure': DB[0].CODEANAL,
                        'urls': DB[0].URLnFile,
                        'domains': python_dict(DB[0].DOMAINS),
                        'emails': DB[0].EmailnFile,
                        'strings': DB[0].STRINGS
                    }
                else:
                    print "[INFO] iOS Source Code Analysis Started"
                    APP_FILE = MD5 + '.zip'  # NEW FILENAME
                    APP_PATH = APP_DIR + APP_FILE  # APP PATH
                    # ANALYSIS BEGINS - Already Unzipped
                    print "[INFO] ZIP Already Extracted"
                    SIZE = str(FileSize(APP_PATH)) + 'MB'  # FILE SIZE
                    SHA1, SHA256 = HashGen(APP_PATH)  # SHA1 & SHA256 HASHES
                    FILES, SFILES = iOS_ListFiles(APP_DIR, MD5, False, 'ios')
                    HTML, CODEANAL, URLnFile, DOMAINS, EmailnFile, INFO_PLIST, BIN_NAME, ID, VER, SDK, PLTFM, MIN = iOS_Source_Analysis(
                        APP_DIR, MD5)
                    LIBS, BIN_ANAL = '', ''
                    # Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if RESCAN == '1':
                        print "\n[INFO] Updating Database..."
                        StaticAnalyzerIOSZIP.objects.filter(MD5=MD5).update(
                            TITLE='Static Analysis',
                            APPNAMEX=APP_NAME,
                            SIZE=SIZE,
                            MD5=MD5,
                            SHA1=SHA1,
                            SHA256=SHA256,
                            INFOPLIST=INFO_PLIST,
                            BINNAME=BIN_NAME,
                            IDF=ID,
                            VERSION=VER,
                            SDK=SDK,
                            PLTFM=PLTFM,
                            MINX=MIN,
                            BIN_ANAL=BIN_ANAL,
                            LIBS=LIBS,
                            FILES=FILES,
                            SFILESX=SFILES,
                            HTML=HTML,
                            CODEANAL=CODEANAL,
                            URLnFile=URLnFile,
                            DOMAINS=DOMAINS,
                            EmailnFile=EmailnFile)
                    elif RESCAN == '0':
                        print "\n[INFO] Saving to Database"
                        STATIC_DB = StaticAnalyzerIOSZIP(
                            TITLE='Static Analysis',
                            APPNAMEX=APP_NAME,
                            SIZE=SIZE,
                            MD5=MD5,
                            SHA1=SHA1,
                            SHA256=SHA256,
                            INFOPLIST=INFO_PLIST,
                            BINNAME=BIN_NAME,
                            IDF=ID,
                            VERSION=VER,
                            SDK=SDK,
                            PLTFM=PLTFM,
                            MINX=MIN,
                            BIN_ANAL=BIN_ANAL,
                            LIBS=LIBS,
                            FILES=FILES,
                            SFILESX=SFILES,
                            HTML=HTML,
                            CODEANAL=CODEANAL,
                            URLnFile=URLnFile,
                            DOMAINS=DOMAINS,
                            EmailnFile=EmailnFile)
                        STATIC_DB.save()
                    context = {
                        'title': 'Static Analysis',
                        'name': APP_NAME,
                        'size': SIZE,
                        'md5': MD5,
                        'sha1': SHA1,
                        'sha256': SHA256,
                        'plist': INFO_PLIST,
                        'bin_name': BIN_NAME,
                        'id': ID,
                        'ver': VER,
                        'sdk': SDK,
                        'pltfm': PLTFM,
                        'min': MIN,
                        'bin_anal': BIN_ANAL,
                        'libs': LIBS,
                        'files': FILES,
                        'file_analysis': SFILES,
                        'api': HTML,
                        'insecure': CODEANAL,
                        'urls': URLnFile,
                        'domains': DOMAINS,
                        'emails': EmailnFile
                    }
                template = "static_analysis/ios_source_analysis.html"
                return render(request, template, context)
            else:
                return HttpResponseRedirect('/error/')
        else:
            return HttpResponseRedirect('/error/')
    except Exception as exp:
        PrintException("[ERROR] Static Analyzer iOS")
        context = {'title': 'Error', 'exp': exp.message, 'doc': exp.__doc__}
        template = "general/error.html"
        return render(request, template, context)