Ejemplo n.º 1
0
 def _extract_smb_os_discovery(self, host_tag):
     """Extracts SMB share information disclosed by SMB"""
     script = host_tag.findall("*/script/[@id='{}']".format(
         SmbExtraInfoExtraction.SMB_OS_DISCOVERY))
     for item in script:
         info = XmlUtils.get_element_text(item, "./elem[@key='os']")
         if info is not None:
             self._service.host.os_details = info
             if "windows" in info.lower():
                 self._service.host.os_family = "windows"
         info = XmlUtils.get_element_text(
             item, "./elem[@key='NetBIOS computer name']")
         if info is not None:
             self._service.host.workgroup = info
         if info is not None:
             self._service.host.os_details = info
             if "windows" in info.lower():
                 self._service.host.os_family = "windows"
         info = XmlUtils.get_element_text(item, "./elem[@key='FQDN']")
         if info is not None:
             self._domain_utils.add_domain_name(
                 session=self._session,
                 workspace=self._workspace,
                 item=info,
                 host=self._service.host,
                 source=self._source,
                 verify=True,
                 report_item=self._report_item)
         info = XmlUtils.get_element_text(item,
                                          "./elem[@key='Domain name']")
         if info is not None:
             self._domain_utils.add_domain_name(
                 session=self._session,
                 workspace=self._workspace,
                 item=info,
                 host=self._service.host,
                 source=self._source,
                 verify=True,
                 report_item=self._report_item)
         info = XmlUtils.get_element_text(item,
                                          "./elem[@key='Forest name']")
         if info is not None:
             self._domain_utils.add_domain_name(
                 session=self._session,
                 workspace=self._workspace,
                 item=info,
                 host=self._service.host,
                 source=self._source,
                 verify=True,
                 report_item=self._report_item)
Ejemplo n.º 2
0
 def _extract_sql_info(self, host_tag):
     """This method extracts the required information."""
     script = host_tag.findall("*/script/[@id='{}']".format(
         MsSqlExtraInfoExtraction.MSSQL_TCP_PORTS))
     script_count = len(script)
     if script_count == 1:
         for table in script[0].findall("./table"):
             tcp_port = XmlUtils.get_xml_text(
                 table.findall(".//*[@key='TCP port']"))
             if tcp_port:
                 service = self._domain_utils.add_service(
                     session=self._session,
                     port=tcp_port,
                     protocol_type=ProtocolType.tcp,
                     state=ServiceState.Open,
                     host=self._service.host,
                     source=self._source,
                     report_item=self._report_item)
                 if service:
                     service.nmap_service_name = MsSqlExtraInfoExtraction.MSSQL_SERVICE_NAME[
                         0]
     elif script_count > 1:
         raise NotImplementedError(
             "expected only one '/script/[@id='{}']' entry.".format(
                 MsSqlExtraInfoExtraction.MSSQL_TCP_PORTS))
Ejemplo n.º 3
0
 def _extract_rpc_info(self, port_tag) -> None:
     """This method determines additional services disclosed by rpcinfo"""
     script = port_tag.findall("*/[@id='{}']".format(
         RpcInfoExtraInfoExtraction.RPC_INFO))
     if len(script) > 0:
         tmp = XmlUtils.get_xml_attribute("output", script[0].attrib).split(
             os.linesep)
         for item in tmp:
             match = self._re_process.match(item)
             if match:
                 port = match.group("port")
                 protocol = match.group("protocol")
                 protocol = Service.get_protocol_type(protocol)
                 service_name = match.group("service")
                 service = self._domain_utils.add_service(
                     session=self._session,
                     port=port,
                     protocol_type=protocol,
                     host=self._service.host,
                     state=ServiceState.Internal,
                     source=self._source_rpc_info,
                     report_item=self._report_item)
                 if service:
                     service.nmap_service_name = service_name if not service.nmap_service_name \
                         else service.nmap_service_name
                     service.state = ServiceState.Internal if service.state != ServiceState.Open else service.state
