Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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?'
        )
Пример #4
0
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!')
Пример #5
0
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?'
        )