def get_user_agent_fingerprint_for_web_service( self, org_uuid=None, web_service_uuid=None, web_service_scan_uuid=None, user_agent_type=None, user_agent_name=None, user_agent_string=None, ): """ Get a user agent fingerprint from the given web service using the given user agent. :param org_uuid: The UUID of the organization to get the fingerprint for. :param web_service_uuid: The UUID of the web service to fingerprint. :param web_service_scan_uuid: The UUID of the web service scan to get the fingerprint for. :param user_agent_type: The type of user agent being tested. :param user_agent_name: A name for the user agent being tested. :param user_agent_string: A string containing the user agent to test with. :return: None """ logger.info( "Now testing web service %s for user agent fingerprint %s (%s)." % (web_service_uuid, user_agent_name, user_agent_string) ) ip_address, port, hostname, use_ssl = get_endpoint_information_for_web_service( web_service_uuid=web_service_uuid, db_session=self.db_session, ) inspector = WebServiceInspector(ip_address=ip_address, port=port, hostname=hostname, use_ssl=use_ssl) response = inspector.get(user_agent=user_agent_string) if isinstance(response.response_content_wrapper, BaseMarkupWrapper): secondary_hash = response.response_content_wrapper.full_decomposition else: secondary_hash = response.response_content_hash user_agent_fingerprint = UserAgentFingerprintModel.from_database_model_uuid( uuid=web_service_scan_uuid, db_session=self.db_session, user_agent_type=user_agent_type, user_agent_name=user_agent_name, user_agent_string=user_agent_string, response_has_content=response.response_has_content, response_mime_type=response.response_mime_string, response_primary_hash=response.response_content_hash, response_secondary_hash=secondary_hash, response_status_code=response.response_status_code, ) user_agent_fingerprint.save(org_uuid) logger.info( "Successfully gathered user agent fingerprint %s (%s) for web service %s." % (user_agent_name, user_agent_string, web_service_uuid) )
def fingerprint_virtual_host( self, org_uuid=None, network_service_uuid=None, network_service_scan_uuid=None, use_ssl=None, hostname=None, order_uuid=None, ): """ Get a virtual host fingerprint from the web service running at the given network service for the given hostname. :param org_uuid: The UUID of the organization to retrieve a fingerprint for. :param network_service_uuid: The UUID of the network service where the web service resides. :param network_service_scan_uuid: The UUID of the network service scan that this fingerprinting is a part of. :param use_ssl: Whether or not to use SSL to connect to the remote endpoint. :param hostname: The hostname to submit a request for. :return: None """ logger.info( "Now retrieving virtual host fingerprint for service %s with hostname %s. Organization is %s." % (network_service_uuid, hostname, org_uuid)) ip_address, port, protocol = self.get_endpoint_information() inspector = WebServiceInspector(ip_address=ip_address, port=port, use_ssl=use_ssl, hostname=hostname) try: response = inspector.get() except (SSLError, ReadTimeout) as e: logger.error("Error thrown when retrieving fingerprint: %s %s." % (e.__class__.__name__, e.message)) return logger.info("Fingerprint retrieved for virtual host %s on service %s." % (hostname, network_service_uuid)) fingerprint_model = response.to_es_model( model_uuid=network_service_scan_uuid, db_session=self.db_session) fingerprint_model.save(org_uuid) logger.info("Fingerprint pushed to Elasticsearch successfully.")
def inspector(self): """ Get a web service inspector that this task should use to investigate the referenced web service. :return: A web service inspector that this task should use to investigate the referenced web service. """ from lib.inspection import WebServiceInspector return WebServiceInspector( ip_address=self.web_service.ip_address, port=self.web_service.port, hostname=self.web_service.host_name, use_ssl=self.web_service.ssl_enabled, )
def assess_virtual_host_fingerprints( self, org_uuid=None, network_service_uuid=None, network_service_scan_uuid=None, use_ssl=None, order_uuid=None, ): """ Evaluate the contents of the virtual host fingerprints gathered during the given network scan and create virtual host models for all of the virtual hosts that were discovered. :param org_uuid: The UUID of the organization to assess virtual hosts for. :param network_service_uuid: The UUID of the network service that virtual hosts were checked for. :param network_service_scan_uuid: The UUID of the network service scan to assess virtual host fingerprints for. :param use_ssl: Whether or not to use SSL to connect to the remote endpoint. :return: None """ logger.info( "Now assessing the results of virtual host fingerprinting for service %s, scan %s. Organization is %s." % (network_service_uuid, network_service_scan_uuid, org_uuid)) self.wait_for_es() fingerprint_results = get_fingerprint_data_for_network_service_scan( org_uuid=org_uuid, scan_uuid=network_service_scan_uuid, over_ssl=use_ssl, ) try: ip_address, port, protocol = self.get_endpoint_information() inspector = WebServiceInspector(ip_address=ip_address, port=port, use_ssl=use_ssl) response = inspector.get() base_fingerprint = response.to_es_model( model_uuid=network_service_scan_uuid, db_session=self.db_session) base_response_code = base_fingerprint.response_code base_response_has_content = base_fingerprint.response_has_content base_response_mime_type = base_fingerprint.response_mime_type base_response_secondary_hash = base_fingerprint.response_secondary_hash base_hostname = base_fingerprint.hostname except SSLError as e: ip_address, port, protocol = self.get_endpoint_information() logger.warning( "SSLError thrown when retrieving baseline for endpoint %s (%s:%s): %s." % (network_service_uuid, ip_address, port, e.message)) baseline = pick_baseline(fingerprint_results) base_response_code = baseline[0] base_response_has_content = baseline[1] base_response_mime_type = baseline[2] base_response_secondary_hash = baseline[4] base_hostname = baseline[6] vhost_domains = [] for code, has_content, mime_type, p_hash, s_hash, over_ssl, hostname in fingerprint_results: if base_response_code != code: vhost_domains.append((hostname, "status-code")) elif base_response_has_content and not has_content: vhost_domains.append((hostname, "has-content")) elif base_response_mime_type != mime_type: vhost_domains.append((hostname, "mime-type")) elif base_response_secondary_hash != s_hash: vhost_domains.append((hostname, "content-hash")) logger.info( "Out of %s fingerprints, %s appear to indicate different virtual hosts for service %s." % (len(fingerprint_results), len(vhost_domains), network_service_uuid)) network_service_scan = self.network_service_scan for hostname, discovery_method in vhost_domains: vhost_model = VirtualHostModel.from_database_model( database_model=network_service_scan, hostname=hostname, discovery_method=discovery_method, ) vhost_model.save(org_uuid) base_model = VirtualHostModel.from_database_model( database_model=network_service_scan, hostname=base_hostname, discovery_method="baseline", ) base_model.save(org_uuid) logger.info( "Elasticsearch updated to reflect results of processing virtual host fingerprints for service %s, " "scan %s, organization %s." % (network_service_uuid, network_service_scan_uuid, org_uuid))