Ejemplo n.º 4
0
 def _extract_http_headers(self, port_tag):
     """This method extracts information from HTTP headers."""
     for script_tag in port_tag.findall("script/[@id='{}']".format(
             HttpExtraInfoExtraction.HTTP_HEADERS)):
         output = XmlUtils.get_xml_attribute("output", script_tag.attrib)
         locations = [
             item.strip() for item in self._re_location.findall(output)
         ]
         if locations:
             self._domain_utils.add_additional_info(
                 session=self._session,
                 name="HTTP Header Location",
                 values=locations,
                 source=self._source,
                 service=self._service,
                 report_item=self._report_item)
             for location in locations:
                 url = urlparse(location)
                 if url.netloc:
                     self._domain_utils.add_domain_name(
                         session=self._session,
                         workspace=self._workspace,
                         item=url.netloc,
                         source=self._source,
                         verify=True,
                         report_item=self._report_item)
Ejemplo n.º 5
0
 def _extract_smb2_message_signing(self, host_tag):
     """Extracts SMB share information disclosed by SMB"""
     script = host_tag.findall("*/script/[@id='{}']".format(
         SmbExtraInfoExtraction.SMB2_SECURITY_MODE))
     for item in script:
         for table_tag in item.findall("table"):
             smb_version = XmlUtils.get_xml_attribute(
                 "key", table_tag.attrib)
             message = XmlUtils.get_element_text(table_tag, "elem")
             if smb_version and message:
                 self._domain_utils.add_additional_info(
                     session=self._session,
                     name="SMB2 message signing",
                     values=["{} ({})".format(message, smb_version)],
                     source=self._source,
                     service=self._service,
                     report_item=self._report_item)
Ejemplo n.º 6
0
 def _extract_rdp_encryption(self, port_tag) -> None:
     """This method extracts RDP encryption information"""
     script = port_tag.findall("*/[@id='{}']".format(
         RdpExtraInfoExtraction.RDP_ENUM_ENCRYPTION))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             security_layer_section = False
             encryption_level_section = False
             protocol_version_section = False
             rdp_security_layers = []
             rdp_encryption_level = []
             rdp_protocol_version = []
             for line in output.split(os.linesep):
                 line = line.strip()
                 if line == "Security layer":
                     security_layer_section = True
                 elif line == "RDP Encryption level: Client Compatible":
                     security_layer_section = False
                     encryption_level_section = True
                 elif line == "RDP Protocol Version:":
                     security_layer_section = False
                     encryption_level_section = False
                     line = line.replace("RDP Protocol Version:",
                                         "").strip()
                     rdp_protocol_version.append(line)
                 elif security_layer_section:
                     rdp_security_layers.append(line)
                 elif encryption_level_section:
                     rdp_encryption_level.append(line)
             if rdp_security_layers:
                 self._domain_utils.add_additional_info(
                     session=self._session,
                     name="RDP security layers",
                     values=rdp_security_layers,
                     source=self._source,
                     service=self._service,
                     report_item=self._report_item)
             if rdp_encryption_level:
                 self._domain_utils.add_additional_info(
                     session=self._session,
                     name="RDP encryption layers",
                     values=rdp_encryption_level,
                     source=self._source,
                     service=self._service,
                     report_item=self._report_item)
             if rdp_protocol_version:
                 self._domain_utils.add_additional_info(
                     session=self._session,
                     name="RDP protocol version",
                     values=rdp_protocol_version,
                     source=self._source,
                     service=self._service,
                     report_item=self._report_item)
Ejemplo n.º 7
0
 def _extract_smtp_commands(self, port_tag) -> None:
     """This method extracts the supported SMTP commands disclosed by the SMTP service"""
     script = port_tag.findall("*/[@id='{}']".format(SmtpExtraInfoExtraction.SMTP_COMMANDS))
     if len(script) > 0:
         tmp = XmlUtils.get_xml_attribute("output", script[0].attrib)
         commands = tmp.strip().split(" ")
         for command in commands:
             command = re.sub("[\W,\.\+_]", "", command)
             if not command.isnumeric():
                 self._domain_utils.add_service_method(session=self._session,
                                                       name=command,
                                                       service=self._service)
