示例#1
0
    def __generate_sidebar_checks(self, service):
        """
        Generate the sidebar with the list of checks that have been run for the
        specified service.

        :param Service service: Service Model
        """
        req = ResultsRequester(self.sqlsession)
        req.select_mission(self.mission)

        # Filter on service id
        filter_ = Filter(FilterOperator.AND)
        filter_.add_condition(Condition(service.id, FilterData.SERVICE_ID))
        req.add_filter(filter_)
        results = req.get_results()

        html = ''
        i = 0
        for r in results:

            # Icon category
            icon = IconsMapping.get_icon_html('category', r.category)

            html += """
            <li{class_}>
                <a href="#{id}">{icon}{check}</a>
            </li>  
            """.format(class_=' class="active"' if i == 0 else '',
                       id=r.check,
                       icon=icon,
                       check=StringUtils.shorten(r.check, 28))
            i += 1

        return html
示例#2
0
    def __generate_results_page(self, service):
        """
        Generate HTML code that contains command outputs of all the checks that have
        been run for the specified service.

        :param Service service: Service Model
        """
        tpl = FileUtils.read(REPORT_TPL_DIR + '/results.tpl.html')

        # service_string = 'host <span class="font-weight-bold">{ip}</span> | ' \
        #     'port <span class="font-weight-bold">{port}/{proto}</span> | ' \
        #     'service <span class="font-weight-bold">{service}</span>'.format(
        #         ip=str(service.host.ip),
        #         port=service.port,
        #         proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
        #             service.protocol),
        #         service=service.name)

        tpl = tpl.replace('{{MISSION_NAME}}', self.mission)
        tpl = tpl.replace('{{SERVICE_ICON}}',
                          IconsMapping.get_icon_html('service', service.name))
        tpl = tpl.replace('{{SERVICE_IP}}', str(service.host.ip))
        tpl = tpl.replace('{{SERVICE_PORT}}', str(service.port))
        tpl = tpl.replace('{{SERVICE_PROTO}}', {
            Protocol.TCP: 'tcp',
            Protocol.UDP: 'udp'
        }.get(service.protocol))
        tpl = tpl.replace('{{SERVICE_NAME}}', service.name)
        tpl = tpl.replace('{{SIDEBAR_CHECKS}}',
                          self.__generate_sidebar_checks(service))
        tpl = tpl.replace('{{RESULTS}}',
                          self.__generate_command_outputs(service))

        return tpl
示例#3
0
    def __generate_table_products(self):
        """
        Generate the table with all products registered in the mission 
        """
        req = ProductsRequester(self.sqlsession)
        req.select_mission(self.mission)
        products = req.get_results()

        if len(products) == 0:
            html = """
            <tr class="notfound">
                <td colspan="7">No record found</td>
            </tr>
            """
        else:
            html = ''
            for product in products:

                # Service name
                service_name = IconsMapping.get_icon_html(
                    'service', product.service.name)
                service_name += str(product.service.name)

                html += """
                <tr>
                    <td>{ip}</td>
                    <td>{hostname}</td>
                    <td>{service}</td>
                    <td>{port} /{proto}</td>
                    <td class="font-weight-bold">{producttype}</td>
                    <td class="font-weight-bold text-green">{productname}</td>
                    <td class="font-weight-bold text-green">{productversion}</td>
                </tr>
                """.format(
                    ip=product.service.host.ip,
                    hostname=product.service.host.hostname \
                        if product.service.host.hostname != str(product.service.host.ip)\
                        else '',
                    service=service_name,
                    port=product.service.port,
                    proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                        product.service.protocol),
                    producttype=product.type,
                    productname=product.name,
                    productversion=product.version)

        return html
