Ejemplo n.º 1
0
    def __init_with_url(self):
        """
        Initialize with an URL (when targeting HTTP).
        This method updates: URL, Hostname, IP, Port

        :raises TargetException: Exception raised if DNS lookup fails
        """
        self.service.url = WebUtils.add_prefix_http(self.service.url)
        self.service.url = WebUtils.remove_ending_slash(self.service.url)
        url = urlparse(self.service.url)

        if NetUtils.is_valid_ip(url.hostname):
            self.service.host.ip = url.hostname
            self.service.host.hostname = url.hostname  # updated in smart_check

        else:
            self.service.host.ip = NetUtils.dns_lookup(url.hostname)
            if not self.service.host.ip:
                raise TargetException('Unable to resolve {}'.format(
                    url.hostname))
            self.service.host.hostname = url.hostname

        if not self.service.port:
            self.service.port = WebUtils.get_port_from_url(self.service.url)
            if not NetUtils.is_valid_port(self.service.port):
                raise TargetException('Invalid port number {}'.format(
                    self.service.port))
    def __init_with_url(self):
        """
        """
        self.service.url = WebUtils.add_prefix_http(self.service.url)
        url = urlparse(self.service.url)

        if NetUtils.is_valid_ip(url.hostname):
            self.service.host.ip = url.hostname
            self.service.host.hostname = NetUtils.reverse_dns_lookup(url.hostname)
        else:
            self.service.host.ip = NetUtils.dns_lookup(url.hostname)
            self.service.host.hostname = url.hostname

        if not self.service.port:
            self.service.port = WebUtils.get_port_from_url(self.service.url)
Ejemplo n.º 3
0
    def __check_args_attack_single_target(self):
        """Check arguments for subcommand Attack > Single target options"""

        target = self.args.target_ip_or_url

        if not target:
            return True

        # Target specified is an URL
        if target.lower().startswith('http://') or target.lower().startswith(
                'https://'):
            self.args.target_mode = TargetMode.URL

            if self.args.service and self.args.service.lower() != 'http':
                logger.warning('URL only supported for HTTP service. ' \
                    'Automatically switch to HTTP')

            elif not self.args.service:
                logger.info('URL given as target, targeted service is HTTP')

            self.args.service = 'http'
            self.args.target_port = WebUtils.get_port_from_url(target)

        # Target specified is IP[:PORT] or HOSTNAME[:PORT]
        else:
            self.args.target_mode = TargetMode.IP  # Actually can be either IP or Hostname
            self.args.target_port = None
            s = target.split(':')
            self.args.target_ip_or_url = s[0]

            # Extract port
            if len(s) == 2:
                self.args.target_port = int(s[1])
                if not (0 <= self.args.target_port <= 65535):
                    logger.error('Target port is not valid. Must be in the ' \
                        'range [0-65535]')
                    return False

            elif len(s) > 2:
                logger.error('Incorrect target format. Must be either IP[:PORT] or ' \
                    'an URL')
                return False

            # Check or define targeted service and port
            if self.args.service:

                # Check if service is supported
                if not self.settings.services.is_service_supported(
                        self.args.service, multi=False):

                    logger.error('Service "{service}" is not supported. ' \
                        'Check "info --services".'.format(
                            service=self.args.service.upper()))
                    return False

                # Try to get default port if it is not specified
                if not self.args.target_port:
                    self.args.target_port = self.settings.services.get_default_port(
                        self.args.service)

                    if self.args.target_port:
                        logger.info('Default port for service {service} will be used: ' \
                            '{port}/{proto}'.format(
                                service = self.args.service,
                                port    = self.args.target_port,
                                proto   = self.settings.services.get_protocol(
                                    self.args.service)))

                    else:
                        logger.error('Target port is not specified and no default port' \
                            ' can be found for the service {service}'.format(
                                service=self.args.service))
                        return False

            # Try to get default service for provided port if not specified
            else:

                if not self.args.target_port:
                    logger.error(
                        'Target port and/or service must be specified')
                    return False

                else:
                    self.args.service = self.settings.services.get_service_from_port(
                        self.args.target_port)

                    if not self.args.service:
                        logger.error('Cannot automatically determine the target ' \
                            'service for port {port}/tcp, use --target IP:PORT ' \
                            'syntax'.format(port=self.args.target_port))
                        return False

                    logger.info('Automatic service detection based on target port: ' \
                        '{service}'.format(service=self.args.service))

        return True
    def add_url(self, url):
        matching_service = self.sqlsess.query(Service).join(Host).join(Mission)\
                                       .filter(Mission.name == self.current_mission)\
                                       .filter(Service.url == url).first()
        if matching_service:
            logger.warning('URL already present into database')
        else:

            # Parse URL: Get IP, hostname, port
            parsed = urlparse(url)
            if NetUtils.is_valid_ip(parsed.hostname):
                ip = parsed.hostname
                hostname = NetUtils.reverse_dns_lookup(parsed.hostname)
            else:
                ip = NetUtils.dns_lookup(parsed.hostname)
                if not ip:
                    logger.error('Host cannot be resolved')
                    return
                hostname = parsed.hostname
            port = WebUtils.get_port_from_url(url)

            # Check URL, grab headers, html title
            is_reachable, status, resp_headers = WebUtils.is_url_reachable(url)
            if is_reachable:
                comment = WebUtils.grab_html_title(url)
                if resp_headers:
                    http_headers = '\n'.join("{}: {}".format(key, val)
                                             for (key,
                                                  val) in resp_headers.items())

                logger.info('HTTP Headers:')
                print(http_headers)
                logger.info('Title: {}'.format(comment))
                logger.info(
                    'Grabbing banner from {ip}:{port} with Nmap...'.format(
                        ip=ip, port=port))
                banner = NetUtils.grab_banner_nmap(ip, port)
                logger.info('Banner: {}'.format(banner or 'None'))
                os = NetUtils.os_from_nmap_banner(banner)
                if os:
                    logger.info('Detected Host OS: {}'.format(os))
            else:
                comment = 'Not reachable'
                banner = http_headers = ''
                logger.warning('URL seems not to be reachable')

            # Add service in db (and host if not existing)
            service = Service(name='http',
                              port=port,
                              protocol=Protocol.TCP,
                              url=url,
                              up=is_reachable,
                              http_headers=http_headers,
                              banner=banner,
                              comment=comment)

            matching_host = self.sqlsess.query(Host).join(Mission)\
                                        .filter(Mission.name == self.current_mission)\
                                        .filter(Host.ip == ip).first()
            new_host = Host(ip=ip, hostname=hostname, os=os)
            if matching_host:
                matching_host.merge(new_host)
                self.sqlsess.commit()
                service.host = matching_host
            else:
                mission = self.sqlsess.query(Mission).filter(
                    Mission.name == self.current_mission).first()
                new_host.mission = mission
                service.host = new_host
                self.sqlsess.add(new_host)

            self.sqlsess.add(service)
            self.sqlsess.commit()
            logger.success('Service/URL added')