Ejemplo n.º 8
0
 def _extract_ipv4_addresses(self, host_tag) -> None:
     """This method extracts IPv4 addresses from traceroute command"""
     trace_tags = host_tag.findall("{}".format(TracerouteExtraction.TRACE_COMMAND))
     for trace_tag in trace_tags:
         for hop_tag in trace_tag.findall("hop"):
             ipv4_address = XmlUtils.get_xml_attribute("ipaddr", hop_tag.attrib)
             if ipv4_address:
                 host = self._ip_utils.add_host(session=self._session,
                                                workspace=self._workspace,
                                                address=ipv4_address,
                                                source=self._source_traceroute,
                                                report_item=self._report_item)
                 if not host:
                     logger.debug("ignoring IPv4 address due to invalid format: {}".format(ipv4_address))
Ejemplo n.º 9
0
 def _extract_http_server_header(self, port_tag: str) -> None:
     """This method extracts the HTTP title"""
     script = port_tag.findall("*/[@id='{}']".format(
         HttpExtraInfoExtraction.HTTP_SERVER_HEADER))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             self._domain_utils.add_additional_info(
                 session=self._session,
                 name="HTTP server header",
                 values=[output],
                 source=self._source,
                 service=self._service,
                 report_item=self._report_item)
Ejemplo n.º 10
0
 def _extract_tftp_paths(self, port_tag) -> None:
     """This method extracts the supported SMTP commands disclosed by the SMTP service"""
     script = port_tag.findall("*/[@id='{}']".format(
         TftpExtraInfoExtraction.TFTP_ENUM))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             for path_str in output.split(os.linesep):
                 path_str = path_str.strip()
                 self._domain_utils.add_path(session=self._session,
                                             service=self._service,
                                             path=path_str,
                                             path_type=PathType.filesystem,
                                             source=self._source,
                                             report_item=self._report_item)
Ejemplo n.º 11
0
 def _extract_robots_txt(self, port_tag: str) -> None:
     """This method extracts web paths disclosed by the robots.txt file."""
     script = port_tag.findall("*/[@id='{}']".format(
         HttpExtraInfoExtraction.ROBOTS_TXT))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             tmp = output.split(os.linesep)
             for line in tmp[1:]:
                 for item in line.split(" "):
                     self._domain_utils.add_url_path(
                         session=self._session,
                         service=self._service,
                         url_path=item,
                         source=self._source_robots_txt,
                         report_item=self._report_item)
Ejemplo n.º 12
0
 def _extract_http_backup_finder(self, port_tag):
     """This method extracts URLs"""
     script = port_tag.findall(".//*[@id='{}']".format(
         HttpExtraInfoExtraction.HTTP_BACKUP_FINDER))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             tmp = output.split(os.linesep)
             for line in tmp:
                 match = self._re_http_backup_finder.match(line)
                 if match:
                     self._domain_utils.add_url_path(
                         session=self._session,
                         service=self._service,
                         url_path=match.group("url"),
                         source=self._source,
                         report_item=self._report_item)
Ejemplo n.º 13
0
 def _extract_http_enum(self, port_tag: str) -> None:
     """This method extracts the enumerated file paths"""
     script = port_tag.findall("*/[@id='{}']".format(
         HttpExtraInfoExtraction.HTTP_ENUM))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             for line in output.split(os.linesep):
                 match = self._re_http_enum.match(line)
                 if match:
                     path = match.group("path")
                     self._domain_utils.add_path(
                         session=self._session,
                         service=self._service,
                         path=path,
                         path_type=PathType.http,
                         source=self._source,
                         report_item=self._report_item)
Ejemplo n.º 14
0
 def _extract_security_headers(self, port_tag: str) -> None:
     """This security headers"""
     for script_tag in port_tag.findall("script/[@id='{}']".format(
             HttpExtraInfoExtraction.HTTP_SECURITY_HEADERS)):
         for table_tag in script_tag.findall("table"):
             key = XmlUtils.get_xml_attribute("key", table_tag.attrib)
             if key:
                 key = key.strip()
                 values = []
                 for elem in table_tag.findall("elem"):
                     values.append(elem.text.strip())
                 if values:
                     self._domain_utils.add_additional_info(
                         session=self._session,
                         name=key,
                         values=values,
                         source=self._source,
                         service=self._service,
                         report_item=self._report_item)