示例#4
0
    def __generate_table_options(self):
        """
        Generate the table with all context-specific options registered in the mission 
        """
        req = OptionsRequester(self.sqlsession)
        req.select_mission(self.mission)
        options = req.get_results()

        if len(options) == 0:
            html = """
            <tr class="notfound">
                <td colspan="6">No record found</td>
            </tr>
            """
        else:
            html = ''
            for option in options:

                # Service name
                service_name = IconsMapping.get_icon_html(
                    'service', option.service.name)
                service_name += str(option.service.name)

                html += """
                <tr>
                    <td>{ip}</td>
                    <td>{hostname}</td>
                    <td>{service}</td>
                    <td>{port} /{proto}</td>
                    <td class="font-weight-bold text-green">{optionname}</td>
                    <td class="font-weight-bold text-green">{optionvalue}</td>
                </tr>
                """.format(
                    ip=option.service.host.ip,
                    hostname=option.service.host.hostname \
                        if option.service.host.hostname != str(option.service.host.ip) \
                        else '',
                    service=service_name,
                    port=option.service.port,
                    proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                        option.service.protocol),
                    optionname=option.name,
                    optionvalue=option.value)

        return html
示例#5
0
    def __generate_table_vulns(self):
        """
        Generate the table with all vulnerabilities registered in the mission 
        """

        req = VulnsRequester(self.sqlsession)
        req.select_mission(self.mission)
        vulnerabilities = req.get_results()

        if len(vulnerabilities) == 0:
            html = """
            <tr class="notfound">
                <td colspan="4">No record found</td>
            </tr>
            """
        else:
            html = ''
            for vuln in vulnerabilities:

                # Service name
                service_name = IconsMapping.get_icon_html(
                    'service', vuln.service.name)
                service_name += str(vuln.service.name)

                html += """
                <tr>
                    <td>{ip}</td>
                    <td>{service}</td>
                    <td>{port} /{proto}</td>
                    <td>{vulnerability}</td>
                </tr>
                """.format(ip=vuln.service.host.ip,
                           service=service_name,
                           port=vuln.service.port,
                           proto={
                               Protocol.TCP: 'tcp',
                               Protocol.UDP: 'udp'
                           }.get(vuln.service.protocol),
                           vulnerability=vuln.name)

        return html
示例#6
0
    def __generate_command_outputs(self, service):
        """
        Generate HTML code with all command outputs for the specified service.

        :param Service service: Service Model
        """
        req = ResultsRequester(self.sqlsession)
        req.select_mission(self.mission)

        # Filter on service id
        filter_ = Filter(FilterOperator.AND)
        filter_.add_condition(Condition(service.id, FilterData.SERVICE_ID))
        req.add_filter(filter_)
        results = req.get_results()

        html = ''
        i = 0
        for r in results:

            # Icon category
            icon = IconsMapping.get_icon_html('category', r.category)

            # Description/Tool of check
            if service.name in self.settings.services:
                check = self.settings.services[
                    service.name]['checks'].get_check(r.check)
                if check is not None:
                    description = check.description
                    tool = check.tool.name
                else:
                    description = tool = ''

            html += """
            <div class="tab-pane{active}" id="{id}">
                <div class="container-fluid">
                    <div class="row">
                        <div class="col-lg-12">
                            <h1 class="title-page">{icon}{category} > {check}</h1>
                            <p class="check-description rounded">
                                <span class="mdi mdi-information-outline"></span> 
                                {description} 
                                (using tool: {tool}).
                            </p>
            """.format(active=' active' if i == 0 else '',
                       id=r.check,
                       icon=icon,
                       category=r.category,
                       check=r.check,
                       description=description,
                       tool=tool)

            for o in r.command_outputs:
                # Convert command output (with ANSI codes) to HTML
                conv = ansi2html.Ansi2HTMLConverter(inline=True,
                                                    scheme='solarized',
                                                    linkify=True)
                output = conv.convert(o.output)

                # Warning: ansi2html generates HTML document with <html>, <style>...
                # tags. We only keep the content inside <pre> ... </pre>
                m = re.search('<pre class="ansi2html-content">(?P<output>.*)' \
                    '</pre>\n</body>', output, re.DOTALL)
                if m:
                    output = m.group('output')

                    html += """
                    <pre class="cmdline rounded"># {cmdline}</pre>
                    <pre>{output}</pre>
                    """.format(cmdline=o.cmdline, output=output)

            html += """
                        </div>
                    </div>
                </div>
            </div>
            """
            i += 1

        return html
