Exemplo n.º 1
0
    def show(self):
        """Display selected vulnerabilities"""
        results = self.get_results()

        if not results:
            logger.warning('No vulnerability to display')
        else:
            data = list()
            columns = [
                'IP',
                'Service',
                'Port',
                'Proto',
                'Vulnerability',
            ]
            for r in results:
                data.append([
                    r.service.host.ip,
                    r.service.name,
                    r.service.port,
                    {
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(r.service.protocol),
                    StringUtils.wrap(r.name, 140),
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 2
0
    def show(self):
        """Display selected results"""
        results = self.get_results()

        Output.title2('Attacks results:')

        if not results:
            logger.warning('No results to display')
        else:
            data = list()
            columns = [
                'IP',
                'Port',
                'Proto',
                'Service',
                'Check id',
                'Category',
                'Check',
                '# Commands run',
            ]
            for r in results:
                data.append([
                    r.service.host.ip,
                    r.service.port,
                    {
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(r.service.protocol),
                    r.service.name,
                    r.id,
                    r.category,
                    r.check,
                    len(r.command_outputs),
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 3
0
    def show_products(self, filter_service=None):
        """
        Display supported products in a table

        :param list filter_service: Filter on services (default: all)
        """
        data = list()
        columns = [
            'Type',
            'Product Names',
        ]
        services = self.list_services() if filter_service is None else [
            filter_service
        ]
        for service in services:
            products = self.services[service]['products']
            for product_type in products:
                names = sorted(
                    self.services[service]['products'][product_type])
                names = StringUtils.wrap(', '.join(names), 100)

                data.append([product_type, names])

        Output.title1('Available products for {filter}'.format(
            filter='all services' if filter_service is None \
                   else 'service ' + filter_service))

        if not data:
            logger.warning('No product')
        else:
            Output.table(columns, data)
Exemplo n.º 4
0
    def show(self):
        """Display selected credentials"""
        results = self.get_results()

        if not results:
            logger.warning('No credential to display')
        else:
            data = list()
            columns = [
                'IP',
                'Hostname',
                'Service',
                'Port',
                'Proto',
                'Type',
                'Username',
                'Password',
                'URL',
                'Comment',
            ]
            for r in results:
                data.append([
                    r.service.host.ip,
                    r.service.host.hostname \
                        if r.service.host.hostname != str(r.service.host.ip) else '',
                    r.service.name,
                    r.service.port,
                    {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(r.service.protocol),
                    r.type or '',
                    '<empty>' if r.username == '' else r.username,
                    {'': '<empty>', None: '<???>'}.get(r.password, r.password),
                    StringUtils.wrap(r.service.url, 50),
                    StringUtils.wrap(r.comment, 50),
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 5
0
    def show_categories(self, filter_service=None):
        """
        Show list of categories of checks for the given service or all services
        :param filter_service: None or given service
        :return: None
        """
        data = list()
        columns = [
            'Category',
            'Services',
        ]
        services = self.list_services() if filter_service is None else [
            filter_service
        ]
        svcbycat = defaultdict(list)
        for service in services:
            for category in self.services[service]['checks'].categories:
                svcbycat[category].append(service)

        for category in svcbycat:
            data.append([
                category,
                StringUtils.wrap(', '.join(svcbycat[category]), 100)
            ])

        Output.table(columns, data)
Exemplo n.º 6
0
    def show(self, filter_service=None):
        """
        Display information about supported attack profiles

        :param str filter_service: Service name to filter with (default: no filter)
        """

        data = list()
        columns = [
            'Profile',
            'Description',
        ]

        for p in self.profiles:
            #print(p.checks)
            if not filter_service or p.is_service_supported(filter_service):
                data.append([
                    Output.colored(p.name, attrs='bold'),
                    StringUtils.wrap(p.description, 120)
                ])

        if filter_service:
            service = 'for service {}'.format(filter_service.upper())
        else:
            service = ''
        Output.title1('Attack Profiles {service}'.format(service=service))
        Output.table(columns, data, hrules=False)

        if not filter_service:
            print
            Output.print('Run "info --attack-profiles <service>" to see the attack ' \
                'profiles supported for a given service.')
Exemplo n.º 7
0
    def show(self):
        """Display selected hosts"""
        results = self.get_results()

        if not results:
            logger.warning('No host to display')
        else:
            data = list()
            columns = [
                'IP',
                'Hostname',
                'OS',
                'Type',
                'Vendor',
                'Comment',
                'TCP',
                'UDP',
            ]
            for r in results:
                data.append([
                    r.ip,
                    StringUtils.wrap(r.hostname, 45) if r.hostname != str(r.ip) else '',
                    StringUtils.wrap(r.os, 50),
                    r.type,
                    StringUtils.wrap(r.vendor, 30),
                    StringUtils.shorten(r.comment, 40),
                    r.get_nb_services(Protocol.TCP),
                    r.get_nb_services(Protocol.UDP),       
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 8
0
    def show_services(self, toolbox):
        """
        Display supported services in a table.

        :param Toolbox toolbox: Toolbox
        """
        data = list()
        columns = [
            'Service',
            'Default port',
            '# Tools',
            '# Checks',
        ]
        for service in self.list_services(multi=True):
            data.append([
                service,
                'N/A' if service == 'multi' else '{port}/{proto}'.format(
                    port  = self.services[service]['default_port'],
                    proto = self.services[service]['protocol']),
                '{nb_installed}/{nb_tools}'.format(
                    nb_installed = toolbox.nb_tools(filter_service=service,
                                                    only_installed=True),
                    nb_tools     = toolbox.nb_tools(filter_service=service)),
                'N/A' if service == 'multi' \
                      else self.services[service]['checks'].nb_checks(),
            ])

        Output.title1('Supported services')
        Output.table(columns, data, hrules=False)
Exemplo n.º 9
0
    def show(self):
        """Display selected specific options"""
        results = self.get_results()

        if not results:
            logger.warning('No specific option to display')
        else:
            data = list()
            columns = [
                'IP',
                'Hostname',
                'Service',
                'Port',
                'Proto',
                'Name',
                'Value',
            ]
            for r in results:
                data.append([
                    r.service.host.ip,
                    r.service.host.hostname \
                        if r.service.host.hostname != str(r.service.host.ip) else '',
                    r.service.name,
                    r.service.port,
                    {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(r.service.protocol),
                    r.name,
                    r.value,
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 10
0
 def show(self, highlight=None):
     """
     Display selected missions.
     :param str highlight: Name of the mission to highlight
     """
     results = self.get_results()
     if not results:
         logger.warning('No matching mission')
     else:
         data = list()
         columns = [
             'Mission',
             'Creation date',
             'Comment',
             '# Hosts',
             '# Services',
         ]
         for mission in results:
             color = 'light_green' if mission.name == highlight else None
             data.append([
                 Output.colored(mission.name, color=color),
                 Output.colored(str(mission.creation_date), color=color),
                 Output.colored(StringUtils.wrap(mission.comment, 50), color=color),
                 Output.colored(len(mission.hosts), color=color),
                 Output.colored(mission.get_nb_services(), color=color),                
             ])
         Output.table(columns, data, hrules=False)
Exemplo n.º 11
0
    def show(self):
        """Show selected products"""
        results = self.get_results()

        if not results:
            logger.warning('No product to display')
        else:
            data = list()
            columns = [
                'IP',
                'Hostname',
                'Service',
                'Port',
                'Proto',
                'Type',
                'Name',
                'Version',
            ]
            for r in results:
                data.append([
                    r.service.host.ip,
                    r.service.host.hostname \
                        if r.service.host.hostname != str(r.service.host.ip) else '',
                    r.service.name,
                    r.service.port,
                    {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(r.service.protocol),
                    r.type,
                    r.name,
                    r.version,
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 12
0
    def show_services(self, toolbox):
        """
        Show all supported services along with number of installed tools / total number
        :param toolbox: Toolbox object
        :return: None
        """
        data = list()
        columns = [
            'Service',
            'Default port',
            '# Tools',
            '# Checks',
        ]
        for service in self.list_services(multi=True):
            data.append([
                service,
                'N/A' if service == 'multi' else '{port}/{proto}'.format(
                    port=self.services[service]['default_port'],
                    proto=self.services[service]['protocol']),
                '{nb_installed}/{nb_tools}'.format(
                    nb_installed=toolbox.nb_tools_installed(service),
                    nb_tools=toolbox.nb_tools(service)),
                'N/A' if service == 'multi' else
                self.services[service]['checks'].nb_checks(),
            ])

        Output.title1('Supported services')
        Output.table(columns, data, hrules=False)
Exemplo n.º 13
0
    def show(self):
        """Display selected services"""
        results = self.get_results()

        if not results:
            logger.warning('No service to display')
        else:
            data = list()
            columns = [
                'id',
                'IP',
                #'Hostname',
                'Port',
                'Proto',
                'Service',
                'Banner',
                'URL',
                'Comment/Title',
                'Checks',
                'Creds',
                'Vulns',
            ]
            for r in results:
                # Creds numbers
                nb_userpass = r.get_nb_credentials(single_username=False)
                nb_usernames = r.get_nb_credentials(single_username=True)
                nb_creds = '{}{}{}'.format(
                    '{}'.format(Output.colored(str(nb_userpass),  color='green' \
                            if nb_userpass > 0 else None)) if nb_userpass > 0 else '',
                    '/' if nb_userpass > 0 and nb_usernames > 0 else '',
                    '{} usr'.format(Output.colored(str(nb_usernames), color='yellow' \
                            if nb_usernames > 0 else None)) if nb_usernames > 0 else '')
                nb_vulns = Output.colored(str(len(r.vulns)), color='green' \
                    if len(r.vulns) > 0 else None) if len(r.vulns) > 0 else ''

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

                data.append([
                    r.id,
                    r.host.ip,
                    #r.host.hostname,
                    r.port,
                    {
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(r.protocol),
                    r.name,
                    StringUtils.wrap(r.banner, 55),
                    StringUtils.wrap(r.url, 50),
                    StringUtils.shorten(comment, 40),
                    len(r.results),
                    nb_creds,
                    nb_vulns,
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 14
0
 def print_technos(self):
     """
     Display web technologies detected in a table.
     """
     if len(self.technos) > 0:
         data = list()
         columns = ['Name', 'Version']
         for t in self.technos:
             data.append([t['name'], t['version']])
         Output.table(columns, data, hrules=False)
     else:
         logger.warning('No technology detected')
    def __attack_target(self, id_, attack_progress):
        """
        Run checks against a given target
        :param id_: Number of the target (as displayed in "id" column in show_summary())
        """
        target = self.targets[id_ - 1]

        if target.get_http_headers():
            logger.info('HTTP Response headers:')
            for l in target.get_http_headers().splitlines():
                Output.print(l)
            print()

        if target.get_credentials():
            logger.info('Credentials set for this target:')
            data = list()
            columns = ['username', 'password']
            if target.get_service_name() == 'http': columns.append('auth-type')
            for c in target.get_credentials():
                username = '******' if c.username == '' else c.username
                if c.password is None:
                    password = '******'
                else:
                    password = '******' if c.password == '' else c.password

                line = [username, password]
                if target.get_service_name() == 'http': line.append(c.type)
                data.append(line)
            Output.table(columns, data, hrules=False)

        if target.get_specific_options():
            logger.info('Context-specific options set for this target:')
            data = list()
            columns = ['option', 'value']
            for o in target.get_specific_options():
                data.append([o.name, o.value])
            Output.table(columns, data, hrules=False)

        # TODO: add/edit specific options before run
        self.smartmodules_loader.call_start_method(target.service)

        service_checks = self.settings.services.get_service_checks(
            target.get_service_name())
        service_checks.run(target,
                           self.smartmodules_loader,
                           self.results_requester,
                           self.filter_categories,
                           self.filter_checks,
                           fast_mode=self.fast_mode,
                           attack_progress=attack_progress)
 def show_summary(self):
     """
     """
     data = list()
     columns = [
         'id',
         'IP',
         'Hostname',
         'Port',
         'Proto',
         'Service',
         'Banner',
         'URL',
     ]
     id_ = 1
     for target in self.targets:
         pointer_color = 'blue' if self.current_targetid == id_ else None
         pointer_attr = 'bold' if self.current_targetid == id_ else None
         data.append([
             Output.colored(
                 '>' +
                 str(id_) if self.current_targetid == id_ else str(id_),
                 color=pointer_color,
                 attrs=pointer_attr),
             Output.colored(target.get_ip(),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(target.get_host(),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(str(target.get_port()),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(target.get_protocol(),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(target.get_service_name(),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(StringUtils.wrap(target.get_banner(), 70),
                            color=pointer_color,
                            attrs=pointer_attr),
             Output.colored(StringUtils.wrap(target.get_url(), 50),
                            color=pointer_color,
                            attrs=pointer_attr),
         ])
         id_ += 1
     Output.table(columns, data, hrules=False)
    def show(self):
        results = self.get_results()

        if not results:
            logger.warning('No service to display')
        else:
            data = list()
            columns = [
                'id',
                'IP',
                #'Hostname',
                'Port',
                'Proto',
                'Service',
                'Banner',
                'URL',
                'Comment',
                'Checks',
                'Creds',
            ]
            for r in results:
                nb_userpass = r.get_nb_credentials(single_username=False)
                nb_usernames = r.get_nb_credentials(single_username=True)
                nb_creds = '{}{}{}'.format(
                    '{}'.format(Output.colored(str(nb_userpass),  color='green' \
                            if nb_userpass > 0 else None)) if nb_userpass > 0 else '',
                    '/' if nb_userpass > 0 and nb_usernames > 0 else '',
                    '{} users'.format(Output.colored(str(nb_usernames), color='yellow' \
                            if nb_usernames > 0 else None)) if nb_usernames > 0 else '')

                data.append([
                    r.id,
                    r.host.ip,
                    #r.host.hostname,
                    r.port,
                    {
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(r.protocol),
                    r.name,
                    StringUtils.wrap(r.banner, 65),
                    StringUtils.wrap(r.url, 50),
                    StringUtils.wrap(r.comment, 50),
                    len(r.results),
                    nb_creds,
                ])
            Output.table(columns, data, hrules=False)
Exemplo n.º 18
0
    def show_authentication_types(self, service='http'):
        """Display list of authentication types for HTTP."""
        Output.title1('Supported {service} authentication types'.format(
            service=service.upper()))

        if not self.is_service_supported(service, multi=False):
            logger.warning('The service {service} is not supported'.format(
                service=service))

        elif not self.services[service]['auth_types']:
            logger.warning('No special authentication type for this service')

        else:
            data = list()
            for t in sorted(self.services[service]['auth_types']):
                data.append([t])
            Output.table(['Authentication types'], data, hrules=False)
Exemplo n.º 19
0
    def show_search_results(self, string, nb_words=12):
        """
        Display command outputs search results.
        For good readability, only some words surrounding the search string are 
        displayed.

        :param str string: Search string (accepts wildcard "%")
        :param int nb_words: Number of words surrounding the search string to show
        """
        results = self.query.filter(CommandOutput.output.ilike('%'+string+'%'))
        if not results:
            logger.error('No result')
        else:
            Output.title2('Search results:')

            data = list()
            columns = [
                'IP',
                'Port',
                'Proto',
                'Service',
                'Check id',
                'Category',
                'Check',
                'Matching text',
            ]
            for r in results:
                match = StringUtils.surrounding_text(r.outputraw, string, nb_words)
                # There might have several matches in one command result (one row
                # per match)
                for m in match:
                    data.append([
                        r.result.service.host.ip,
                        r.result.service.port,
                        {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                            r.result.service.protocol),
                        r.result.service.name,
                        r.result.id,
                        r.result.category,
                        r.result.check,
                        StringUtils.wrap(m, 70),
                    ])

        print()
        Output.table(columns, data, hrules=False)
Exemplo n.º 20
0
    def show_toolbox(self, filter_service=None):
        """
        Display a table showing the content of the toolbox.

        :param str filter_service: Service name to filter with (default: no filter)
        """
        if filter_service is not None and filter_service not in self.services:
            return

        data = list()
        columns = [
            'Name',
            'Service',
            'Status/Update',
            'Description',
        ]

        services = self.services if filter_service is None else [
            filter_service
        ]
        for service in services:
            for tool in self.tools[service]:

                # Install status style
                if tool.installed:
                    status = Output.colored('OK | ' +
                                            tool.last_update.split(' ')[0],
                                            color='green')
                else:
                    status = Output.colored('Not installed', color='red')

                # Add line for the tool
                data.append([
                    tool.name,
                    tool.target_service,
                    status,
                    StringUtils.wrap(tool.description, 120),  # Max line length
                ])

        Output.title1('Toolbox content - {filter}'.format(
            filter='all services' if filter_service is None \
                   else 'service ' + filter_service))

        Output.table(columns, data, hrules=False)
Exemplo n.º 21
0
 def show_authentication_types(self, service):
     """
     Show list of authentication types for the given service.
     Actually relevant only for HTTP (for now ?)
     :param service: Service name
     :return: None
     """
     Output.title1('Supported {service} authentication types'.format(
         service=service.upper()))
     if not self.is_service_supported(service, multi=False):
         logger.warning('The service {service} is not supported'.format(
             service=service))
     elif not self.services[service]['auth_types']:
         logger.warning('No special authentication type for this service')
     else:
         data = list()
         for t in sorted(self.services[service]['auth_types']):
             data.append([t])
         Output.table(['Authentication types'], data, hrules=False)
    def show(self):
        results = self.get_results()

        if not results:
            logger.warning('No host to display')
        else:
            data = list()
            columns = [
                'IP',
                'Hostname',
                'OS',
                'Comment',
                '# Services',
            ]
            for r in results:
                data.append(
                    [r.ip, r.hostname, r.os, r.comment,
                     len(r.services)])
            Output.table(columns, data, hrules=False)
Exemplo n.º 23
0
    def show_results(self, service_id):
        service = self.sqlsess.query(Service).filter(
            Service.id == service_id).first()
        if not service:
            logger.error('Invalid service id')
        else:

            Output.title2('Attacks results:')
            Output.title2(
                'Target: host={ip}{hostname} | port={port}/{proto} | service {service}'
                .format(ip=service.host.ip,
                        hostname=' (' + service.host.hostname +
                        ')' if service.host.hostname else '',
                        port=service.port,
                        proto={
                            Protocol.TCP: 'tcp',
                            Protocol.UDP: 'udp'
                        }.get(service.protocol),
                        service=service.name))

            results = self.sqlsess.query(Result).filter(
                Result.service_id == service_id).all()
            if not results:
                logger.warning('No results to display')
            else:
                data = list()
                columns = [
                    'Check id',
                    'Category',
                    'Check',
                    '# Commands',
                ]
                for r in results:
                    data.append([
                        r.id,
                        r.category,
                        r.check,
                        len(r.command_outputs),
                    ])
                Output.table(columns, data, hrules=False)
Exemplo n.º 24
0
    def show_specific_options(self, filter_service=None):
        """
        Display supported specific options in a table.

        :param list filter_service: Filter on services (default: all)
        """
        data = list()
        columns = [
            'Option',
            'Service',
            'Supported values',
        ]
        services = self.list_services() if filter_service is None else [
            filter_service
        ]
        for service in services:
            options = self.services[service]['specific_options']
            for opt in options:
                if options[opt] == OptionType.BOOLEAN:
                    values = 'true, false'

                elif options[opt] == OptionType.LIST:
                    values = sorted(
                        self.services[service]['supported_list_options'][opt])
                    values = StringUtils.wrap(', '.join(values), 80)

                else:
                    values = '<anything>'
                data.append([opt, service, values])

        Output.title1('Available context-specific options for {filter}'.format(
            filter='all services' if filter_service is None \
                   else 'service ' + filter_service))

        if not data:
            logger.warning('No specific option')
        else:
            Output.table(columns, data, hrules=False)
Exemplo n.º 25
0
 def show(self):
     """Display a table with all the checks for the service."""
     data = list()
     columns = [
         'Name',
         'Category',
         'Description',
         'Tool used',
         #'# Commands',
     ]
     for category in self.categories:
         for check in self.checks[category]:
             color_tool = 'grey_19' if not check.tool.installed else None
             data.append([
                 check.name,
                 category,
                 check.description,
                 Output.colored(check.tool.name, color=color_tool),
                 #len(check.commands),
             ])
             
     Output.title1('Checks for service {service}'.format(service=self.service))
     Output.table(columns, data, hrules=False)
Exemplo n.º 26
0
    def print_context(self):
        """Print target's context information"""

        # Print credentials if available
        if self.get_credentials():
            logger.info('Credentials set for this target:')
            data = list()
            columns = ['Username', 'Password']
            if self.get_service_name() == 'http': columns.append('auth-type')
            for c in self.get_credentials():
                username = '******' if c.username == '' else c.username
                if c.password is None:
                    password = '******'
                else:
                    password = '******' if c.password == '' else c.password

                line = [username, password]
                if self.get_service_name() == 'http': line.append(c.type)
                data.append(line)
            Output.table(columns, data, hrules=False)

        # Print specific options if available
        if self.get_specific_options():
            logger.info('Context-specific options set for this target:')
            data = list()
            columns = ['Option', 'Value']
            for o in self.get_specific_options():
                data.append([o.name, o.value])
            Output.table(columns, data, hrules=False)

        # Print products if available
        if self.get_products():
            logger.info('Products detected for this target:')
            data = list()
            columns = ['Type', 'Name', 'Version']
            for p in self.get_products():
                data.append([p.type, p.name, p.version])
            Output.table(columns, data, hrules=False)

        # Print OS type if available
        if self.get_os():
            logger.info('OS type detected for this target: {os}'.format(
                os=self.get_os()))
Exemplo n.º 27
0
    def show_summary(self):
        """
        Display a table showing the summary of the attack scope.
        The table has a max size defined in lib.core.Config, to avoid displaying an
        unreadable summary when large amount of targets have been loaded.
        """
        if len(self.targets) > ATTACK_SUMMARY_TABLE_MAX_SIZE:
            id_min = self.current_targetid-2
            if id_min < 1:  
                id_min = 1

            id_max = self.current_targetid+ATTACK_SUMMARY_TABLE_MAX_SIZE-1 \
                -(self.current_targetid-id_min)
            if id_max > len(self.targets):
                id_min = id_min-(id_max-len(self.targets))
                id_max = len(self.targets)
        else:
            id_min = 1
            id_max = len(self.targets)

        data = list()
        columns = [
            'id',
            'IP',
            'Hostname',
            'Port',
            'Proto',
            'Service',
            'Banner',
            'URL',
        ]
        id_ = 1
        for target in self.targets:
            if id_ < id_min:
                id_ += 1
                continue
            if id_ > id_max:
                break

            pointer_color = 'blue'   if self.current_targetid == id_ else None
            pointer_attr  = 'bold' if self.current_targetid == id_ else None

            data.append([
                Output.colored('>'+str(id_) if self.current_targetid == id_ \
                               else str(id_), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(target.get_ip(), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(StringUtils.wrap(target.get_host(), 50), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(str(target.get_port()), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(target.get_protocol(), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(target.get_service_name(), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(StringUtils.wrap(target.get_banner(), 55), 
                    color=pointer_color, attrs=pointer_attr),
                Output.colored(StringUtils.wrap(target.get_url(), 50), 
                    color=pointer_color, attrs=pointer_attr),
            ])
            id_ += 1

        print()
        Output.table(columns, data, hrules=False)
        if len(self.targets) > ATTACK_SUMMARY_TABLE_MAX_SIZE:
            logger.info('Table has been truncated. Total number of loaded ' \
                'targets: {}'.format(len(self.targets)))
        print()