Ejemplo n.º 15
0
 def _extract_http_comments_displayer(self, port_tag):
     """This method extracts URLs"""
     script = port_tag.findall(".//*[@id='{}']".format(
         HttpExtraInfoExtraction.HTTP_COMMENTS_DISPLAYER))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             dedup = {}
             for line in output.split(os.linesep):
                 match = self._re_comments_displayer_path.match(line)
                 if match:
                     url = match.group("url")
                     if url not in dedup:
                         dedup[url] = True
                         self._domain_utils.add_url_path(
                             session=self._session,
                             service=self._service,
                             url_path=url,
                             source=self._source_auth_finder,
                             report_item=self._report_item)
Ejemplo n.º 16
0
 def _extract_shares(self, host_tag):
     """Extracts SMB share information disclosed by SMB"""
     script = host_tag.findall("*/script/[@id='{}']".format(
         SmbExtraInfoExtraction.SMB_ENUM_SHARES))
     script_count = len(script)
     if script_count == 1:
         for table in script[0].findall("./table"):
             name = XmlUtils.get_xml_attribute("key", table.attrib)
             path_match = self._re_path.match(name)
             if path_match:
                 name = path_match.group("name")
             if name:
                 self._domain_utils.add_path(session=self._session,
                                             service=self._service,
                                             path=name,
                                             source=self._source,
                                             path_type=PathType.smb_share,
                                             report_item=self._report_item)
     elif script_count > 1:
         raise NotImplementedError(
             "expected only one '/script/[@id='smb-enum-shares']' entry in "
             "'parseSmbEnumShares'.")
Ejemplo n.º 17
0
 def _extract_http_title(self, port_tag: str) -> None:
     """This method extracts the HTTP title"""
     script = port_tag.findall("*/[@id='{}']".format(
         HttpExtraInfoExtraction.HTTP_TITLE))
     if len(script) > 0:
         output = XmlUtils.get_xml_attribute("output", script[0].attrib)
         if output:
             self._domain_utils.add_additional_info(
                 session=self._session,
                 name="HTTP title",
                 values=[output],
                 source=self._source,
                 service=self._service,
                 report_item=self._report_item)
             host_names = self._domain_utils.extract_domains(
                 unquote(output))
             for host_name in host_names:
                 self._domain_utils.add_domain_name(
                     session=self._session,
                     workspace=self._workspace,
                     item=host_name,
                     source=self._source,
                     verify=True,
                     report_item=self._report_item)
Ejemplo n.º 18
0
 def _extract_tls_info(self, port_tag) -> None:
     """This method determines additional services disclosed by rpcinfo"""
     script = port_tag.find("*/[@id='{}']".format(
         TlsInfoExtraction.TLS_INFO))
     if script:
         for tls_version_tag in script.findall("table"):
             order = 0
             tls_version_str = XmlUtils.get_xml_attribute(
                 "key", tls_version_tag.attrib)
             if tls_version_str:
                 tls_version = TlsInfo.get_tls_version(tls_version_str)
                 if tls_version:
                     preference_str = self._get_elem_text(
                         tls_version_tag,
                         query="elem[@key='cipher preference']")
                     if preference_str:
                         preference = TlsInfo.get_tls_preference(
                             preference_str)
                         if preference:
                             tls_info = self._domain_utils.add_tls_info(
                                 session=self._session,
                                 service=self._service,
                                 version=tls_version,
                                 preference=preference,
                                 report_item=self._report_item)
                             compressor_tag = tls_version_tag.find(
                                 "table[@key='compressors']")
                             if compressor_tag is not None:
                                 tls_info.compressors = [
                                     item.text for item in
                                     compressor_tag.findall("elem")
                                     if item.text != 'NULL'
                                 ]
                             for cipher_tag in tls_version_tag.findall(
                                     "table[@key='ciphers']"):
                                 for table_tag in cipher_tag.findall(
                                         "table"):
                                     order += 1
                                     kex_info = self._get_elem_text(
                                         table_tag,
                                         query="elem[@key='kex_info']")
                                     kex_info = TlsInfoCipherSuiteMapping.get_kex_algorithm(
                                         kex_info, self._source)
                                     if kex_info:
                                         tls_cipher = self._get_elem_text(
                                             table_tag,
                                             query="elem[@key='name']")
                                         self._domain_utils.add_tls_info_cipher_suite_mapping(
                                             session=self._session,
                                             tls_info=tls_info,
                                             order=order,
                                             kex_algorithm_details=kex_info,
                                             iana_name=tls_cipher,
                                             source=self._source,
                                             prefered=order == 1,
                                             report_item=self._report_item)
                         else:
                             raise NotImplementedError(
                                 "unknown TLS preference: {}".format(
                                     preference_str))
                 else:
                     raise NotImplementedError(
                         "unknown TLS version: {}".format(tls_version_str))