示例#7
0
    def __generate_table_credentials(self):
        """
        Generate the table with all credentials registered in the mission 
        """

        req = CredentialsRequester(self.sqlsession)
        req.select_mission(self.mission)
        credentials = req.get_results()

        if len(credentials) == 0:
            html = """
            <tr class="notfound">
                <td colspan="9">No record found</td>
            </tr>
            """
        else:
            html = ''
            for cred in credentials:

                # Service name
                service_name = IconsMapping.get_icon_html(
                    'service', cred.service.name)
                service_name += str(cred.service.name)

                # Add color to username/password
                username = '******' if cred.username == '' else cred.username
                username = '******'.format(
                    color='green' if cred.password is not None else 'yellow',
                    username=username)

                password = {
                    '': '&lt;empty&gt;',
                    None: '&lt;???&gt;'
                }.get(cred.password, cred.password)
                password = '******'.format(
                    color='green' if cred.password is not None else 'yellow',
                    password=password)

                html += """
                <tr>
                    <td>{ip}</td>
                    <td>{hostname}</td>
                    <td>{service}</td>
                    <td>{port} /{proto}</td>
                    <td>{type}</td>
                    <td class="font-weight-bold">{username}</td>
                    <td class="font-weight-bold">{password}</td>
                    <td>{url}</td>
                    <td>{comment}</td>
                </tr>
                """.format(
                    ip=cred.service.host.ip,
                    hostname=cred.service.host.hostname \
                        if cred.service.host.hostname != str(cred.service.host.ip)\
                        else '',
                    service=service_name,
                    port=cred.service.port,
                    proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                        cred.service.protocol),
                    type=cred.type or '',
                    username=username,
                    password=password,
                    url='<a href="{}" title="{}">{}</a>'.format(
                        cred.service.url, cred.service.url,
                        StringUtils.shorten(cred.service.url, 50)) \
                            if cred.service.url else '',
                    comment=cred.comment)

        return html
示例#8
0
    def __generate_table_hosts(self):
        """
        Generate the table with all hosts registered in the mission
        """
        req = HostsRequester(self.sqlsession)
        req.select_mission(self.mission)
        hosts = req.get_results()

        if len(hosts) == 0:
            html = """
            <tr class="notfound">
                <td colspan="10">No record found</td>
            </tr>
            """
        else:
            html = ''
            for host in hosts:

                # OS
                os = IconsMapping.get_icon_html('os_family', host.os_family)
                os += str(host.os)

                # Device type
                device_type = IconsMapping.get_icon_html(
                    'device_type', host.type)
                device_type += str(host.type)

                # Number of creds
                nb_userpass = host.get_nb_credentials(single_username=False)
                nb_usernames = host.get_nb_credentials(single_username=True)
                nb_creds = '{}{}{}'.format(
                    '<span class="text-green">{}</span>'.format(str(nb_userpass)) \
                        if nb_userpass > 0 else '',
                    '/' if nb_userpass > 0 and nb_usernames > 0 else '',
                    '<span class="text-yellow">{}</span>'.format(
                        str(nb_usernames)) if nb_usernames > 0 else '')

                # Number of vulns
                nb_vulns = host.get_nb_vulns()
                if nb_vulns > 0:
                    nb_vulns = '<span class="text-green">{}</span>'.format(
                        nb_vulns)
                else:
                    nb_vulns = ''

                html += """
                <tr>
                    <td class="font-weight-bold">{ip}</td>
                    <td>{hostname}</td>
                    <td>{os}</td>
                    <td>{type}</td>
                    <td>{vendor}</td>
                    <td>{comment}</td>
                    <td>{nb_tcp}</td>
                    <td>{nb_udp}</td>
                    <td>{nb_creds}</td>
                    <td>{nb_vulns}</td>
                </tr>
                """.format(ip=host.ip,
                           hostname=host.hostname
                           if host.hostname != str(host.ip) else '',
                           os=os,
                           type=device_type,
                           vendor=host.vendor,
                           comment=host.comment,
                           nb_tcp=host.get_nb_services(Protocol.TCP) or '',
                           nb_udp=host.get_nb_services(Protocol.UDP) or '',
                           nb_creds=nb_creds,
                           nb_vulns=nb_vulns)

        return html
