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)
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)