def test_child_parent_verification_event_succeeds(session, workspace): """ Asserts that no exception will be raised when workspace are the same. """ host = HostFactory.build(workspace=workspace) ServiceFactory.build(host=host, workspace=workspace) session.commit()
def test_sort_credentials_target(self, test_client, second_workspace): host = HostFactory(workspace=second_workspace, ip="192.168.1.1") service = ServiceFactory(name="http", workspace=second_workspace, host=host) host2 = HostFactory(workspace=second_workspace, ip="192.168.1.2") service2 = ServiceFactory(name="ssh", workspace=second_workspace, host=host2) credential = self.factory.create(service=service, host=None, workspace=second_workspace) credential2 = self.factory.create(service=None, host=host2, workspace=second_workspace) credential3 = self.factory.create(service=None, host=host, workspace=second_workspace) credential4 = self.factory.create(service=service2, host=None, workspace=second_workspace) credentials_target = [ "{}/{}".format(credential.service.host.ip, credential.service.name), "{}".format(credential2.host.ip), "{}".format(credential3.host.ip), "{}/{}".format(credential4.service.host.ip, credential4.service.name), ] # Desc order response = test_client.get(self.url(workspace=second_workspace) + "?sort=target&sort_dir=desc") assert response.status_code == 200 assert sorted(credentials_target, reverse=True) == [ v['value']['target'] for v in response.json['rows']] # Asc order response = test_client.get(self.url(workspace=second_workspace) + "?sort=target&sort_dir=asc") assert response.status_code == 200 assert sorted(credentials_target) == [v['value']['target'] for v in response.json['rows']]
def test_child_parent_verification_event_fails(session, workspace, second_workspace): host = HostFactory.build(workspace=workspace) ServiceFactory.build(host=host, workspace=second_workspace) with pytest.raises(AssertionError): session.commit() session.rollback() assert session.query(Host).filter( Workspace.id == workspace.id).first() == None
def test_update_with_parent_of_other_workspace(self, parent_type, parent_factory, test_client, session, second_workspace, credential_factory): parent = parent_factory.create(workspace=second_workspace) if parent_type == 'Host': credential = credential_factory.create( host=HostFactory.create(workspace=self.workspace), service=None, workspace=self.workspace) else: credential = credential_factory.create( host=None, service=ServiceFactory.create(workspace=self.workspace), workspace=self.workspace) session.commit() assert parent.workspace_id != self.workspace.id data = { "username": "******", "password": "******", "name": "test", "parent_type": parent_type, "parent": parent.id } res = test_client.put(self.url(credential), data=data) assert res.status_code == 400 assert b'Parent id not found' in res.data
def test_cannot_create_comment__with_invalid_object_type(self, test_client, session): service = ServiceFactory.create(workspace=self.workspace) session.commit() raw_comment = self._create_raw_comment('workspace', service.id) res = test_client.post(self.url(), data=raw_comment) assert res.status_code == 400 assert 'Must be one of' in res.json['messages']['object_type'][0]
def test_cannot_create_comment_of_another_workspace_object(self, test_client, session, second_workspace): service = ServiceFactory.create(workspace=self.workspace) session.commit() raw_comment = self._create_raw_comment('service', service.id) res = test_client.post(self.url(workspace=second_workspace), data=raw_comment) assert res.status_code == 400 assert res.json == {u'message': u"Can't comment object of another workspace"}
def test_child_parent_verification_event_succeds_update(session, workspace): host = HostFactory.build(workspace=workspace) service = ServiceFactory.build(host=host, workspace=workspace) session.commit() service.workspace = workspace session.add(service) session.commit()
def test_verify_created_vulns_with_host_and_service_verification( self, session, test_client): workspace = WorkspaceFactory.create() command = EmptyCommandFactory.create(workspace=workspace) host = HostFactory.create(workspace=workspace) service = ServiceFactory.create(workspace=workspace) vuln = VulnerabilityFactory.create(severity='critical', workspace=workspace, host=host, service=None) vuln_med = VulnerabilityFactory.create(severity='medium', workspace=workspace, service=service, host=None) session.flush() CommandObjectFactory.create(command=command, object_type='host', object_id=host.id, workspace=workspace) CommandObjectFactory.create(command=command, object_type='vulnerability', object_id=vuln.id, workspace=workspace) CommandObjectFactory.create(command=command, object_type='service', object_id=service.id, workspace=workspace) CommandObjectFactory.create(command=command, object_type='vulnerability', object_id=vuln_med.id, workspace=workspace) session.commit() res = test_client.get( self.url(workspace=command.workspace) + 'activity_feed/') assert res.status_code == 200 assert res.json == [{ u'_id': command.id, u'command': command.command, u'import_source': u'shell', u'tool': command.tool, u'user': command.user, u'date': time.mktime(command.start_date.timetuple()) * 1000, u'params': command.params, u'hosts_count': 1, u'services_count': 1, u'vulnerabilities_count': 2, u'criticalIssue': 1 }]
def test_get_credentials_for_a_service_backwards_compatibility(self, session, test_client): service = ServiceFactory.create() credential = self.factory.create(service=service, host=None, workspace=service.workspace) session.commit() res = test_client.get(self.url(workspace=credential.workspace) + '?service={0}'.format(credential.service.id)) assert res.status_code == 200 assert [cred['value']['parent'] for cred in res.json['rows']] == [credential.service.id] assert [cred['value']['parent_type'] for cred in res.json['rows']] == [u'Service']
def test_create_comment_from_plugins(self, test_client, session): service = ServiceFactory.create(workspace=self.workspace) session.commit() initial_comment_count = len(session.query(Comment).all()) raw_comment = self._create_raw_comment('service', service.id) res = test_client.post(self.url(workspace=self.workspace), data=raw_comment) assert res.status_code == 201 assert len(session.query(Comment).all()) == initial_comment_count + 1
def populate_workspace(workspace): host = HostFactory.create(workspace=workspace) service = ServiceFactory.create(workspace=workspace, host=host) code = SourceCodeFactory.create(workspace=workspace) # Create non confirmed vulnerabilities # Create standard vulns VulnerabilityFactory.create_batch(NC_STANDARD_VULN_COUNT[0], workspace=workspace, host=host, service=None, confirmed=False) VulnerabilityFactory.create_batch(NC_STANDARD_VULN_COUNT[1], workspace=workspace, service=service, host=None, confirmed=False) # Create web vulns VulnerabilityWebFactory.create_batch(NC_WEB_VULN_COUNT, workspace=workspace, service=service, confirmed=False) # Create source code vulns VulnerabilityCodeFactory.create_batch(NC_SOURCE_CODE_VULN_COUNT, workspace=workspace, source_code=code, confirmed=False) # Create confirmed vulnerabilities # Create standard vulns VulnerabilityFactory.create_batch(C_STANDARD_VULN_COUNT[0], workspace=workspace, host=host, service=None, confirmed=True) VulnerabilityFactory.create_batch(C_STANDARD_VULN_COUNT[1], workspace=workspace, service=service, host=None, confirmed=True) # Create web vulns VulnerabilityWebFactory.create_batch(C_WEB_VULN_COUNT, workspace=workspace, service=service, confirmed=True) # Create source code vulns VulnerabilityCodeFactory.create_batch(C_SOURCE_CODE_VULN_COUNT, workspace=workspace, source_code=code, confirmed=True) db.session.commit()
def test_child_parent_verification_event_fails_update(session, workspace, second_workspace): host = HostFactory.build(workspace=workspace) service = ServiceFactory.build(host=host, workspace=workspace) session.commit() service.workspace = second_workspace session.add(service) with pytest.raises(AssertionError): session.commit()
def test_cannot_create_comment__with_invalid_object_type( self, test_client, session): service = ServiceFactory.create(workspace=self.workspace) session.commit() raw_comment = self._create_raw_comment('workspace', service.id) res = test_client.post(self.url(), data=raw_comment) assert res.status_code == 400 assert res.json == { u'messages': { u'object_type': [u'Not a valid choice.'] } }
def test_child_parent_verification_event_changing_id_fails(session, workspace, second_workspace): session.add(workspace) session.add(second_workspace) session.commit() host = HostFactory.build(workspace=workspace) session.add(host) session.commit() service = ServiceFactory.build(host=host, workspace_id=second_workspace.id) session.add(service) with pytest.raises(AssertionError): session.commit()
def test_create_unique_comment_for_plugins_after_and_before(self, session, test_client): """ """ service = ServiceFactory.create(workspace=self.workspace) session.commit() initial_comment_count = len(session.query(Comment).all()) raw_comment = self._create_raw_comment('service', service.id) url = self.url(workspace=self.workspace).strip('/') + '_unique/' res = test_client.post(url, data=raw_comment) assert res.status_code == 201 assert len(session.query(Comment).all()) == initial_comment_count + 1 res = test_client.post(url, data=raw_comment) assert res.status_code == 409 assert 'object' in res.json assert type(res.json) == dict
def test_update_services(self, api, session, test_client): workspace = WorkspaceFactory.create() service = ServiceFactory.create(workspace=workspace, name="http", owned=False) session.add(workspace) session.add(service) session.commit() assert service.owned is False searcher = Searcher(api(workspace, test_client, session)) rules = [{ 'id': 'UPDATE_SERVICE', 'model': 'Service', 'object': "name=http", 'actions': ["--UPDATE:owned=True"] }] searcher.process(rules) service = session.query(Service).filter_by(workspace=workspace).first() assert service.owned is True
def test_delete_services(self, api, session, test_client): workspace = WorkspaceFactory.create() service = ServiceFactory.create(workspace=workspace, name="http") session.add(workspace) session.add(service) session.commit() searcher = Searcher(api(workspace, test_client, session)) rules = [{ 'id': 'DELETE_SERVICE', 'model': 'Service', 'object': "name=http", 'actions': ["--DELETE:"] }] service_count = session.query(Service).filter_by(workspace=workspace).count() assert service_count == 1 searcher.process(rules) service_count = session.query(Service).filter_by(workspace=workspace).count() assert service_count == 0
def test_multiple_commands_executed_with_same_objects_found( self, session, test_client): """ This text verifies that multiple command does not affect activity feed counters. """ workspace = WorkspaceFactory.create() host = HostFactory.create(workspace=workspace) vuln = VulnerabilityFactory.create(severity='low', workspace=workspace, host=host, service=None) service = ServiceFactory.create(workspace=workspace) commands = [] in_the_middle_commands = [] first_command = None for index in range(0, 10): command = EmptyCommandFactory.create(workspace=workspace) commands.append(command) if index > 0: # in the middle commands should not affect counters (should be at 0) in_the_middle_commands.append(command) else: first_command = command session.flush() CommandObjectFactory.create(command=command, object_type='host', object_id=host.id, workspace=workspace) CommandObjectFactory.create(command=command, object_type='vulnerability', object_id=vuln.id, workspace=workspace) # This command will change activity feed counters vuln_med = VulnerabilityFactory.create(severity='medium', workspace=workspace, service=service, host=None) session.flush() last_command = EmptyCommandFactory.create(workspace=workspace) CommandObjectFactory.create(command=last_command, object_type='service', object_id=service.id, workspace=workspace) CommandObjectFactory.create(command=last_command, object_type='vulnerability', object_id=vuln_med.id, workspace=workspace) session.commit() res = test_client.get( self.url(workspace=command.workspace) + 'activity_feed/') assert res.status_code == 200 raw_first_command = list( filter(lambda comm: comm['_id'] == commands[0].id, res.json)) assert raw_first_command.pop() == { u'_id': first_command.id, u'command': first_command.command, u'import_source': u'shell', u'user': first_command.user, u'date': time.mktime(first_command.start_date.timetuple()) * 1000, u'params': first_command.params, u'hosts_count': 1, u'services_count': 0, u'vulnerabilities_count': 1, u'tool': first_command.tool, u'criticalIssue': 0 } for in_the_middle_command in in_the_middle_commands: raw_in_the_middle_command = list( filter(lambda comm: comm['_id'] == in_the_middle_command.id, res.json)) assert raw_in_the_middle_command.pop() == { u'_id': in_the_middle_command.id, u'command': in_the_middle_command.command, u'import_source': u'shell', u'user': in_the_middle_command.user, u'date': time.mktime(in_the_middle_command.start_date.timetuple()) * 1000, u'params': in_the_middle_command.params, u'hosts_count': 0, u'tool': in_the_middle_command.tool, u'services_count': 0, u'vulnerabilities_count': 0, u'criticalIssue': 0 } # new command must create new service and vuln raw_last_command = list( filter(lambda comm: comm['_id'] == last_command.id, res.json)) assert raw_last_command.pop() == { u'_id': last_command.id, u'command': last_command.command, u'import_source': u'shell', u'user': last_command.user, u'date': time.mktime(last_command.start_date.timetuple()) * 1000, u'params': last_command.params, u'hosts_count': 0, u'tool': last_command.tool, u'services_count': 1, u'vulnerabilities_count': 1, u'criticalIssue': 0 }
def test_init_service(self): s = ServiceFactory.create() self.assertEqual('http://localhost:1234/check', s.check_url) self.assertEqual('http://localhost:1234/fetch', s.fetch_url)
def test_is_service_available(self): s = ServiceFactory.create() self.assertFalse(s.is_available)
def test_export_data_xml_metasploit_format(self, test_client, session): workspace = WorkspaceFactory.create() host = HostFactory.create(workspace=workspace, ip='127.0.0.1', os='Linux', mac='30-65-EC-6F-C4-58', description='Host for test purposes') host.set_hostnames(['localhost', 'test']) session.add(host) session.commit() # Hardcode create_date and update_date for tests purposes host.create_date = host.create_date.replace(2020, 4, 1, 20, 49, 31) host.update_date = host.update_date.replace(2020, 4, 1, 20, 49, 31) service = ServiceFactory.create(workspace=workspace, host=host, port=8080, protocol='tcp', status='open', name='Test service', version='5.0', description='Description for service') session.add(service) session.commit() # Hardcode create_date and update_date for tests purposes service.create_date = service.create_date.replace( 2020, 4, 1, 20, 49, 49) service.update_date = service.update_date.replace( 2020, 4, 1, 20, 49, 49) vuln = VulnerabilityFactory.create(workspace=workspace, host=host, service=None, name='Vulnerability test', description='Desc for testing') session.add(vuln) vuln_web = VulnerabilityWebFactory.create( workspace=workspace, service=service, name='Vulnerability Web test', description='Desc for testing web vuln', severity="high", path='faraday.com', method="GET", parameters="ABCDEF", parameter_name="qwerty", query_string="query for vuln", request="GET for vuln") session.add(vuln_web) session.commit() url = self.check_url( f'/v2/ws/{workspace.name}/export_data?format=xml_metasploit') response = test_client.get(url) assert response.status_code == 200 response_xml = response.data xml_file_path = TEST_DATA_PATH / \ 'faraday_export_data_xml_metasploit.xml' with xml_file_path.open('rb') as output: xml_file = output.read() response_tree = fromstring(response_xml) xml_file_tree = fromstring(xml_file) xpaths_list = [{ '//host': ['address', 'mac', 'name', 'comments'] }, { '//host/services/service': ['port', 'proto', 'state', 'name', 'info'] }, { '//MetasploitV4/services/service': ['port', 'proto', 'state', 'name', 'info'] }, { '//MetasploitV4/web_sites/web_site': ['vhost', 'host', 'port', 'comments', 'ssl'] }, { '//host/vulns/vuln': ['name', 'info'] }, { '//MetasploitV4/web_vulns/web_vuln': [ 'name', 'description', 'risk', 'path', 'method', 'params', 'pname', 'query', 'request', 'vhost', 'host', 'port', 'ssl' ] }] for xpath_data in xpaths_list: for xpath, tags_list in xpath_data.items(): for tag in tags_list: full_xpath = xpath + '/' + tag if full_xpath == '//host/name': # Check hostnames list order # Sometimes host.set_hostnames() switch the order of the hostnames list sent. response_hostnames = response_tree.xpath( full_xpath)[0].text xml_file_hostnames = xml_file_tree.xpath( full_xpath)[0].text if response_hostnames != xml_file_hostnames: # For testing purposes, response_hostnames list will be reordered. response_hostnames = response_hostnames.split(',') response_hostnames[0], response_hostnames[ 1] = response_hostnames[1], response_hostnames[ 0] response_tree.xpath(full_xpath)[0].text = ','.join( response_hostnames) assert response_tree.xpath( full_xpath)[0].text == xml_file_hostnames else: assert response_tree.xpath(full_xpath)[ 0].text == xml_file_tree.xpath(full_xpath)[0].text