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() 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 } BASE_DIR = os.path.dirname( os.path.dirname(os.path.dirname( os.path.abspath(__file__)))) path_wk = os.path.join(BASE_DIR, 'windows/wkhtmltopdf/wkhtmltopdf.exe') # path_wk = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe' # 安装位置 config = pdfkit.configuration(wkhtmltopdf=path_wk) pdf_dat = pdfkit.from_string(html, False, options=options, configuration=config) 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=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)
def static_analyzer_ios(request, api=False): """Module that performs iOS IPA/ZIP Static Analysis""" try: print("[INFO] iOS Static Analysis Started") if api: file_type = request.POST['scan_type'] checksum = request.POST['hash'] rescan = str(request.POST.get('re_scan', 0)) filename = request.POST['file_name'] else: file_type = request.GET['type'] checksum = request.GET['checksum'] rescan = str(request.GET.get('rescan', 0)) filename = request.GET['name'] md5_match = re.match('^[0-9a-f]{32}$', checksum) if ((md5_match) and (filename.lower().endswith('.ipa') or filename.lower().endswith('.zip') ) and (file_type in ['ipa', 'ios']) ): app_dict = {} app_dict["directory"] = settings.BASE_DIR # BASE DIR app_dict["file_name"] = filename # APP ORGINAL NAME app_dict["md5_hash"] = 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( file_size(app_dict["app_path"])) + 'MB' # FILE SIZE app_dict["sha1"], app_dict["sha256"] = hash_gen( 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"], infoplist_dict.get("bin")) # 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) context['VT_RESULT'] = None if settings.VT_ENABLED: vt = VirusTotal.VirusTotal() context['VT_RESULT'] = vt.get_result( os.path.join(app_dict['app_dir'], app_dict[ 'md5_hash']) + '.ipa', app_dict['md5_hash'] ) template = "static_analysis/ios_binary_analysis.html" if api: return context else: 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( file_size(app_dict["app_path"])) + 'MB' # FILE SIZE app_dict["sha1"], app_dict["sha256"] = hash_gen( app_dict["app_path"]) # SHA1 & SHA256 HASHES files, sfiles = ios_list_files( app_dict["app_dir"], app_dict["md5_hash"], False, 'ios') infoplist_dict = plist_analysis(app_dict["app_dir"], True) code_analysis_dic = ios_source_analysis( app_dict["app_dir"]) # 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" 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 or file type" if api: return print_n_send_error_response(request, msg, True) else: return print_n_send_error_response(request, msg, False) except Exception as exp: msg = str(exp) exp_doc = exp.__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 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 static_analyzer_ios(request, api=False): """Module that performs iOS IPA/ZIP Static Analysis.""" try: logger.info('iOS Static Analysis Started') if api: file_type = request.POST['scan_type'] checksum = request.POST['hash'] rescan = str(request.POST.get('re_scan', 0)) filename = request.POST['file_name'] else: file_type = request.GET['type'] checksum = request.GET['checksum'] rescan = str(request.GET.get('rescan', 0)) filename = request.GET['name'] md5_match = re.match('^[0-9a-f]{32}$', checksum) if ((md5_match) and (filename.lower().endswith('.ipa') or filename.lower().endswith('.zip')) and (file_type in ['ipa', 'ios'])): app_dict = {} app_dict['directory'] = settings.BASE_DIR # BASE DIR app_dict['file_name'] = filename # APP ORGINAL NAME app_dict['md5_hash'] = 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/') 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: logger.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_dict['bin_dir'] = os.path.join(app_dict['app_dir'], 'Payload/') app_dict['size'] = str(file_size( app_dict['app_path'])) + 'MB' # FILE SIZE app_dict['sha1'], app_dict['sha256'] = hash_gen( app_dict['app_path']) # SHA1 & SHA256 HASHES logger.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) app_dict['appstore'] = app_search(infoplist_dict.get('id')) bin_analysis_dict = binary_analysis( app_dict['bin_dir'], tools_dir, app_dict['app_dir'], infoplist_dict.get('bin')) # Saving to DB logger.info('Connecting to DB') if rescan == '1': logger.info('Updating Database...') update_db_entry_ipa(app_dict, infoplist_dict, bin_analysis_dict, files, sfiles) update_scan_timestamp(app_dict['md5_hash']) elif rescan == '0': logger.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) context['VT_RESULT'] = None if settings.VT_ENABLED: vt = VirusTotal.VirusTotal() context['VT_RESULT'] = vt.get_result( os.path.join(app_dict['app_dir'], app_dict['md5_hash']) + '.ipa', app_dict['md5_hash']) context['average_cvss'], context['security_score'] = score( context['bin_anal']) template = 'static_analysis/ios_binary_analysis.html' if api: return context else: 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: logger.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']) # ANALYSIS BEGINS - Already Unzipped logger.info('ZIP Already Extracted') app_dict['size'] = str(file_size( app_dict['app_path'])) + 'MB' # FILE SIZE app_dict['sha1'], app_dict['sha256'] = hash_gen( app_dict['app_path']) # SHA1 & SHA256 HASHES files, sfiles = ios_list_files(app_dict['app_dir'], app_dict['md5_hash'], False, 'ios') infoplist_dict = plist_analysis(app_dict['app_dir'], True) app_dict['appstore'] = app_search(infoplist_dict.get('id')) code_analysis_dic = ios_source_analysis( app_dict['app_dir']) # Firebase DB Check code_analysis_dic['firebase'] = firebase_analysis( list(set(code_analysis_dic['urls_list']))) # Saving to DB logger.info('Connecting to DB') if rescan == '1': logger.info('Updating Database...') update_db_entry_ios(app_dict, infoplist_dict, code_analysis_dic, files, sfiles) update_scan_timestamp(app_dict['md5_hash']) elif rescan == '0': logger.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) context['average_cvss'], context['security_score'] = score( context['insecure']) template = 'static_analysis/ios_source_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 or file type' if api: return print_n_send_error_response(request, msg, True) else: return print_n_send_error_response(request, msg, False) except Exception as exp: logger.exception('Error Perfroming Static Analysis') msg = str(exp) exp_doc = exp.__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, 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 static_analyzer_ios(request, api=False): """Module that performs iOS IPA/ZIP Static Analysis""" try: logger.info("iOS Static Analysis Started") if api: file_type = request.POST['scan_type'] checksum = request.POST['hash'] rescan = str(request.POST.get('re_scan', 0)) filename = request.POST['file_name'] else: file_type = request.GET['type'] checksum = request.GET['checksum'] rescan = str(request.GET.get('rescan', 0)) filename = request.GET['name'] md5_match = re.match('^[0-9a-f]{32}$', checksum) if ((md5_match) and (filename.lower().endswith('.ipa') or filename.lower().endswith('.zip') ) and (file_type in ['ipa', 'ios']) ): app_dict = {} app_dict["directory"] = settings.BASE_DIR # BASE DIR app_dict["file_name"] = filename # APP ORGINAL NAME app_dict["md5_hash"] = 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: logger.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( file_size(app_dict["app_path"])) + 'MB' # FILE SIZE app_dict["sha1"], app_dict["sha256"] = hash_gen( app_dict["app_path"]) # SHA1 & SHA256 HASHES logger.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) app_dict["appstore"] = app_search(infoplist_dict.get("id")) bin_analysis_dict = binary_analysis( app_dict["bin_dir"], tools_dir, app_dict["app_dir"], infoplist_dict.get("bin")) # Saving to DB logger.info("Connecting to DB") if rescan == '1': logger.info("Updating Database...") update_db_entry_ipa( app_dict, infoplist_dict, bin_analysis_dict, files, sfiles) update_scan_timestamp(app_dict["md5_hash"]) elif rescan == '0': logger.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) context['VT_RESULT'] = None if settings.VT_ENABLED: vt = VirusTotal.VirusTotal() context['VT_RESULT'] = vt.get_result( os.path.join(app_dict['app_dir'], app_dict[ 'md5_hash']) + '.ipa', app_dict['md5_hash'] ) context["average_cvss"], context[ "security_score"] = score(context["bin_anal"]) template = "static_analysis/ios_binary_analysis.html" if api: return context else: 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: logger.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 logger.info("ZIP Already Extracted") app_dict["size"] = str( file_size(app_dict["app_path"])) + 'MB' # FILE SIZE app_dict["sha1"], app_dict["sha256"] = hash_gen( app_dict["app_path"]) # SHA1 & SHA256 HASHES files, sfiles = ios_list_files( app_dict["app_dir"], app_dict["md5_hash"], False, 'ios') infoplist_dict = plist_analysis(app_dict["app_dir"], True) app_dict["appstore"] = app_search(infoplist_dict.get("id")) code_analysis_dic = ios_source_analysis( app_dict["app_dir"]) # Firebase DB Check code_analysis_dic['firebase'] = firebase_analysis( list(set(code_analysis_dic["urls_list"]))) # Saving to DB logger.info("Connecting to DB") if rescan == '1': logger.info("Updating Database...") update_db_entry_ios( app_dict, infoplist_dict, code_analysis_dic, files, sfiles) update_scan_timestamp(app_dict["md5_hash"]) elif rescan == '0': logger.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) context["average_cvss"], context[ "security_score"] = score(context["insecure"]) template = "static_analysis/ios_source_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 or file type" if api: return print_n_send_error_response(request, msg, True) else: return print_n_send_error_response(request, msg, False) except Exception as exp: msg = str(exp) exp_doc = exp.__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): 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 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 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/')