Ejemplo n.º 19
0
 def __init__(self, **kwargs):
     super().__init__(priority=41320, timeout=0, **kwargs)
     self._xml_utils = XmlUtils()
Ejemplo n.º 20
0
class CollectorClass(BaseTlsCollector, ServiceCollector,
                     HostNameServiceCollector):
    """This class implements a collector module that is automatically incorporated into the application."""
    def __init__(self, **kwargs):
        super().__init__(priority=41320, timeout=0, **kwargs)
        self._xml_utils = XmlUtils()

    @staticmethod
    def get_argparse_arguments():
        return {"help": __doc__, "action": "store_true"}

    def _create_command(self, session: Session, service: Service,
                        collector_name: CollectorName,
                        ipv6: bool) -> List[BaseCollector]:
        """This method creates and returns a list of commands based on the given service.

        This method determines whether the command exists already in the database. If it does, then it does nothing,
        else, it creates a new Collector entry in the database for each new command as well as it creates a corresponding
        operating system command and attaches it to the respective newly created Collector class.

        :param session: Sqlalchemy session that manages persistence operations for ORM-mapped objects
        :param service: The service based on which commands shall be created.
        :param collector_name: The name of the collector as specified in table collector_name
        :return: List of Collector instances that shall be processed.
        """

        collectors = []
        address = service.address
        if address:
            matches = True
            xml_file = self.create_xml_file_path(service)
            os_command = [
                self._path_sslscan, '-6' if ipv6 else '-4',
                '--show-certificate', '--ocsp', '--no-color',
                '--xml={}'.format(ExecutionInfoType.xml_output_file.argument)
            ]
            if self.match_service_tls(service) or (
                    MsSqlServiceDescriptor().match_nmap_service_name(service)):
                pass
            elif LdapServiceDescriptor().match_nmap_service_name(service):
                os_command.append('--starttls-ldap')
            elif FtpServiceDescriptor().match_nmap_service_name(service):
                os_command.append('--starttls-ftp')
            elif SmtpServiceDescriptor().match_nmap_service_name(service):
                os_command.append('--starttls-smtp')
            elif MySqlServiceDescriptor().match_nmap_service_name(service):
                os_command.append('--starttls-mysql')
            elif PostgresSqlServiceDescriptor().match_nmap_service_name(
                    service):
                os_command.append('--starttls-psql')
            elif RdpServiceDescriptor().match_nmap_service_name(service):
                os_command.append('--rdp')
            else:
                matches = False
            if matches:
                if ipv6:
                    os_command.append("[{}]:{}".format(address, service.port))
                else:
                    os_command.append("{}:{}".format(address, service.port))
                collector = self._get_or_create_command(session,
                                                        os_command,
                                                        collector_name,
                                                        service=service,
                                                        xml_file=xml_file)
                collectors.append(collector)
        return collectors

    def create_host_name_service_commands(
            self, session: Session, service: Service,
            collector_name: CollectorName) -> List[BaseCollector]:
        """This method creates and returns a list of commands based on the given host name.

        This method determines whether the command exists already in the database. If it does, then it does nothing,
        else, it creates a new Collector entry in the database for each new command as well as it creates a corresponding
        operating system command and attaches it to the respective newly created Collector class.

        :param session: Sqlalchemy session that manages persistence operations for ORM-mapped objects
        :param service: The service based on which commands shall be created.
        :param collector_name: The name of the collector as specified in table collector_name
        :return: List of Collector instances that shall be processed.
        """

        result = []
        if service.host_name.name or self._scan_tld:
            # resolve host name to IPv4 address
            if service.host_name.resolves_to_in_scope_ipv4_address():
                result = self._create_command(session=session,
                                              service=service,
                                              collector_name=collector_name,
                                              ipv6=False)
            # resolve host name to IPv6 address
            if service.host_name.resolves_to_in_scope_ipv6_address():
                result = self._create_command(session=session,
                                              service=service,
                                              collector_name=collector_name,
                                              ipv6=True)
        return result

    def create_service_commands(
            self, session: Session, service: Service,
            collector_name: CollectorName) -> List[BaseCollector]:
        """This method creates and returns a list of commands based on the given service.

        This method determines whether the command exists already in the database. If it does, then it does nothing,
        else, it creates a new Collector entry in the database for each new command as well as it creates a corresponding
        operating system command and attaches it to the respective newly created Collector class.

        :param session: Sqlalchemy session that manages persistence operations for ORM-mapped objects
        :param service: The service based on which commands shall be created.
        :param collector_name: The name of the collector as specified in table collector_name
        :return: List of Collector instances that shall be processed.
        """
        return self._create_command(session=session,
                                    service=service,
                                    collector_name=collector_name,
                                    ipv6=service.host.ip_address.version == 6)

    def verify_results(self,
                       session: Session,
                       command: Command,
                       source: Source,
                       report_item: ReportItem,
                       process: PopenCommand = None,
                       **kwargs) -> None:
        """This method analyses the results of the command execution.

        After the execution, this method checks the OS command's results to determine the command's execution status as
        well as existing vulnerabilities (e.g. weak login credentials, NULL sessions, hidden Web folders). The
        stores the output in table command. In addition, the collector might add derived information to other tables as
        well.

        :param session: Sqlalchemy session that manages persistence operations for ORM-mapped objects
        :param command: The command instance that contains the results of the command execution
        :param source: The source object of the current collector
        :param report_item: Item that can be used for reporting potential findings in the UI
        :param process: The PopenCommand object that executed the given result. This object holds stderr, stdout, return
        code etc.
        """
        command.hide = True
        try:
            tls_info_list = {}
            if command.xml_output:
                xml_root = ET.fromstring(command.xml_output)
                if xml_root is None:
                    return
                results_tag = xml_root.find("ssltest")
                if results_tag is None:
                    return
                certinfo = results_tag.find(
                    "./certificates/*/certificate-blob")
                if certinfo is not None and certinfo.text:
                    self.add_certificate(session=session,
                                         command=command,
                                         content=certinfo.text,
                                         type=CertType.identity,
                                         source=source,
                                         report_item=report_item)
                else:
                    logger.error("no certificate information found.")
                order = 1
                for cipher_tag in results_tag.findall("cipher"):
                    status = self._xml_utils.get_xml_attribute(
                        "status", cipher_tag.attrib)
                    sslversion = self._xml_utils.get_xml_attribute(
                        "sslversion", cipher_tag.attrib)
                    cipher = self._xml_utils.get_xml_attribute(
                        "cipher", cipher_tag.attrib)
                    curve = self._xml_utils.get_xml_attribute(
                        "curve", cipher_tag.attrib)
                    tls_version = TlsInfo.get_tls_version(sslversion)
                    if tls_version:
                        heartbleed_tag = results_tag.find(
                            "heartbleed[@sslversion='{}']".format(sslversion))
                        heartbleed = self._xml_utils.get_xml_attribute(
                            "vulnerable", heartbleed_tag.attrib)
                        heartbleed = heartbleed != "0"
                        if sslversion not in tls_info_list:
                            tls_info_list[sslversion] = self.add_tls_info(
                                session=session,
                                service=command.service,
                                version=tls_version,
                                heartbleed=heartbleed)
                            order = 1
                        if tls_info_list[sslversion]:
                            tls_info = tls_info_list[sslversion]
                            kex_algorithm = TlsInfoCipherSuiteMapping.get_kex_algorithm(
                                curve) if curve else None
                            # sslscan does not consistently use one cipher suite notation.
                            mapping = self.add_tls_info_cipher_suite_mapping(
                                session=session,
                                tls_info=tls_info,
                                order=order,
                                kex_algorithm_details=kex_algorithm,
                                gnutls_name=cipher,
                                prefered=status == "preferred",
                                source=source,
                                report_item=report_item)
                            if not mapping:
                                mapping = self.add_tls_info_cipher_suite_mapping(
                                    session=session,
                                    tls_info=tls_info,
                                    order=order,
                                    kex_algorithm_details=kex_algorithm,
                                    iana_name=cipher,
                                    prefered=status == "preferred",
                                    source=source,
                                    report_item=report_item)
                                if not mapping:
                                    mapping = self.add_tls_info_cipher_suite_mapping(
                                        session=session,
                                        tls_info=tls_info,
                                        order=order,
                                        kex_algorithm_details=kex_algorithm,
                                        openssl_name=cipher,
                                        prefered=status == "preferred",
                                        source=source,
                                        report_item=report_item)
                                    if not mapping:
                                        logger.error(
                                            "cipher suite '{}' does not exist. ignoring cipher suite"
                                            .format(cipher))
                            if mapping:
                                order += 1
        except xml.etree.ElementTree.ParseError as e:
            logger.exception(e)
