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. """ if command.return_code and command.return_code > 0: command.hide = False self._set_execution_failed(session, command) return else: command.hide = True for line in command.stdout_output: line = line.strip() match = self._smb_info_re.match(line) if match: os_info = match.group("os").strip() domain = match.group("domain").strip() signing = match.group("signing").strip().lower() smbv1 = match.group("smbv1").strip().lower() if domain: command.host.workgroup = domain self.add_host_name(session=session, command=command, host_name=domain, source=source, verify=True, report_item=report_item) if os_info: if "windows" in os_info.lower(): command.host.os_family = "windows" command.host.os_details = os_info if signing and signing in ['true', 'false']: command.service.smb_message_signing = signing == 'true' self.add_additional_info( session=session, command=command, service=command.service, name="SMB", values=[ "SMB message signing: {}, SMBv1: {}".format( signing, smbv1) ], source=source, report_item=report_item)
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 = command.return_code and command.return_code > 0 output = os.linesep.join(command.stderr_output) + os.linesep.join( command.stdout_output) for match in self._nt_status_re.finditer(output): code = match.group("value") if code in self._failed_status: command.hide = True break
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. """ for line in command.stdout_output: if self._re_no_response.match(line): command.hide = True break paths = self.add_robots_txt(session=session, command=command, service=command.service, robots_txt=command.stdout_output, source=source, report_item=report_item) if not paths: command.hide = True
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. """ summary = False text = "{} Summary:".format(self._path_davtest) for line in command.stdout_output: if summary and line: command.hide = False report_item.details = "potential file upload via HTTP PUT" report_item.report_type = "UPLOAD" self.add_report_item(report_item) if text in line: summary = True
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. """ success = False for line in command.stdout_output: match_creds = self._re_success.match(line) if match_creds: success = True credential = self.add_credential(session=session, command=command, username=None, password=None, credential_type=None, source=source, service=command.service, report_item=report_item) if not credential: logger.debug("ignoring credentials in line: {}".format(line)) command.hide = not success
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.hint = [] for line in command.stdout_output: match = self._export_re.match(line) if match: export = match.group("export").strip().strip('"').strip("'") self.add_path(session=session, command=command, service=command.service, path=export, path_type=PathType.nfs_export, source=source, report_item=report_item)
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.hint = [] command.hide = command.return_code and command.return_code > 0 for line in command.stdout_output: line = line.strip() match_share = self._re_shares.match(line) if match_share: ipv4_address = command.service.host.ipv4_address name = "/{}".format(match_share.group(1)) self.add_path(session=session, command=command, service=command.service, path=name, path_type=PathType.smb_share, source=source, report_item=report_item) self.add_hint( command=command, hint="$ smbclient //{}{} -U\"$user\"%\"$password\" -c " "'prompt OFF;recurse ON;mget *'".format( ipv4_address, name)) self.add_hint( command=command, hint= "$ sudo mount -t cifs -o user=$usr,password=$pwd //{}/{} " "$mountpoint".format(ipv4_address, name))
def _filter(self, command: Command) -> bool: """ Method determines whether the given item shall be included into the report """ return command.is_processable( included_items=self._included_items, excluded_items=self._excluded_items, exclude_collectors=self._excluded_collectors, include_collectors=self._included_collectors, scope=self._scope)
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. """ if command.return_code and command.return_code > 0: self._set_execution_failed(session, command) else: command.hide = True command.stderr_output = [] for line in command.stdout_output: line = line.strip() match = self._result_re.match(line) if match: size_bytes = int(match.group("size")) status_code = int(match.group("status")) url = match.group("url") self.add_url_path(session=session, service=command.service, url_path=url, status_code=status_code, size_bytes=size_bytes, source=source, report_item=report_item)
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. """ contexts = {} unique = {} matchers = [ "defaultNamingContext:", "defaultNamingContext:", "rootDomainNamingContext:" ] command.hint = [] for line in command.stdout_output: for matcher in matchers: if matcher in line: tmp = line.split(":") if len(tmp) >= 2: key = tmp[0] value = ":".join(tmp[1:]) contexts[key] = value unique[value] = True for key, value in contexts.items(): self.add_additional_info(session=session, command=command, service=command.service, name="{} {}".format( command.collector_name.name, key), values=[value], source=source, report_item=report_item) for key, _ in unique.items(): new_command = command.os_command_substituted[:-2] new_command.extend(['-b', '"{}"'.format(key)]) self.add_hint(command=command, hint="$ {}".format(" ".join(new_command)))
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 for line in command.stdout_output: path_status_pair = None line = line.strip() match = self._re_path.match(line) match_wildcard = self._re_wildcard_response.match(line) if match: path_str = match.group(1).strip() status_code = int(match.group(2).strip()) size_bytes = int(match.group(3).strip()) path_status_pair = [path_str, status_code, size_bytes] elif match_wildcard: path_str = match.group(1).strip() status_code = int(match.group(2).strip()) path_status_pair = [path_str, status_code, None] if path_status_pair: path_str, status_code, size_bytes = path_status_pair url = self.add_url_path(session=session, service=command.service, url_path=path_str, status_code=status_code, size_bytes=size_bytes, source=source, report_item=report_item) if not url: logger.debug( "ignoring host name due to invalid domain in line: {}". format(line))
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 for line in command.stdout_output: match = self._re_pointer.match(line) if match: host_name = match.group("value").strip().lower() # Add host name to database host_name = self.add_host_name(session=session, command=command, source=source, host_name=host_name, report_item=report_item) if not host_name: logger.debug( "ignoring host name due to invalid domain in line: {}". format(line)) else: self.add_host_host_name_mapping( session=session, command=command, host=command.host, host_name=host_name, source=source, mapping_type=DnsResourceRecordType.ptr, report_item=report_item)
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 output = os.linesep.join(command.stdout_output) certificates = self._re_cert.findall(output) certificates_len = len(certificates) if certificates_len == 0: self._set_execution_failed(session, command) for i in range(0, certificates_len): if i == 0: cert_type = CertType.identity elif i == (certificates_len - 1): cert_type = CertType.root else: cert_type = CertType.intermediate self.add_certificate(session=session, command=command, content=certificates[i], type=cert_type, source=source, report_item=report_item)
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 for line in command.stdout_output: match = self._success_re.match(line) if match: ntlm = match.group("ntlm") lm = match.group("lm") user_name = match.group("user") domain = match.group("domain") self.add_credential(session=session, command=command, password="******".format(lm, ntlm), credential_type=CredentialType.hash, username=user_name, domain=domain, source=source, service=command.service, report_item=report_item)
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 for line in command.stdout_output: match = self._re_entry.match(line) if match: host_name_str = match.group("hostname").strip(". ") record_type_str = match.group("type").strip().lower() content = match.group("content").strip().strip(". ") try: record_type = DnsResourceRecordType[record_type_str] host_name = self.add_host_name(session=session, command=command, host_name=host_name_str, source=source, report_item=report_item) if host_name: if record_type in [ DnsResourceRecordType.a, DnsResourceRecordType.aaaa ] and content: # Add IPv4 address to database host = self.add_host(session=session, command=command, source=source, address=content, report_item=report_item) if not host: logger.debug( "ignoring host due to invalid IP address in line: {}" .format(line)) else: self.add_host_host_name_mapping( session=session, command=command, host=host, host_name=host_name, source=source, mapping_type=record_type, report_item=report_item) if record_type == DnsResourceRecordType.cname and content: cname_host_name = self.add_host_name( session=session, command=command, host_name=content, source=source, report_item=report_item) if cname_host_name: self.add_host_name_host_name_mapping( session=session, command=command, source_host_name=host_name, resolved_host_name=cname_host_name, source=source, mapping_type=DnsResourceRecordType.cname, report_item=report_item) else: logger.debug( "ignoring host name due to invalid domain in line: {}" .format(line)) else: for item in self._domain_utils.extract_domains( content): host_name = self.add_host_name( session=session, command=command, host_name=item, source=source, report_item=report_item) if not host_name: logger.debug( "ignoring host name due to invalid domain in line: {}" .format(line)) else: logger.debug( "ignoring host name due to invalid domain in line: {}" .format(line)) except KeyError as ex: logger.exception(ex)
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. """ companies = {} email_objects = {} network_objects = {} command.hide = True # extract company names for line in command.stdout_output: match = self._re_organizations.match(line) if match: name = match.group("name").strip().lower() companies[name] = None # extract IPv4/IPv6 networks and emails for line in command.stdout_output: match_ip_network_range = self._re_ip_network_range.match(line) match_ipv4_network_cidr = self._re_ipv4_network_cidr.match(line) match_ipv6_network_cidr = self._re_ipv6_network_cidr.match(line) emails = self._email_utils.extract_emails(line) for email in emails: email_objects[email] = None if match_ip_network_range: try: for item in IpUtils.qualys_to_cidr(match_ip_network_range.group("range")): network_objects[str(item)] = None except ValueError as ex: logger.exception(ex) elif match_ipv4_network_cidr: try: for item in self._split_cidr(match_ipv4_network_cidr.group("range")): network_objects[item] = None except ValueError as ex: logger.exception(ex) elif match_ipv6_network_cidr: try: for item in self._split_cidr(match_ipv6_network_cidr.group("range")): network_objects[item] = None except ValueError as ex: logger.exception(ex) # saving companies, IPv4/IPv6 networks, and emails for item in network_objects.keys(): network = self.add_network(session=session, command=command, network=item, source=source, report_item=report_item) if not network: logger.debug("ignoring network '{}' due to invalid format.".format(item)) else: for name in companies.keys(): company = self.add_company(session=session, workspace=command.workspace, name=name, network=network, source=source, report_item=report_item) if not company: logger.debug("ignoring company '{}' due to invalid format.".format(company)) for item in email_objects.keys(): email = self.add_email(session=session, command=command, email=item, source=source, report_item=report_item) if not email: logger.debug("ignoring email '{}' due to invalid format.") else: for name in companies.keys(): company = self.add_company(session=session, workspace=command.workspace, name=name, domain_name=email.host_name.domain_name, source=source, report_item=report_item) if not company: logger.debug("ignoring company '{}' due to invalid format.".format(company))
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 for line in command.stdout_output: line = line.strip() match = self._re_vhost.match(line) if match: vhost = match.group("vhost").strip() return_code = int(match.group("status").strip()) size_bytes = int(match.group("size").strip()) if IpUtils.is_valid_address(vhost): # Add IP address to database host = self.add_host(session=session, command=command, address=vhost, source=source, report_item=report_item) if not host: logger.debug( "ignoring IP address due to invalid domain in line: {}" .format(line)) else: self.add_vhost_name_mapping(session=session, host=host, service=command.service, return_code=return_code, size_bytes=size_bytes, source=source, report_item=report_item) else: # Add host name to database host_name = self.add_host_name(session=session, command=command, source=source, host_name=vhost, verify=False, report_item=report_item) if not host_name: logger.debug( "ignoring host name due to invalid domain in line: {}" .format(line)) else: self.add_vhost_name_mapping(session=session, host_name=host_name, service=command.service, return_code=return_code, size_bytes=size_bytes, source=source, report_item=report_item)
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 if command.return_code and command.return_code > 0: self._set_execution_failed(session=session, command=command) try: if command.json_output: for json_object in command.json_output: if "server_scan_results" in json_object: # Obtain all relevant information from JSON object server_scan_results = json_object[ "server_scan_results"] for server_scan_result in server_scan_results: certificate_deployments = self._json_utils.get_attribute_value( json_object=server_scan_result, path= "scan_result/certificate_info/result/certificate_deployments", default_value=[]) ssl_2_0_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/ssl_2_0_cipher_suites/result" ) ssl_3_0_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/ssl_3_0_cipher_suites/result" ) tls_1_0_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/tls_1_0_cipher_suites/result" ) tls_1_1_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/tls_1_1_cipher_suites/result" ) tls_1_2_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/tls_1_2_cipher_suites/result" ) tls_1_3_cipher_suites = self._json_utils.get_attribute_value( json_object=server_scan_result, path="scan_result/tls_1_3_cipher_suites/result" ) # Parse the certificate information for certificate_deployment in certificate_deployments: if "received_certificate_chain" in certificate_deployment and \ isinstance(certificate_deployment["received_certificate_chain"], list): chain = certificate_deployment[ "received_certificate_chain"] i = 1 for item in chain: if "as_pem" in item: self.add_certificate( session=session, command=command, content=item["as_pem"], type=CertType.identity if i == 1 else CertType.intermediate if i < len(chain) else CertType.root, source=source, report_item=report_item) i += 1 else: raise NotImplementedError( "unexpected JSON format (missing attribute 'as_pem')" ) else: raise NotImplementedError( "unexpected JSON format (missing attribute " "'received_certificate_chain')") # Process all TLS versions self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.ssl2, tls_result=ssl_2_0_cipher_suites) self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.ssl3, tls_result=ssl_3_0_cipher_suites) self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.tls10, tls_result=tls_1_0_cipher_suites) self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.tls11, tls_result=tls_1_1_cipher_suites) self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.tls12, tls_result=tls_1_2_cipher_suites) self._parse_cipher_suites( session=session, command=command, report_item=report_item, source=source, tls_version=TlsVersion.tls13, tls_result=tls_1_3_cipher_suites) except xml.etree.ElementTree.ParseError as e: logger.exception(e)
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)
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 if command.return_code and command.return_code > 0: self._set_execution_failed(session, command) for line in command.stdout_output: match = self._re_organizations.match(line) if match: name = match.group("name").strip().lower() company = self.add_company( session=session, workspace=command.workspace, name=name, domain_name=command.host_name.domain_name, source=source, report_item=report_item) if not company: logger.debug("ignoring company: {}".format(name)) emails = self._email_utils.extract_emails(line) match = self._re_name_server_info.match(line) if match: host_name = match.group("domain") ipv4_address = match.group("ipv4") host = self.add_host(session=session, command=command, address=ipv4_address, source=source, report_item=report_item) if not host: logger.debug( "ignoring host due to invalid address in line: {}". format(line)) host_name = self.add_host_name(session=session, command=command, host_name=host_name, source=source, report_item=report_item) if not host_name: logger.debug( "ignoring host name due to invalid domain in line: {}". format(line)) elif host: self.add_host_host_name_mapping( session=session, command=command, host=host, host_name=host_name, source=source, mapping_type=DnsResourceRecordType.ns, report_item=report_item) for item in emails: email = self.add_email(session=session, command=command, email=item, source=source, report_item=report_item) if not email: logger.debug("ignoring company: {}".format(item))
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 for line in command.stdout_output: ipv4_match = self._re_ipv4.match(line) ipv6_match = self._re_ipv6.match(line) cname_match = self._re_cname.match(line) mx_host_match = self._re_host_mx.match(line) if ipv4_match: source_host_str = ipv4_match.group("domain").strip() address = ipv4_match.group("address") # Add IPv4 address to database host = self.add_host(session=session, command=command, source=source, address=address, report_item=report_item) if source_host_str and source_host_str != command.host_name.full_name: source_host = self.add_host_name(session=session, command=command, host_name=source_host_str, source=source, report_item=report_item) if source_host and host: self._domain_utils.add_host_host_name_mapping( session=session, host=host, host_name=source_host, source=source, mapping_type=DnsResourceRecordType.a, report_item=report_item) session.flush() else: logger.debug( "could not link host name '{}' with host '{}'". format(source_host_str, address)) if address and not host: logger.debug( "ignoring host due to invalid IPv4 address in line: {}" .format(line)) elif host: self._domain_utils.add_host_host_name_mapping( session=session, host=host, host_name=command.host_name, source=source, mapping_type=DnsResourceRecordType.a, report_item=report_item) session.flush() elif ipv6_match: source_host_str = ipv6_match.group("domain").strip() address = ipv6_match.group("address") # Add IPv4 address to database host = self.add_host(session=session, command=command, source=source, address=address, report_item=report_item) if source_host_str and source_host_str != command.host_name.full_name: source_host = self.add_host_name(session=session, command=command, host_name=source_host_str, source=source, report_item=report_item) if source_host and host: self._domain_utils.add_host_host_name_mapping( session=session, host=host, host_name=source_host, source=source, mapping_type=DnsResourceRecordType.aaaa, report_item=report_item) session.flush() else: logger.debug( "could not link host name '{}' with host '{}'". format(source_host_str, address)) if address and not host: logger.debug( "ignoring host due to invalid IPv6 address in line: {}" .format(line)) elif host: self._domain_utils.add_host_host_name_mapping( session=session, host=host, host_name=command.host_name, source=source, mapping_type=DnsResourceRecordType.aaaa, report_item=report_item) session.flush() elif mx_host_match: mx_host_name = mx_host_match.group("domain") # Add host name to database host_name = self.add_host_name(session=session, command=command, source=source, host_name=mx_host_name, report_item=report_item) if not host_name: logger.debug( "ignoring host name due to invalid domain in line: {}". format(line)) elif cname_match: source_domain = cname_match.group("domain1").strip() target_domain = cname_match.group("domain2").strip() source_host_name = self.add_host_name(session=session, command=command, host_name=source_domain, source=source, report_item=report_item) target_host_name = self.add_host_name(session=session, command=command, host_name=target_domain, source=source, report_item=report_item) if not source_host_name: logger.debug( "ignoring host name due to invalid domain in line: {}". format(source_domain)) elif not target_host_name: logger.debug( "ignoring host name due to invalid domain in line: {}". format(source_domain)) else: self.add_host_name_host_name_mapping( session=session, command=command, source_host_name=source_host_name, resolved_host_name=target_host_name, source=source, mapping_type=DnsResourceRecordType.cname, report_item=report_item)