def static_analyzer_ios(request):
    """Module that performs iOS IPA/ZIP Static Analysis"""
    try:
        print "[INFO] iOS Static Analysis Started"
        file_type = request.GET['type']
        rescan = str(request.GET.get('rescan', 0))
        md5_match = re.match('^[0-9a-f]{32}$', request.GET['checksum'])
        if ((md5_match) and
                (request.GET['name'].lower().endswith('.ipa') or
                 request.GET['name'].lower().endswith('.zip')
                ) and
                (file_type in ['ipa', 'ios'])
           ):
            app_dict = {}
            app_dict["directory"] = settings.BASE_DIR  # BASE DIR
            app_dict["app_name"] = request.GET['name']  # APP ORGINAL NAME
            app_dict["md5_hash"] = request.GET['checksum']  # MD5
            app_dict["app_dir"] = os.path.join(
                settings.UPLD_DIR, app_dict["md5_hash"] + '/')  # APP DIRECTORY
            tools_dir = os.path.join(
                app_dict["directory"], 'StaticAnalyzer/tools/mac/')  # TOOLS DIR
            if file_type == 'ipa':
                # DB
                ipa_db = StaticAnalyzerIPA.objects.filter(
                    MD5=app_dict["md5_hash"])
                if ipa_db.exists() and rescan == '0':
                    context = get_context_from_db_entry_ipa(ipa_db)
                else:
                    print "[INFO] iOS Binary (IPA) Analysis Started"
                    app_dict["app_file"] = app_dict[
                        "md5_hash"] + '.ipa'  # NEW FILENAME
                    app_dict["app_path"] = app_dict["app_dir"] + \
                        app_dict["app_file"]  # APP PATH
                    app_dict["bin_dir"] = os.path.join(
                        app_dict["app_dir"], "Payload/")
                    app_dict["size"] = str(
                        FileSize(app_dict["app_path"])) + 'MB'  # FILE SIZE
                    app_dict["sha1"], app_dict["sha256"] = HashGen(
                        app_dict["app_path"])  # SHA1 & SHA256 HASHES
                    print "[INFO] Extracting IPA"
                    # EXTRACT IPA
                    Unzip(app_dict["app_path"], app_dict["app_dir"])
                    # Get Files, normalize + to x,
                    # and convert binary plist -> xml
                    files, sfiles = ios_list_files(
                        app_dict["bin_dir"], app_dict["md5_hash"], True, 'ipa')
                    infoplist_dict = plist_analysis(app_dict["bin_dir"], False)
                    bin_analysis_dict = binary_analysis(
                        app_dict["bin_dir"], tools_dir, app_dict["app_dir"])
                    # Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if rescan == '1':
                        print "\n[INFO] Updating Database..."
                        update_db_entry_ipa(
                            app_dict, infoplist_dict, bin_analysis_dict, files, sfiles)
                    elif rescan == '0':
                        print "\n[INFO] Saving to Database"
                        create_db_entry_ipa(
                            app_dict, infoplist_dict, bin_analysis_dict, files, sfiles)
                    context = get_context_from_analysis_ipa(
                        app_dict, infoplist_dict, bin_analysis_dict, files, sfiles)
                template = "static_analysis/ios_binary_analysis.html"
                return render(request, template, context)
            elif file_type == 'ios':
                ios_zip_db = StaticAnalyzerIOSZIP.objects.filter(
                    MD5=app_dict["md5_hash"])
                if ios_zip_db.exists() and rescan == '0':
                    context = get_context_from_db_entry_ios(ios_zip_db)
                else:
                    print "[INFO] iOS Source Code Analysis Started"
                    app_dict["app_file"] = app_dict[
                        "md5_hash"] + '.zip'  # NEW FILENAME
                    app_dict["app_path"] = app_dict["app_dir"] + \
                        app_dict["app_file"]  # APP PATH
                    # ANALYSIS BEGINS - Already Unzipped‰
                    print "[INFO] ZIP Already Extracted"
                    app_dict["size"] = str(
                        FileSize(app_dict["app_path"])) + 'MB'  # FILE SIZE
                    app_dict["sha1"], app_dict["sha256"] = HashGen(
                        app_dict["app_path"])  # SHA1 & SHA256 HASHES
                    files, sfiles = ios_list_files(
                        app_dict["app_dir"], app_dict["md5_hash"], False, 'os')
                    infoplist_dict = plist_analysis(app_dict["app_dir"], True)
                    code_analysis_dic = ios_source_analysis(
                        app_dict["app_dir"], app_dict["md5_hash"])
                    # Saving to DB
                    print "\n[INFO] Connecting to DB"
                    if rescan == '1':
                        print "\n[INFO] Updating Database..."
                        update_db_entry_ios(
                            app_dict, infoplist_dict, code_analysis_dic, files, sfiles)
                    elif rescan == '0':
                        print "\n[INFO] Saving to Database"
                        create_db_entry_ios(
                            app_dict, infoplist_dict, code_analysis_dic, files, sfiles)
                    context = get_context_from_analysis_ios(
                        app_dict, infoplist_dict, code_analysis_dic, files, sfiles)
                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)