Ejemplo n.º 21
0
 def _import_file(self, input_file: str) -> None:
     """
     This method imports the given file into the database.
     :param input_file: The file to be imported
     :return:
     """
     tree = ET.parse(input_file)
     root = tree.getroot()
     source = Engine.get_or_create(self._session, Source, name=self._source)
     for host_tag in root.findall('*/ReportHost'):
         host = None
         properties = host_tag.find("HostProperties")
         ip_address = DatabaseImporter.get_xml_attribute(
             "name", host_tag.attrib)
         if properties:
             ipv4_address = properties.find("*/[@name='host-ip']")
             ipv4_address = ipv4_address.text if ipv4_address is not None else ip_address
             os_info = properties.find("*/[@name='os']")
             os_info = os_info.text if os_info is not None else None
             host = self._ip_utils.add_host(session=self._session,
                                            workspace=self._workspace,
                                            address=ipv4_address,
                                            source=source,
                                            report_item=self._report_item)
             host.os_family = os_info.lower(
             ) if os_info is not None and host.os_family is None else None
         if host:
             for item in host_tag.findall("ReportItem"):
                 port = int(
                     DatabaseImporter.get_xml_attribute(
                         "port", item.attrib))
                 severity = int(
                     DatabaseImporter.get_xml_attribute(
                         "severity", item.attrib))
                 protocol = DatabaseImporter.get_xml_attribute(
                     "protocol", item.attrib)
                 service_name = DatabaseImporter.get_xml_attribute(
                     "svc_name", item.attrib)
                 if service_name:
                     if service_name[-1] == '?':
                         confidence = 7
                         service_name = service_name[:-1]
                     else:
                         confidence = 10
                 else:
                     confidence = None
                 protocol = Service.get_protocol_type(protocol)
                 if protocol:
                     if port > 0:
                         plugin_id = DatabaseImporter.get_xml_attribute(
                             "pluginID", item.attrib)
                         plugin_name = DatabaseImporter.get_xml_attribute(
                             "pluginName", item.attrib)
                         nmap_tunnel = "ssl" if plugin_id == "56984" and \
                                                plugin_name == "SSL / TLS Versions Supported" else None
                         service = self._domain_utils.add_service(
                             session=self._session,
                             port=port,
                             protocol_type=protocol,
                             state=ServiceState.Open,
                             nessus_service_confidence=confidence,
                             nessus_service_name=service_name,
                             host=host,
                             nmap_tunnel=nmap_tunnel,
                             source=source,
                             report_item=self._report_item)
                         # add vulnerability information
                         if severity > 0:
                             description = XmlUtils.get_element_text(
                                 item, "description")
                             cve = XmlUtils.get_element_text(item, "cve")
                             cvss_base_score = XmlUtils.get_element_text(
                                 item, "cvss_base_score")
                             cvss3_base_score = XmlUtils.get_element_text(
                                 item, "cvss3_base_score")
                             row = [[
                                 cve, cvss3_base_score, cvss_base_score,
                                 "{} - {}".format(plugin_id,
                                                  plugin_name), description
                             ]]
                             vulnerability = self._domain_utils.get_list_as_csv(
                                 row)
                             self._domain_utils.add_additional_info(
                                 session=self._session,
                                 service=service,
                                 name="CVEs",
                                 values=vulnerability,
                                 source=source,
                                 report_item=self._report_item)