示例#9
0
    def __generate_table_services(self):
        """
        Generate the table with all services registered in the mission
        """
        req = ServicesRequester(self.sqlsession)
        req.select_mission(self.mission)
        services = req.get_results()

        if len(services) == 0:
            html = """
            <tr class="notfound">
                <td colspan="12">No record found</td>
            </tr>
            """
        else:
            html = ''
            for service in services:

                hostname = service.host.hostname \
                    if service.host.ip != service.host.hostname else ''

                # Number of checks
                if len(service.results) > 0:
                    nb_checks = len(service.results)
                else:
                    nb_checks = '<span class="mdi mdi-window-close"></span>'

                # Number of creds
                nb_userpass = service.get_nb_credentials(single_username=False)
                nb_usernames = service.get_nb_credentials(single_username=True)
                nb_creds = '{}{}{}'.format(
                    '<span class="text-green">{}</span>'.format(str(nb_userpass)) \
                        if nb_userpass > 0 else '',
                    '/' if nb_userpass > 0 and nb_usernames > 0 else '',
                    '<span class="text-yellow">{}</span>'.format(
                        str(nb_usernames)) if nb_usernames > 0 else '')
                #if nb_creds == '':
                #    nb_creds = '<span class="mdi mdi-window-close"></span>'

                # Number of vulns
                if len(service.vulns) > 0:
                    nb_vulns = '<span class="text-green">{}</span>'.format(
                        len(service.vulns))
                else:
                    #nb_vulns = '<span class="mdi mdi-window-close"></span>'
                    nb_vulns = ''

                # Encrypted ? (SSL/TLS)
                enc = '<span class="mdi mdi-lock" title="SSL/TLS encrypted"></span>' \
                    if service.is_encrypted() else ''

                # Service name
                service_name = IconsMapping.get_icon_html(
                    'service', service.name)
                service_name += str(service.name)

                # Technologies
                technos = ''
                # For HTTP, respect a given order for technos for better readability
                if service.name == 'http':
                    product_types = (
                        'web-server',
                        'web-appserver',
                        # 'web-application-firewall', Displayed only in "web" tab
                        # for better readability
                        'web-cms',
                        'web-language',
                        'web-framework',
                        'web-jslib')
                    for t in product_types:
                        product = service.get_product(t)
                        if product:
                            technos += '<span class="badge badge-{type} badge-light">' \
                                '{name}{version}</span>'.format(
                                    type=t,
                                    name=product.name,
                                    version=' '+str(product.version) \
                                        if product.version else '')
                else:
                    for p in service.products:
                        technos += '<span class="badge badge-generic badge-light">' \
                            '{name}{version}</span>'.format(
                                type=p.type,
                                name=p.name,
                                version=' '+str(p.version) if p.version else '')

                # Col "Comment/Title" (title is for HTML title for HTTP)
                if service.html_title:
                    comment = service.html_title
                else:
                    comment = service.comment

                # Results HTML page name
                results = 'results-{ip}-{port}-{service}-{id}.html'.format(
                    ip=str(service.host.ip),
                    port=service.port,
                    service=service.name,
                    id=service.id)

                html += """
                <tr{clickable}>
                    <td class="font-weight-bold">{ip}</td>
                    <td>{hostname}</th>
                    <td class="font-weight-bold">{port} /{proto}</td>
                    <td>{service}</td>
                    <td>{enc}</td>
                    <td>{banner}</td>
                    <td>{technos}</td>
                    <td>{url}</td>
                    <td>{comment}</td>
                    <td>{nb_checks}</td>
                    <td>{nb_creds}</td>
                    <td>{nb_vulns}</td>
                </tr>
                """.format(
                    clickable=' class="clickable-row" data-href="{results}"'.format(
                        results=results) if len(service.results) > 0 else '',
                    ip=service.host.ip,
                    hostname=hostname,
                    port=service.port,
                    proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                        service.protocol),
                    service=service_name,
                    enc=enc,
                    banner=service.banner,
                    technos=technos,
                    url='<a href="{}" title="{}">{}</a>'.format(
                        service.url, service.url, StringUtils.shorten(service.url, 40)) \
                        if service.url else '',
                    comment=StringUtils.shorten(comment, 40),
                    nb_checks=nb_checks,
                    nb_creds=nb_creds,
                    nb_vulns=nb_vulns)

        return html