Exemple #2
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)
def static_analyzer(request):
    """Do static analysis on an request and save to db."""
    try:
        # Input validation
        app_dic = {}
        typ = request.GET['type']
        # output = request.GET['format'] # Later for json output
        match = re.match('^[0-9a-f]{32}$', request.GET['checksum'])
        if ((match) and (request.GET['name'].lower().endswith('.apk')
                         or request.GET['name'].lower().endswith('.zip'))
                and (typ in ['zip', 'apk'])):
            app_dic['dir'] = settings.BASE_DIR  # BASE DIR
            app_dic['app_name'] = request.GET['name']  # APP ORGINAL NAME
            app_dic['md5'] = request.GET['checksum']  # MD5
            app_dic['app_dir'] = os.path.join(
                settings.UPLD_DIR, app_dic['md5'] + '/')  # APP DIRECTORY
            app_dic['tools_dir'] = os.path.join(
                app_dic['dir'], 'StaticAnalyzer/tools/')  # TOOLS DIR
            # DWD_DIR = settings.DWD_DIR # not needed? Var is never used.
            print "[INFO] Starting Analysis on : " + app_dic['app_name']
            rescan = str(request.GET.get('rescan', 0))
            if typ == 'apk':
                # Check if in DB
                # pylint: disable=E1101
                db_entry = StaticAnalyzerAndroid.objects.filter(
                    MD5=app_dic['md5'])
                if db_entry.exists() and rescan == '0':
                    context = get_context_from_db_entry(db_entry)
                else:
                    app_dic[
                        'app_file'] = app_dic['md5'] + '.apk'  # NEW FILENAME
                    app_dic['app_path'] = app_dic['app_dir'] + \
                        app_dic['app_file']  # APP PATH

                    # ANALYSIS BEGINS
                    app_dic['size'] = str(FileSize(
                        app_dic['app_path'])) + 'MB'  # FILE SIZE
                    app_dic['sha1'], app_dic['sha256'] = HashGen(
                        app_dic['app_path'])

                    app_dic['files'] = Unzip(app_dic['app_path'],
                                             app_dic['app_dir'])
                    app_dic['certz'] = get_hardcoded_cert_keystore(
                        app_dic['files'])

                    print "[INFO] APK Extracted"

                    # Manifest XML
                    app_dic['parsed_xml'] = get_manifest(
                        app_dic['app_dir'], app_dic['tools_dir'], '', True)

                    # Set Manifest link
                    app_dic['mani'] = '../ManifestView/?md5=' + \
                        app_dic['md5'] + '&type=apk&bin=1'
                    man_data_dic = manifest_data(app_dic['parsed_xml'])

                    man_an_dic = manifest_analysis(app_dic['parsed_xml'],
                                                   man_data_dic)

                    cert_dic = cert_info(app_dic['app_dir'],
                                         app_dic['tools_dir'])
                    dex_2_jar(app_dic['app_path'], app_dic['app_dir'],
                              app_dic['tools_dir'])
                    dex_2_smali(app_dic['app_dir'], app_dic['tools_dir'])
                    jar_2_java(app_dic['app_dir'], app_dic['tools_dir'])
                    code_an_dic = code_analysis(app_dic['app_dir'],
                                                app_dic['md5'],
                                                man_an_dic['permissons'],
                                                "apk")

                    print "\n[INFO] Generating Java and Smali Downloads"
                    gen_downloads(app_dic['app_dir'], app_dic['md5'])

                    # Get the strings
                    app_dic['strings'] = strings(app_dic['app_file'],
                                                 app_dic['app_dir'],
                                                 app_dic['tools_dir'])
                    app_dic['zipped'] = '&type=apk'

                    print "\n[INFO] Connecting to Database"
                    try:
                        # SAVE TO DB
                        if rescan == '1':
                            print "\n[INFO] Updating Database..."
                            update_db_entry(app_dic, man_data_dic, man_an_dic,
                                            code_an_dic, cert_dic)
                        elif rescan == '0':
                            print "\n[INFO] Saving to Database"
                            create_db_entry(app_dic, man_data_dic, man_an_dic,
                                            code_an_dic, cert_dic)
                    except:
                        PrintException("[ERROR] Saving to Database Failed")
                    context = get_context_from_an(app_dic, man_data_dic,
                                                  man_an_dic, code_an_dic,
                                                  cert_dic)
                template = "static_analysis/static_analysis.html"
                return render(request, template, context)
            elif typ == 'zip':
                # Check if in DB
                # pylint: disable=E1101
                db_entry = StaticAnalyzerAndroid.objects.filter(
                    MD5=app_dic['md5'])
                if db_entry.exists() and rescan == '0':
                    context = get_context_from_db_entry_zip(db_entry)
                else:
                    app_dic[
                        'app_file'] = app_dic['md5'] + '.zip'  # NEW FILENAME
                    app_dic['app_path'] = app_dic['app_dir'] + \
                        app_dic['app_file']  # APP PATH
                    print "[INFO] Extracting ZIP"
                    app_dic['files'] = Unzip(app_dic['app_path'],
                                             app_dic['app_dir'])
                    # Check if Valid Directory Structure and get ZIP Type
                    pro_type, valid = valid_android_zip(app_dic['app_dir'])
                    if valid and pro_type == 'ios':
                        print "[INFO] Redirecting to iOS Source Code Analyzer"
                        return HttpResponseRedirect(
                            '/StaticAnalyzer_iOS/?name=' +
                            app_dic['app_name'] + '&type=ios&checksum=' +
                            app_dic['md5'])
                    app_dic['certz'] = get_hardcoded_cert_keystore(
                        app_dic['files'])
                    print "[INFO] ZIP Type - " + pro_type
                    if valid and (pro_type in ['eclipse', 'studio']):
                        # ANALYSIS BEGINS
                        app_dic['size'] = str(FileSize(
                            app_dic['app_path'])) + 'MB'  # FILE SIZE
                        app_dic['sha1'], app_dic['sha256'] = HashGen(
                            app_dic['app_path'])

                        # Manifest XML
                        app_dic['persed_xml'] = get_manifest(
                            app_dic['app_dir'], app_dic['tools_dir'], pro_type,
                            False)

                        # Set manifest view link
                        app_dic['mani'] = ('../ManifestView/?md5=' +
                                           app_dic['md5'] + '&type=' +
                                           pro_type + '&bin=0')

                        man_data_dic = manifest_data(app_dic['persed_xml'])

                        man_an_dic = manifest_analysis(app_dic['persed_xml'],
                                                       man_data_dic)

                        code_an_dic = code_analysis(app_dic['app_dir'],
                                                    app_dic['md5'],
                                                    man_an_dic['permissons'],
                                                    pro_type)
                        print "\n[INFO] Connecting to Database"
                        try:
                            # SAVE TO DB
                            if rescan == '1':
                                print "\n[INFO] Updating Database..."
                                update_db_entry_zip(app_dic, man_data_dic,
                                                    man_an_dic, code_an_dic)
                            elif rescan == '0':
                                print "\n[INFO] Saving to Database"
                                create_db_entry_zip(app_dic, man_data_dic,
                                                    man_an_dic, code_an_dic)
                        except:
                            PrintException("[ERROR] Saving to Database Failed")
                        context = get_context_from_an_zip(
                            app_dic, man_data_dic, man_an_dic, code_an_dic)
                    else:
                        return HttpResponseRedirect('/zip_format/')
                template = "static_analysis/static_analysis_android_zip.html"
                return render(request, template, context)
            else:
                print "\n[ERROR] Only APK,IPA and Zipped Android/iOS Source code supported now!"
        else:
            return HttpResponseRedirect('/error/')

    except Exception as excep:
        PrintException("[ERROR] Static Analyzer")
        context = {
            'title': 'Error',
            'exp': excep.message,
            'doc': excep.__doc__
        }
        template = "general/error.html"
        return render(request, template, context)