def clearResult(result_id): # Delete report_directory # remove <result_id> entry from reports.json report_info = core.get_result_info(result_id) if not report_info[0]: core.updatelog( 'No result found for analysis ID: {0}'.format(result_id)) return False analysis_dir = report_info[1]['report_directory'] reportids = core.reportids report_index = core.report_index # Check if there is a directory with the analysis id if not os.path.isdir(analysis_dir): core.updatelog( 'Could not find any directory with the given analysis ID: ' + result_id) else: try: core.updatelog('Deleting analysis directory: ' + analysis_dir) shutil.rmtree(analysis_dir) core.updatelog('Successfully deleted analysis directory') except Exception as e: core.updatelog( 'Something went wrong while deleting analysis directory: ' + str(e)) logging.error(traceback.format_exc()) # Check if there is any analysis id in the index if result_id not in str(reportids): core.updatelog( 'No analysis with the id {0} in analysis index file'.format( result_id)) #print(result_id) #print(str(reportids)) return False else: reports = reportids['reports'] for report in reports: if report['id'] == result_id: reports.remove(report) reportids['reports'] = reports core.reportids = reportids core.updatelog( 'Removed analysis {0} from index.. writing index to file'.format( result_id)) r = open(report_index, 'w+') r.write(json.dumps(reportids, indent=4, sort_keys=True)) r.close() core.updatelog('Analysis index written to file: ' + report_index) return True
def view(analysis_id): try: int(analysis_id.replace('EXA', '')) # throws exception if improper id passed analysis_info = core.get_result_info(analysis_id) if not analysis_info[0]: # Could not get analysis_info error_txt = 'Something went wrong while getting analysis info!<br>Error: ' + analysis_info[ 1] return render_template( 'error.html', error_title="Invalid Result ID", error_head="Invalid Result ID: {0}".format(analysis_id), error_txt=error_txt) analysis_path = analysis_info[1]['report_directory'].replace( '<reports_path>', core.reports_path) graph_data = os.path.join(analysis_path, 'graph.data') if os.path.isfile(graph_data): graph_data = open(graph_data, 'r') graph_data = graph_data.read() return render_template('graph.html', graph_data=graph_data) else: return render_template( 'error.html', error_title="Missing Graph File", error_head="Missing Graph File for Result ID: {0}".format( analysis_id), error_txt= 'ExtAnalysis could not find "grpah.data" file in the analysis report directory! Please re-analyze the extension' ) except: error_txt = 'There seems to be no result corresponding to the provided ID. Did you delete the result? or maybe you did some weird shit with the parameter?' return render_template( 'error.html', error_title="Invalid Result ID", error_head="Invalid Result ID: {0}".format(analysis_id), error_txt=error_txt)
def view(analysis_id, file_id): int(analysis_id.replace('EXA', '')) # throws exception if improper id passed int(file_id.replace('EXTAF', '')) analysis_info = core.get_result_info(analysis_id) if not analysis_info[0]: # Could not get analysis_info error_txt = 'Something went wrong while getting analysis info!<br>Error: ' + analysis_info[ 1] return render_template( 'error.html', error_title="Invalid Result ID", error_head="Invalid Result ID: {0}".format(analysis_id), error_txt=error_txt) analysis_path = analysis_info[1]['report_directory'].replace( '<reports_path>', core.reports_path) sources_file = os.path.join(analysis_path, 'source.json') if os.path.isfile(sources_file): # valid source s = open(sources_file, 'r') sources = json.loads(s.read()) try: file_info = sources[file_id] file_name = file_info['file_name'] file_location = file_info['location'] file_type = file_name.split('.')[-1] if file_type.endswith(('html', 'htm')): file_icon = 'html1.png' elif file_type.endswith('js'): file_icon = 'js1.png' elif file_type.endswith('css'): file_icon = 'css1.png' elif file_type.endswith( ('png', 'jpg', 'jpeg', 'bmp', 'tiff', 'svg')): file_icon = 'static1.png' elif file_type.endswith('json'): file_icon = 'json1.png' else: file_icon = 'other1.png' icon_url = url_for('static', filename='images/' + file_icon) file_icon = '<img src="' + icon_url + '">' file_type = ('javascript' if file_type == 'js' else file_type) try: fs = open(file_location, 'r', encoding='utf8') file_source = fs.read() file_size = str(os.path.getsize(file_location) >> 10) + ' KB' return render_template('source.html', file_name=file_name, file_source=file_source, file_id=file_id, file_location=file_location, file_type=file_type, file_size=file_size, file_icon=file_icon) except Exception as e: logging.error(traceback.format_exc()) return render_template( 'error.html', error_title="Error Accessing File", error_head="Problem while reading file source!", error_txt= 'Something went wrong while reading the file source... error: ' + str(e)) except: return render_template( 'error.html', error_title="Invalid File ID", error_head="Invalid File ID", error_txt= 'I could not find any file with the given file id... well either you tempered with the parameter or something went WRONG!' ) else: return render_template( 'error.html', error_title="Invalid Analysis ID", error_head="Invalid Analysis ID", error_txt= 'There seems to be no result corresponding to the provided ID. Did you delete the result? or maybe you did some weird shit with the parameter?' )
def view(query, allargs): if query == 'dlanalysis': try: extension_id = allargs.get('extid') saveas = "" try: saveas = allargs.get('savedir') if saveas == "" or saveas == " ": saveas = extension_id except Exception as e: print('Save name not specified') try: download_log = download_extension.download( extension_id, saveas) if download_log: aok = analysis.analyze(saveas + '.crx', 'Remote Google Chrome Extension') return (aok) else: return ( 'error: Something went wrong while downloading extension' ) except Exception as e: core.updatelog( 'Something went wrong while downloading extension: ' + str(e)) return ( 'error: Something went wrong while downloading extension, check log for more information' ) except Exception as e: core.updatelog('Something went wrong: ' + str(e)) return ( 'error: Something went wrong while downloading extension, check log for more information' ) elif query == 'firefoxaddon': try: addonurl = allargs.get('addonurl') try: download_log = download_extension.downloadFirefox(addonurl) if download_log: aok = analysis.analyze(download_log + '.xpi', 'Remote Firefox Addon') return (aok) else: return ( 'error: Something went wrong while downloading extension' ) except Exception as e: core.updatelog( 'Something went wrong while downloading extension: ' + str(e)) return ( 'error: Something went wrong while downloading extension, check log for more information' ) except Exception as e: core.updatelog('Something went wrong: ' + str(e)) return ( 'error: Something went wrong while downloading extension, check log for more information' ) elif query == 'results': reportids = core.reportids if reportids == {}: # Result index not loaded so let's load it and show em results core.updatelog('Reading report index and loading json') ridfile = core.report_index ridcnt = open(ridfile, 'r', encoding='utf8') ridcnt = ridcnt.read() reportids = json.loads(ridcnt) rd = "<table class='result-table' id='result-table'><thead><tr><th>Name</th><th>Version</th><th>Date</th><th>Actions</th></tr></thead><tbody>" for areport in reportids['reports']: report_name = areport['name'] report_id = areport['id'] report_date = areport['time'] report_version = areport['version'] rd += '<tr><td>' + report_name + '</td><td>' + report_version + '</td><td>' + report_date + '</td><td><button class="bttn-fill bttn-xs bttn-primary" onclick=viewResult(\'' + report_id + '\')><i class="fas fa-eye"></i> View</button> <button class="bttn-fill bttn-xs bttn-danger" onclick=deleteResult(\'' + report_id + '\')><i class="fas fa-trash"></i> Delete</button></td></tr>' return (rd + '</tbody></table><br>') elif query == 'getlocalextensions': try: browser = allargs.get('browser') if browser == 'googlechrome': import core.localextensions as localextensions lexts = localextensions.GetLocalExtensions() exts = "" exts = lexts.googlechrome() if exts != False and exts != [] and exts != None: return_html = "<table class='result-table' id='result-table'><thead><tr><th>Extension Name</th><th>Action</th></tr></thead><tbody>" for ext in exts: ext_info = ext.split(',') return_html += '<tr><td>' + ext_info[ 0] + '</td><td><button class="bttn-fill bttn-xs bttn-success" onclick="analyzeLocalExtension(\'' + ext_info[ 1].replace( '\\', '\\\\' ) + '\', \'googlechrome\')"><i class="fas fa-bolt"></i> Analyze</button></td></tr>' return (return_html + '</tbody></table>') else: return ( 'error: Something went wrong while getting local Google Chrome extensions! Check log for more information' ) elif browser == 'firefox': import core.localextensions as localextensions lexts = localextensions.GetLocalExtensions() exts = lexts.firefox() if exts != False and exts != [] and exts != None: return_html = "<table class='result-table' id='result-table'><thead><tr><th>Extension Name</th><th>Action</th></tr></thead><tbody>" for ext in exts: ext_info = ext.split(',') return_html += '<tr><td>' + ext_info[ 0] + '</td><td><button class="bttn-fill bttn-xs bttn-success" onclick="analyzeLocalExtension(\'' + ext_info[ 1].replace( '\\', '\\\\' ) + '\', \'firefox\')"><i class="fas fa-bolt"></i> Analyze</button></td></tr>' return (return_html + '</tbody></table>') else: return ( 'error: Something went wrong while getting local firefox extensions! Check log for more information' ) else: return ('error: Invalid Browser!') except Exception: logging.error(traceback.format_exc()) return ('error: Incomplete Query') elif query == 'analyzelocalextension': try: browser = allargs.get('browser') path_to_local = allargs.get('path') path = helper.fixpath(path_to_local) if browser == 'firefox' and os.path.isfile(path): # valid firefox extension import core.localextensions as localextensions analysis_stat = localextensions.analyzelocalfirefoxextension( path) return (analysis_stat) elif browser == 'googlechrome' and os.path.isdir(path): if os.path.isfile(os.path.join(path, 'manifest.json')): analysis_stat = analysis.analyze( path, 'Local Google Chrome Extension') return (analysis_stat) else: return ('error: Invalid Google Chrome Extension Directory') else: return ('error: Malformed Query') except Exception: logging.error(traceback.format_exc()) return ('error: Incomplete Query') elif query == 'deleteAll': ''' DELETES ALL RESULTS RESPONSE = SUCCESS / ERROR ''' import core.result as result delete_status = result.clearAllResults() if delete_status: return "success" else: return ( 'There were some errors while deleting all analysis reports... refer to log for more information' ) elif query == 'clearLab': ''' Deletes all the contents of lab RESPONSE = SUCCESS / ERROR ''' clear_lab = core.clear_lab() if clear_lab[0]: # Successful return (clear_lab[1]) else: # Unsuccessful return ('error: ' + clear_lab[1]) elif query == 'deleteResult': ''' DELETES A SPECIFIC RESULT PARAMETER = resultID RESPONSE = SUCCESS_MSG / 'error: ERROR_MSG' ''' try: result_id_to_delete = allargs.get('resultID') import core.result as result delete_status = result.clearResult(result_id_to_delete) if delete_status: return "success" else: return "Something went wrong while deleting result! Check log for more information" except Exception: return ('Invalid Query') elif query == 'vtDomainReport': try: domain = allargs.get('domain') analysis_id = allargs.get('analysis_id') ranalysis = core.get_result_info(analysis_id) if ranalysis[0]: # if ranalysis[0] is True then ranalysis[1] contains the details analysis_dir = ranalysis[1]['report_directory'] analysis_report = os.path.join(analysis_dir, 'extanalysis_report.json') if os.path.isfile(analysis_report): report = open(analysis_report, 'r') domains = json.loads(report.read())['domains'] for adomain in domains: if adomain['name'] == domain: vtjson = json.dumps(adomain['virustotal'], indent=4, sort_keys=False) #return_html = '<div id="vt_info"></div><script>var wrapper1 = document.getElementById("vt_info");var data = '+vtjson+' try {var data = JSON.parse(dataStr);} catch (e) {} var tree = jsonTree.create(data, wrapper1);tree.expand(function(node) { return node.childNodes.length < 2 || node.label === "phoneNumbers";});</script>' return vtjson return ('error: Domain info not found in analysis report!') else: return ('error: Analysis report for #{0} not found'.format( analysis_id)) else: # ranalysis[1] is the error msg when ranalysis[0] = False return ('error: ' + ranalysis[1]) except: logging.error(traceback.format_exc()) return ('error: Malformed api call') elif query == 'retirejsResult': ''' GET RETIREJS SCAN RESULTS FOR FILE REQUIRED PARAMETER: file = FILE_ID ''' try: file_id = allargs.get('file') analysis_id = allargs.get('analysis_id') ranalysis = core.get_result_info(analysis_id) if ranalysis[0]: # if ranalysis[0] is True then ranalysis[1] contains the details analysis_dir = ranalysis[1]['report_directory'] source_json = os.path.join(analysis_dir, 'source.json') if os.path.isfile(source_json): report = open(source_json, 'r') files = json.loads(report.read()) for _file in files: if _file == file_id: retirejs_result = files[_file]['retirejs_result'] if retirejs_result == []: ret = 'none' else: ret = json.dumps(retirejs_result, indent=4, sort_keys=False) return ret return ('error: File ID not found in report!') else: return ('error: Analysis report for #{0} not found'.format( analysis_id)) else: # ranalysis[1] is the error msg when ranalysis[0] = False return ('error: ' + ranalysis[1]) except: logging.error(traceback.format_exc()) return ('error: Malformed api call') elif query == 'whois': ''' GET WHOIS REPORT OF DOMAIN REQUIRES 'python-whois' module RESPONSE = HTML DIV WITH FORMATTED WHOIS INFO ''' try: domain = allargs.get('domain') try: import whois except: return ( "error: python-whois module not installed! install it using `pip3 install python-whois` or `pip3 install -r requirements.txt`" ) whois_result = whois.whois(domain) whois_html = '<div class="whois-data" style="overflow-y: scroll; max-height:500px; text-align: left;">' for data in whois_result: proper_data = data.replace('_', ' ').capitalize() if isinstance(whois_result[data], list): for subdata in whois_result[data]: whois_html += '<b style="color:#89ff00;">{0} : </b>{1}<br>'.format( proper_data, subdata) else: whois_html += '<b style="color:#89ff00;">{0} : </b>{1}<br>'.format( proper_data, whois_result[data]) whois_html += '</div>' if whois_result: return ( '<center><h4>Whois Results For {0}</h4></center><br>{1}'. format(domain, whois_html)) else: return ( "error: Something went wrong while checking whois information of: " + domain) except Exception: logging.error(traceback.format_exc()) return ('error: Invalid Query') elif query == 'geoip': ''' GEO-IP LOOKUP OF AN IP ADDRESS PARAMETERS -> IP = CONTAINS IP ADDRESS TO BE LOOKED UP RETURNS A HTML TO BE SHOWN ''' try: ip_address = allargs.get('ip') geo_ip = scan.geoip(ip_address) if geo_ip[0]: gip = geo_ip[1] rethtml = '<div class="whois-data" style="overflow-y: scroll; max-height:500px; text-align: left;">' for g in gip: name = str(g).replace('_', ' ').capitalize() val = str(gip[g]) rethtml += '<b style="color:#89ff00;">{0} : </b>{1}<br>'.format( name, val) rethtml += '</div>' return ( '<center><h4>Geo-IP Lookup Results For {0}</h4></center><br>{1}' .format(ip_address, rethtml)) else: # in case of geo_ip[0] being false element 1 has the error msg return ('error: ' + geo_ip[1]) except Exception as e: logging.error(traceback.format_exc()) return ('error: Invalid Query') elif query == 'HTTPHeaders': ''' HTTP HEADERS OF AN URL PARAMETERS -> URL -> BASE64 ENCODED URL RETURNS HTML ''' try: url = allargs.get('url') url = base64.b64decode(url).decode('ascii') headers_status = scan.http_headers(url) if headers_status[0]: rethtml = '<div class="whois-data" style="overflow-y: scroll; max-height:500px; text-align: left;">' headers = headers_status[1] for header in headers: hval = headers[header] rethtml += '<b style="color:#89ff00;">{0} : </b>{1}<br>'.format( header, hval) rethtml += '</div>' return ( '<center><h4>Showing HTTP Headers of: {0}</h4></center><br>{1}' .format(url, rethtml)) else: return ('error: ' + headers_status[1]) except Exception as e: logging.error(traceback.format_exc()) return ('error: Invalid Query') elif query == 'SourceCode': ''' GET SOURCE CODE OF AN URL PARAMETERS -> URL -> BASE64 ENCODED URL RETURNS HTML ''' try: url = allargs.get('url') rurl = base64.b64decode(url).decode('ascii') headers_status = scan.source_code(rurl) if headers_status[0]: rethtml = '<textarea id="src_code" class="source_code" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">' headers = headers_status[1] rethtml += headers rethtml += '</textarea><br><br><center><a href="{0}" target="_blank" class="start_scan"><i class="fas fa-external-link-alt"></i> View Full Screen</a>'.format( '/source-code/' + url) return ('<center><h4>Source Code of: {0}</h4></center><br>{1}'. format(rurl, rethtml)) else: return ('error: ' + headers_status[1]) except Exception as e: logging.error(traceback.format_exc()) return ('error: Invalid Query') elif query == 'clearlogs': ''' CLEARS LOG ''' core.clearlog() return ('Logs cleared successfully!') elif query == 'changeReportsDir': ''' CHANGES THE REPORT DIRECTORY RESPONSE = SUCCESS / 'error: ERROR_MSG' ''' try: newpath = allargs.get('newpath') if os.path.isdir(newpath): # valid directory.. let's get the absolute path and set it absolute_path = os.path.abspath(newpath) import core.settings as settings change = settings.changedir(absolute_path) if change[0]: return (change[1]) else: return ('error: ' + change[1]) else: return ('error: Invalid directory path!') except: logging.error(traceback.format_exc()) return ('error: Invalid request for directory change!') elif query == 'changeVTapi': ''' CHANGE VIRUSTOTAL API RESPONSE = SUCCESS_MSG / 'error: ERROR_MSG' ''' try: new_api = allargs.get('api') import core.settings as settings change = settings.change_vt_api(new_api) if change[0]: return (change[1]) else: return ('error: ' + change[1]) except: logging.error(traceback.format_exc()) return ('error: Invalid request!') elif query == 'changelabDir': ''' CHANGES THE LAB DIRECTORY RESPONSE = SUCCESS / 'error : ERROR_MSG' ''' try: newpath = allargs.get('newpath') if os.path.isdir(newpath): # valid directory.. let's get the absolute path and set it absolute_path = os.path.abspath(newpath) import core.settings as settings change = settings.changelabdir(absolute_path) if change[0]: return (change[1]) else: return ('error: ' + change[1]) else: return ('error: Invalid directory path!') except: logging.error(traceback.format_exc()) return ('error: Invalid request for directory change!') elif query == 'updateIntelExtraction': ''' UPDATES INTELS TO BE EXTRACTED RESPONSE = SUCCESS_MSG / 'error: ' + ERROR_MSG ''' try: # Create the dict with all values and keys parameters = {} parameters["extract_comments"] = str( allargs.get('extract_comments')) parameters["extract_btc_addresses"] = str( allargs.get('extract_btc_addresses')) parameters["extract_base64_strings"] = str( allargs.get('extract_base64_strings')) parameters["extract_email_addresses"] = str( allargs.get('extract_email_addresses')) parameters["extract_ipv4_addresses"] = str( allargs.get('extract_ipv4_addresses')) parameters["extract_ipv6_addresses"] = str( allargs.get('extract_ipv6_addresses')) parameters["ignore_css"] = str(allargs.get('ignore_css')) import core.settings as settings status_code = settings.update_settings_batch(parameters) # 0 = failed, 1 = success, 2 = some updated some not! if status_code == '0': return ( 'error: Settings could not be updated! Check log for more information' ) elif status_code == '1': return ( 'Settings updated successfully... Please restart ExtAnalysis for them to take effect!' ) elif status_code == '2': return ( 'Some settings were updated and some were not... Please restart ExtAnalysis for them to take effect!' ) else: return ( 'error: Invalid response from "update_settings_batch". please report it here: https://github.com/Tuhinshubhra/ExtAnalysis/issues/new' ) except: logging.error(traceback.format_exc()) return ('error: Incomplete Request!') else: return ('error: Invalid Query!')
def view(analysis_id): # so the result ids are in this format : EXA<some digits> so we can try to replace 'EXTA' and convert the rest to int if it passes it's a valid type try: int(analysis_id.replace('EXA', '')) # Check analysis_info = core.get_result_info(analysis_id) if not analysis_info[0]: # Could not get analysis_info error_txt = 'Something went wrong while getting analysis info!<br>Error: ' + analysis_info[ 1] return render_template( 'error.html', error_title="Invalid Result ID", error_head="Invalid Result ID: {0}".format(analysis_id), error_txt=error_txt) else: result_directory = analysis_info[1]['report_directory'].replace( '<reports_path>', core.reports_path) if os.path.isdir(result_directory): # result directory found let's check for all necessary files graph_file = os.path.join(result_directory, 'graph.data') report_json = os.path.join(result_directory, 'extanalysis_report.json') source_file = os.path.join(result_directory, 'source.json') if all([ os.path.isfile(the_file) for the_file in [graph_file, report_json, source_file] ]): core.updatelog('Viewing Analysis {0}'.format(analysis_id)) graph_data = open(graph_file, 'r') graph_data = graph_data.read() source_data = open(source_file, 'r') source_data = json.loads(source_data.read()) report_data = open(report_json, 'r') report_data = json.loads(report_data.read()) # prepare data to be sent to result page basic_info_t = [ report_data['name'], report_data['version'], report_data['author'], report_data['description'], analysis_info[1]['time'] ] # extension type extension_type = report_data['type'] # URL Table if report_data['urls'] != []: urls_table = '<table class="result-table" id="urls-table"><thead><tr><th>URL</th><th>Domain</th><th>File</th><th>Actions</th></tr></thead><tbody>' extjs_table = '<table class="result-table" id="extjs-table"><thead><tr><th>URL</th><th>Domain</th><th>File</th><th>Actions</th></tr></thead><tbody>' done_urls = [] done_ejss = [] urls_count = 0 extjs_count = 0 for aurl in report_data['urls']: if aurl['url'].endswith('.js'): if aurl['url'] not in done_ejss: done_ejss.append(aurl['url']) aurl_href = '<a href="{0}" class="ext_url" target="_blank"><i class="fas fa-external-link-alt" style="font-size:12px;"></i> {0}</a>'.format( aurl['url']) extjs_table += '<tr><td>' + aurl_href + '</td>' b64url = "'" + base64.b64encode( aurl['url'].encode( 'ascii', 'ignore')).decode('ascii') + "'" extjs_table += '<td>{0}</td><td>{1}</td>'.format( aurl['domain'], aurl['file']) extjs_table += '<td><button class="bttn-fill bttn-xs bttn-primary" onclick=whois(\'{1}\')><i class="fab fa-searchengin"></i> WHOIS</button> <button class="bttn-fill bttn-xs bttn-success" onclick="getSource({0})"><i class="fas fa-code"></i> Source</button> <button class="bttn-fill bttn-xs bttn-danger" onclick="getHTTPHeaders({0})"><i class="fas fa-stream"></i> HTTP Headers</button></td></tr>'.format( b64url, aurl['url']) extjs_count += 1 else: if aurl['url'] not in done_urls: done_urls.append(aurl['url']) aurl_href = '<a href="{0}" class="ext_url" target="_blank"><i class="fas fa-external-link-alt" style="font-size:12px;"></i> {0}</a>'.format( aurl['url']) urls_table += '<tr><td>' + aurl_href + '</td>' urls_table += '<td>{0}</td><td>{1}</td>'.format( aurl['domain'], aurl['file']) b64url = "'" + base64.b64encode( aurl['url'].encode( 'ascii', 'ignore')).decode('ascii') + "'" urls_table += '<td><button class="bttn-fill bttn-xs bttn-primary" onclick=whois(\'{1}\')><i class="fab fa-searchengin"></i> WHOIS</button> <button class="bttn-fill bttn-xs bttn-success" onclick="getSource({0})"><i class="fas fa-code"></i> Source</button> <button class="bttn-fill bttn-xs bttn-danger" onclick="getHTTPHeaders({0})"><i class="fas fa-stream"></i> HTTP Headers</button></td></tr>'.format( b64url, aurl['url']) urls_count += 1 if done_urls != []: urls_table += '</tbody></table>' else: urls_table = '<h3 class="nothing"> No URLs Found </h3>' if done_ejss != []: extjs_table += '</tbody></table>' else: extjs_table = '<h3 class="nothing"> No External JavaScript Found in any files! </h3>' else: urls_table = '<h3 class="nothing"> No URLs Found </h3>' extjs_table = '<h3 class="nothing"> No External JavaScript Found in any files! </h3>' extjs_count = 0 urls_count = 0 # Domains div if report_data['domains'] != []: domains_table = '<table class="result-table" id="domains-table"><thead><tr><th>Country</th><th>Domain</th><th>IP Address</th><th>Virustotal Score</th><th>Actions</th></tr></thead><tbody>' for domain in report_data['domains']: domain_flag = helper.fixpath( core.path + '/static/images/flags/' + domain['country_code'] + '.png') if os.path.isfile(domain_flag): flag_path = url_for('static', filename='images/flags/' + domain['country_code'] + '.png') else: flag_path = url_for( 'static', filename='images/flags/unknown.png') country_html = '<img src="{0}" class="country_flag"> {1}'.format( flag_path, domain['country']) domains_table += '<tr><td>{4}</td><td>{0}</td><td>{2}</td><td>{1}</td><td><button class="bttn-fill bttn-xs bttn-danger" onclick=whois("{0}")><i class="fab fa-searchengin"></i> WHOIS</button> <button class="bttn-fill bttn-xs bttn-primary" onclick="domainvt(\'{0}\', \'{3}\')"><i class="fas fa-hourglass-end"></i> VT Report</button> <button class="bttn-fill bttn-xs bttn-success" onclick=geoip("{2}")><i class="fas fa-globe-americas"></i> Geo-IP Lookup</button></td></tr>'.format( domain['name'], '0/66', domain['ip'], analysis_id, country_html) domains_table += '</tbody></table>' else: domains_table = '<h3 class="nothing"> No Domains Extracted! </h3>' unique_domains = len(report_data['domains']) # Permissions div containing all permissions accordions permissions_div = "" for perm in report_data['permissions']: #perm_html = '<div class="perm"><div class="perm-name">{0}</div> <div class="perm-desc">{1}</div> <div class="perm-warn">{2}</div></div>'.format(perm['name'], perm['description'], (perm['warning'] if perm['warning'] != 'na' else '')) perm_html = '<div class="accordion"><div class="accordion__item"><div class="accordion__question">{0} {1} <div class="risk-pill {4}">{4}</div></div><div class="accordion__answer">{2} <div class="warning"> {3} </div></div></div></div>'.format( perm['badge'], helper.escape(perm['name']), perm['description'], (perm['warning'] if perm['warning'] != 'na' else ''), perm['risk']) permissions_div += perm_html permissions_count = len(report_data['permissions']) # table consisting of all the viewable source files files_table = '<table class="result-table" id="files-table"><thead><tr><th>File Name</th><th>Path</th><th>Size</th><th>Actions</th></tr></thead><tbody>' for file_info in source_data: file_name = source_data[file_info]['file_name'] rel_path = source_data[file_info]['relative_path'] file_id = source_data[file_info]['id'] file_size = source_data[file_info]['file_size'] file_action = '<button class="bttn-fill bttn-xs bttn-primary" onclick="viewfile(\'' + analysis_id + '\', \'' + file_id + '\')"><i class="fas fa-code"></i> View Source</button>' if file_name.endswith('.js'): # Add button for viewing retirejs vulnerability scan results file_action += ' <button class="bttn-fill bttn-xs bttn-danger" onclick="retirejsResult({0}, {1}, {2})"><i class="fas fa-spider"></i> Vulnerabilities</button>'.format( "'" + file_id + "'", "'" + analysis_id + "'", "'" + file_name + "'") file_type = helper.fixpath(core.path + '/static/images/' + file_name.split('.')[-1] + '1.png') if os.path.isfile(file_type): file_type = file_name.split('.')[-1] + '1.png' else: file_type = 'other1.png' file_type = url_for('static', filename='images/' + file_type) file_type = '<img src="{0}" class="ft_icon">'.format( file_type) file_html = "<tr><td>{2} {0}</td><td>{1}</td><td>{4}</td><td>{3}</td></tr>".format( file_name, rel_path, file_type, file_action, file_size) files_table += file_html files_table += '</tbody></table>' # table consisting of ipv6 and ipv4 addresses if report_data['ipv4_addresses'] == [] and report_data[ 'ipv6_addresses'] == []: ips_table = '<h3 class="nothing">No IPv4 or IPv6 addresses found!</h3>' else: ips_table = '<table class="result-table" id="ips_table"><thead><tr><th>IP Address</th><th>Type</th><th>File</th></tr></thead><tbody>' for ip in report_data['ipv4_addresses']: ips_table += '<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>'.format( ip['address'], 'IPv4', ip['file']) for ip in report_data['ipv6_addresses']: ips_table += '<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>'.format( ip['address'], 'IPv6', ip['file']) ips_table += '</tbody></table>' # table consisting of emails if report_data['emails'] != []: mails_table = '<table class="result-table" id="mails_table"><thead><tr><th>Email Address</th><th>File</th></tr></thead><tbody>' for mail in report_data['emails']: mails_table += '<tr><td>{0}</td><td>{1}</td></tr>'.format( mail['mail'], mail['file']) mails_table += '</tbody></table>' else: mails_table = '<h3 class="nothing">No email addresses found in any of the files!</h3>' # table containing btc addresses if report_data['bitcoin_addresses'] != []: btc_table = '<table class="result-table" id="btc_table"><thead><tr><th>BTC Address</th><th>File</th></tr></thead><tbody>' for mail in report_data['bitcoin_addresses']: btc_table += '<tr><td>{0}</td><td>{1}</td></tr>'.format( mail['address'], mail['file']) btc_table += '</tbody></table>' else: btc_table = '<h3 class="nothing">No Bitcoin Address found!</h3>' # table containing comments if report_data['comments'] != []: comments_table = '<table class="result-table" id="comments_table"><thead><tr><th>Comment</th><th>File</th></tr></thead><tbody>' for comment in report_data['comments']: comments_table += '<tr><td>{0}</td><td>{1}</td></tr>'.format( helper.escape(comment['comment']), comment['file']) comments_table += '</tbody></table>' else: comments_table = '<h3 class="nothing">No comments found in any js/html/css files!</h3>' # table containing base64 encoded strings if report_data['base64_strings'] != []: base64_table = '<table class="result-table" id="base64_table"><thead><tr><th>Base64 Encoded String</th><th>File</th></tr></thead><tbody>' for b64 in report_data['base64_strings']: base64_table += '<tr><td>{0}</td><td>{1}</td></tr>'.format( b64['string'], b64['file']) base64_table += '</tbody></table>' else: base64_table = '<h3 class="nothing">No base64 encoded string found in any js/html/css files!</h3>' manifest_content = json.dumps(report_data['manifest']) ''' Files count ''' js_files_count = len(report_data['files']['js']) css_files_count = len(report_data['files']['css']) html_files_count = len(report_data['files']['html']) json_files_count = len(report_data['files']['json']) other_files_count = len(report_data['files']['other']) static_files_count = len(report_data['files']['static']) return render_template( "report.html", extension_type=extension_type, graph_data=graph_data, basic_info=basic_info_t, urls_table=urls_table, permissions_div=permissions_div, analysis_id=analysis_id, files_table=files_table, manifest_content=manifest_content, domains_table=domains_table, base64_table=base64_table, comments_table=comments_table, ips_table=ips_table, btc_table=btc_table, mails_table=mails_table, extjs_table=extjs_table, urls_count=urls_count, extjs_count=extjs_count, permissions_count=permissions_count, unique_domains=unique_domains, js_files_count=js_files_count, css_files_count=css_files_count, html_files_count=html_files_count, json_files_count=json_files_count, other_files_count=other_files_count, static_files_count=static_files_count) else: error_txt = 'All the result files are not found.. Try scanning the extension again! and don\'t mess with the result files this time' return render_template('error.html', error_title="Malformed Result", error_head="Incomplete Result", error_txt=error_txt) else: error_txt = 'The result directory corresponding to result id {0} could not be found... hence ExtAnalysis has nothing to show'.format( analysis_id) return render_template( 'error.html', error_title="Result Directory Not Found", error_head="Result Directory Not Foundt", error_txt=error_txt) except: logging.error(traceback.format_exc()) return render_template( 'error.html', error_title="Invalid Result ID", error_head="Invalid Result ID", error_txt= 'There seems to be no result corresponding to the provided ID. Did you delete the result? or maybe you did some weird shit with the parameter?' )