def testWriteArtifactWithSources(self): file_source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, conditions=["os_major_version < 6"], attributes={ "paths": ["/tmp/foo", "/tmp/bar"], }) registry_key_source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.REGISTRY_KEY, attributes={ "key_value_pairs": [ { "key": "HKEY_LOCAL_MACHINE\\Foo\\Bar\\Baz", "value": "Quux" }, ], }) artifact = rdf_artifacts.Artifact( name="Foo", sources=[file_source, registry_key_source], labels=["quux"], supported_os=["Windows", "Linux"], urls=["http://foobar.com/"]) self.db.WriteArtifact(artifact) self.assertEqual(self.db.ReadArtifact("Foo"), artifact)
def testReadAllArtifactsPatching(self): source0 = rdf_artifacts.ArtifactSource() source0.type = rdf_artifacts.ArtifactSource.SourceType.PATH source0.attributes = { b"paths": ["norf/thud"], } source1 = rdf_artifacts.ArtifactSource() source1.type = rdf_artifacts.ArtifactSource.SourceType.COMMAND source1.attributes = { b"cmd": "quux", b"args": ["foo", "bar"], } artifact = rdf_artifacts.Artifact() artifact.name = "foobar" artifact.sources = [source0, source1] self.db.WriteArtifact(artifact) artifacts = self.db.ReadAllArtifacts() self.assertLen(artifacts, 1) self.assertEqual(artifacts[0].sources[0].attributes["paths"], ["norf/thud"]) self.assertEqual(artifacts[0].sources[1].attributes["cmd"], "quux") self.assertEqual(artifacts[0].sources[1].attributes["args"], ["foo", "bar"]) # Should not raise. artifacts[0].sources[0].Validate() artifacts[0].sources[1].Validate()
def testConditions(self): """Test we can get a GRR client artifact with conditions.""" client_id = self.SetupClient(0, system="Linux") with utils.Stubber(psutil, "process_iter", ProcessIter): # Run with false condition. client_mock = action_mocks.ActionMock(standard.ListProcesses) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, conditions=["os == 'Windows'"]) self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertEmpty(results) # Now run with matching or condition. coll1.conditions = ["os == 'Linux' or os == 'Windows'"] self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertTrue(results) # Now run with impossible or condition. coll1.conditions.append("os == 'NotTrue'") self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertLen(results, 0) self.assertEmpty(results)
def testGetArtifact(self): """Test we can get a basic artifact.""" client_mock = action_mocks.FileFinderClientMock() client_id = self.SetupClient(0, system="Linux") # Dynamically add an ArtifactSource specifying the base path. file_path = os.path.join(self.base_path, "test_img.dd") coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, attributes={"paths": [file_path]}) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] flow_test_lib.TestFlowHelper(aff4_flows.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, use_tsk=False, token=self.token, client_id=client_id) # Test the AFF4 file that was created. fd1 = aff4.FACTORY.Open("%s/fs/os/%s" % (client_id, file_path), token=self.token) fd2 = open(file_path, "rb") fd2.seek(0, 2) self.assertEqual(fd2.tell(), int(fd1.Get(fd1.Schema.SIZE)))
def testGrep(self): class MockCallFlow(object): def CallFlow(self, *args, **kwargs): self.args = args self.kwargs = kwargs mock_call_flow = MockCallFlow() with utils.Stubber(aff4_flows.ArtifactCollectorFlow, "CallFlow", mock_call_flow.CallFlow): collect_flow = aff4_flows.ArtifactCollectorFlow(None, token=self.token) collect_flow.args = mock.Mock() collect_flow.args.ignore_interpolation_errors = False kb = rdf_client.KnowledgeBase() kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) collect_flow.state["knowledge_base"] = kb collect_flow.current_artifact_name = "blah" collector = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GREP, attributes={ "paths": ["/etc/passwd"], "content_regex_list": [r"^a%%users.username%%b$"] }) collect_flow.Grep(collector, rdf_paths.PathSpec.PathType.TSK) conditions = mock_call_flow.kwargs["conditions"] self.assertLen(conditions, 1) regexes = conditions[0].contents_regex_match.regex.SerializeToString() self.assertCountEqual(regexes.split("|"), ["(^atest1b$)", "(^atest2b$)"]) self.assertEqual(mock_call_flow.kwargs["paths"], ["/etc/passwd"])
def testGRRClientActionEnumerateUsers(self): """Test the GRR Client Action EnumerateUsers.""" def MockedOpen(requested_path, mode="rb"): try: fixture_path = os.path.join(self.base_path, "VFSFixture", requested_path.lstrip("/")) return __builtin__.open.old_target(fixture_path, mode) except IOError: return __builtin__.open.old_target(requested_path, mode) source = rdf_artifact.ArtifactSource( type=rdf_artifact.ArtifactSource.SourceType.GRR_CLIENT_ACTION) ext_src = rdf_artifact.ExpandedSource(base_source=source) ext_art = rdf_artifact.ExpandedArtifact( name="TestClientActionArtifact", sources=[ext_src]) request = rdf_artifact.ClientArtifactCollectorArgs(artifacts=[ext_art], apply_parsers=False) source.attributes["client_action"] = "EnumerateUsers" with utils.MultiStubber((__builtin__, "open", MockedOpen), (glob, "glob", lambda x: ["/var/log/wtmp"])): result = self.RunAction(artifact_collector.ArtifactCollector, request)[0] collected_artifact = result.collected_artifacts[0] self.assertEqual(len(collected_artifact.action_results), 4) for action_result in collected_artifact.action_results: value = action_result.value self.assertIsInstance(value, rdf_client.User) if value.username not in ["user1", "user2", "user3", "utuser"]: self.fail("Unexpected user found: %s" % result.username)
def testSupportedOS(self): """Test supported_os inside the collector object.""" with utils.Stubber(psutil, "process_iter", ProcessIter): # Run with false condition. client_mock = action_mocks.ActionMock(standard.ListProcesses) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, supported_os=["Windows"]) self.fakeartifact.sources.append(coll1) fd = self._RunClientActionArtifact(client_mock, ["FakeArtifact"]) self.assertEqual(fd.__class__, sequential_collection.GeneralIndexedCollection) self.assertEqual(len(fd), 0) # Now run with matching or condition. coll1.conditions = [] coll1.supported_os = ["Linux", "Windows"] self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) fd = self._RunClientActionArtifact(client_mock, ["FakeArtifact"]) self.assertEqual(fd.__class__, sequential_collection.GeneralIndexedCollection) self.assertNotEqual(len(fd), 0) # Now run with impossible or condition. coll1.conditions = ["os == 'Linux' or os == 'Windows'"] coll1.supported_os = ["NotTrue"] self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) fd = self._RunClientActionArtifact(client_mock, ["FakeArtifact"]) self.assertEqual(fd.__class__, sequential_collection.GeneralIndexedCollection) self.assertEqual(len(fd), 0)
def testDirectoryArtifact(self): """Test the source type `DIRECTORY`.""" paths = [ os.path.join(self.base_path, "%%Users.username%%*"), os.path.join(self.base_path, "VFSFixture", "var", "*", "wtmp") ] expected = [ os.path.join(self.base_path, "test.plist"), os.path.join(self.base_path, "test_img.dd"), os.path.join(self.base_path, "tests"), os.path.join(self.base_path, "tests_long"), os.path.join(self.base_path, "syslog"), os.path.join(self.base_path, "syslog_compress.gz"), os.path.join(self.base_path, "syslog_false.gz"), os.path.join(self.base_path, "VFSFixture", "var", "log", "wtmp"), ] source = rdf_artifact.ArtifactSource(type=self.source_type.DIRECTORY, attributes={"paths": paths}) knowledge_base = rdf_client.KnowledgeBase(users=[ rdf_client.User(username="******"), rdf_client.User(username="******") ]) request = GetRequest(source, "TestDirectory", knowledge_base) collected_artifact = self.RunArtifactCollector(request) self.assertGreater(len(collected_artifact.action_results), 0) for file_stat in collected_artifact.action_results: self.assertIsInstance(file_stat.value, rdf_client_fs.StatEntry) self.assertIn(file_stat.value.pathspec.path, expected)
def testSupportedOS(self): """Test supported_os inside the collector object.""" client_id = self.SetupClient(0, system="Linux") with utils.Stubber(psutil, "process_iter", ProcessIter): # Run with false condition. client_mock = action_mocks.ActionMock(standard.ListProcesses) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, supported_os=["Windows"]) self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertEmpty(results) # Now run with matching or condition. coll1.conditions = [] coll1.supported_os = ["Linux", "Windows"] self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertTrue(results) # Now run with impossible or condition. coll1.conditions = ["os == 'Linux' or os == 'Windows'"] coll1.supported_os = ["NotTrue"] self.fakeartifact.sources = [] self.fakeartifact.sources.append(coll1) results = self._RunClientActionArtifact(client_id, client_mock, ["FakeArtifact"]) self.assertEmpty(results)
def testReadArtifactPatching(self): source = rdf_artifacts.ArtifactSource() source.type = rdf_artifacts.ArtifactSource.SourceType.GREP source.attributes = { b"paths": ["foo/bar", "norf/thud"], b"content_regex_list": ["ba[rz]"], } artifact = rdf_artifacts.Artifact() artifact.name = "foobar" artifact.sources = [source] self.db.WriteArtifact(artifact) artifact = self.db.ReadArtifact("foobar") self.assertLen(artifact.sources, 1) source = artifact.sources[0] source.Validate() # Should not raise. self.assertEqual(source.attributes["paths"], ["foo/bar", "norf/thud"]) self.assertEqual(source.attributes["content_regex_list"], ["ba[rz]"]) # Should not raise. source.Validate() self.assertEqual(artifact, self.db.ReadArtifact("foobar"))
def testRunGrrClientActionArtifactSplit(self): """Test that artifacts get split into separate collections.""" with utils.Stubber(psutil, "process_iter", ProcessIter): client_mock = action_mocks.ActionMock(standard.ListProcesses) client = aff4.FACTORY.Open(self.client_id, token=self.token, mode="rw") client.Set(client.Schema.SYSTEM("Linux")) client.Flush() coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}) self.fakeartifact.sources.append(coll1) self.fakeartifact2.sources.append(coll1) artifact_list = ["FakeArtifact", "FakeArtifact2"] session_id = flow_test_lib.TestFlowHelper( aff4_flows.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=self.client_id, split_output_by_artifact=True) # Check that we got two separate collections based on artifact name fd = aff4_flows.ArtifactCollectorFlow.ResultCollectionForArtifact( session_id, "FakeArtifact") self.assertTrue(isinstance(list(fd)[0], rdf_client.Process)) self.assertEqual(len(fd), 1) fd = aff4_flows.ArtifactCollectorFlow.ResultCollectionForArtifact( session_id, "FakeArtifact2") self.assertEqual(len(fd), 1) self.assertTrue(isinstance(list(fd)[0], rdf_client.Process))
def testArtifactCollectorIndicatesCollectedSizeAfterCollection(self): registry_stub = artifact_registry.ArtifactRegistry() source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, attributes={ "paths": [os.path.join(self.base_path, "numbers.txt")], }) artifact = rdf_artifacts.Artifact( name="FakeArtifact", sources=[source], doc="fake artifact doc") registry_stub.RegisterArtifact(artifact) client_ref = self.api.Client(client_id=self.client_id) with mock.patch.object(artifact_registry, "REGISTRY", registry_stub): args = rdf_artifacts.ArtifactCollectorFlowArgs( artifact_list=["FakeArtifact"]).AsPrimitiveProto() client_ref.CreateFlow( name=collectors.ArtifactCollectorFlow.__name__, args=args) client_mock = action_mocks.FileFinderClientMock() flow_test_lib.FinishAllFlowsOnClient( self.client_id, client_mock=client_mock) f = client_ref.File("fs/os" + os.path.join(self.base_path, "numbers.txt")).Get() self.assertNotEqual(f.data.hash.sha256, b"") self.assertGreater(f.data.hash.num_bytes, 0) self.assertGreater(f.data.last_collected, 0) self.assertGreater(f.data.last_collected_size, 0)
def testFileArtifactWithParser(self): artifact_list = ["TestFileArtifact"] file_path = os.path.join(self.base_path, "numbers.txt") source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, attributes={"paths": [file_path]}) artifact_obj = artifact_registry.REGISTRY.GetArtifact( "TestFileArtifact") artifact_obj.sources.append(source) # Run the ArtifactCollector to get the expected result. session_id = flow_test_lib.TestFlowHelper( collectors.ArtifactCollectorFlow.__name__, action_mocks.FileFinderClientMock(), artifact_list=artifact_list, token=self.token, apply_parsers=True, client_id=self.client_id) expected = flow.GRRFlow.ResultCollectionForFID(session_id)[0] self.assertIsInstance(expected, rdf_protodict.AttributedDict) self.assertEquals(expected.filename, file_path) self.assertEqual(len(expected.users), 1000) # Run the ClientArtifactCollector to get the actual result. result = self._RunFlow(collectors.ClientArtifactCollector, artifact_collector.ArtifactCollector, artifact_list, apply_parsers=True)[0] self.assertEqual(len(result.collected_artifacts), 1) result = result.collected_artifacts[0].action_results[0].value self.assertEqual(result, expected)
def testRegistryDefaultValueArtifact(self): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.REGISTRY, vfs_test_lib.FakeRegistryVFSHandler): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.OS, vfs_test_lib.FakeFullVFSHandler): client_mock = action_mocks.ActionMock(standard.GetFileStat) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType. REGISTRY_VALUE, attributes={ "key_value_pairs": [{ "key": (r"HKEY_LOCAL_MACHINE/SOFTWARE/ListingTest"), "value": "" }] }) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] session_id = flow_test_lib.TestFlowHelper( collectors.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=self.client_id) fd = flow.GRRFlow.ResultCollectionForFID(session_id) self.assertTrue(isinstance(list(fd)[0], rdf_client.StatEntry)) self.assertEqual(fd[0].registry_data.GetValue(), "DefaultValue")
def testRegistryValueArtifact(self): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.REGISTRY, vfs_test_lib.FakeRegistryVFSHandler): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.OS, vfs_test_lib.FakeFullVFSHandler): client_mock = action_mocks.ActionMock(standard.GetFileStat) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType. REGISTRY_VALUE, attributes={ "key_value_pairs": [{ "key": (r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet" r"\Control\Session Manager"), "value": "BootExecute" }] }) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] session_id = flow_test_lib.TestFlowHelper( collectors.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=self.client_id) # Test the statentry got stored. fd = flow.GRRFlow.ResultCollectionForFID(session_id) self.assertTrue(isinstance(list(fd)[0], rdf_client.StatEntry)) urn = fd[0].pathspec.AFF4Path(self.client_id) self.assertTrue(str(urn).endswith("BootExecute"))
def testRegistryDefaultValueArtifact(self): client_id = self.SetupClient(0, system="Linux") with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.REGISTRY, vfs_test_lib.FakeRegistryVFSHandler): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.OS, vfs_test_lib.FakeFullVFSHandler): client_mock = action_mocks.ActionMock(standard.GetFileStat) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType. REGISTRY_VALUE, attributes={ "key_value_pairs": [{ "key": (r"HKEY_LOCAL_MACHINE/SOFTWARE/ListingTest"), "value": "" }] }) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] session_id = flow_test_lib.TestFlowHelper( aff4_flows.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=client_id) results = flow_test_lib.GetFlowResults(client_id, session_id) self.assertIsInstance(results[0], rdf_client_fs.StatEntry) self.assertEqual(results[0].registry_data.GetValue(), "DefaultValue")
def testRunGrrClientActionArtifact(self): """Test we can get a GRR client artifact.""" with utils.Stubber(psutil, "process_iter", ProcessIter): client_mock = action_mocks.ActionMock(standard.ListProcesses) client = aff4.FACTORY.Open(self.client_id, token=self.token, mode="rw") client.Set(client.Schema.SYSTEM("Linux")) client.Flush() coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] session_id = flow_test_lib.TestFlowHelper( aff4_flows.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=self.client_id) fd = flow.GRRFlow.ResultCollectionForFID(session_id) self.assertTrue(isinstance(list(fd)[0], rdf_client.Process)) self.assertTrue(len(fd) == 1)
def testPrepareArtifactFilesClientArtifactCollectorArgs(self): """Test the preparation of ArtifactFiles Args.""" artifact_list = ["TestArtifactFilesArtifact"] self.SetOS("Linux") file_path = os.path.join(self.base_path, "numbers.txt") source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, attributes={"paths": [file_path]}) artifact_obj = artifact_registry.REGISTRY.GetArtifact( "TestFileArtifact") artifact_obj.sources.append(source) args = self.ArtifactCollectorArgs(artifact_list) art_obj = args.artifacts[0] self.assertEqual(art_obj.name, "TestArtifactFilesArtifact") source = art_obj.sources[0] self.assertEqual(source.base_source.type, "ARTIFACT_FILES") sub_artifact_source = source.artifact_sources[0] self.assertEqual(sub_artifact_source.base_source.type, "FILE")
def testRegistryValueArtifact(self): client_id = self.SetupClient(0, system="Linux") with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.REGISTRY, vfs_test_lib.FakeRegistryVFSHandler): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.OS, vfs_test_lib.FakeFullVFSHandler): client_mock = action_mocks.ActionMock(standard.GetFileStat) coll1 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType. REGISTRY_VALUE, attributes={ "key_value_pairs": [{ "key": (r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet" r"\Control\Session Manager"), "value": "BootExecute" }] }) self.fakeartifact.sources.append(coll1) artifact_list = ["FakeArtifact"] session_id = flow_test_lib.TestFlowHelper( aff4_flows.ArtifactCollectorFlow.__name__, client_mock, artifact_list=artifact_list, token=self.token, client_id=client_id) # Test the statentry got stored. results = flow_test_lib.GetFlowResults(client_id, session_id) self.assertIsInstance(results[0], rdf_client_fs.StatEntry) self.assertTrue( results[0].pathspec.CollapsePath().endswith("BootExecute"))
def testRegistryValueArtifact(self): """Test the basic Registry Value collection.""" with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.REGISTRY, vfs_test_lib.FakeRegistryVFSHandler): with vfs_test_lib.VFSOverrider(rdf_paths.PathSpec.PathType.OS, vfs_test_lib.FakeFullVFSHandler): source = rdf_artifact.ArtifactSource( type=rdf_artifact.ArtifactSource.SourceType.REGISTRY_VALUE, attributes={ "key_value_pairs": [{ "key": (r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet" r"\Control\Session Manager"), "value": "BootExecute" }] }) ext_src = rdf_artifact.ExtendedSource(base_source=source) ext_art = rdf_artifact.ExtendedArtifact( name="FakeRegistryValue", sources=[ext_src]) request = rdf_artifact.ClientArtifactCollectorArgs( artifacts=[ext_art], apply_parsers=False) result = self.RunAction(artifact_collector.ArtifactCollector, request)[0] collected_artifact = list(result.collected_artifacts)[0] file_stat = list(collected_artifact.action_results)[0].value self.assertTrue(isinstance(file_stat, rdf_client.StatEntry)) urn = file_stat.pathspec.AFF4Path(self.SetupClient(0)) self.assertTrue(str(urn).endswith("BootExecute"))
def testAggregatedArtifact(self): """Test we can collect an ARTIFACT_GROUP.""" client_test_lib.Command("/bin/echo", args=["1"]) artifact_list = ["TestArtifactGroup"] file_path = os.path.join(self.base_path, "numbers.txt") source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.FILE, attributes={"paths": [file_path]}) artifact_obj = artifact_registry.REGISTRY.GetArtifact("TestFileArtifact") artifact_obj.sources.append(source) results = self._RunFlow( collectors.ClientArtifactCollector, artifact_collector.ArtifactCollector, artifact_list, apply_parsers=False) self.assertEqual(len(results), 1) result = results[0] self.assertIsInstance(result, rdf_artifacts.ClientArtifactCollectorResult) self.assertEqual(len(result.collected_artifacts), 1) collected_artifact = result.collected_artifacts[0] self.assertEqual(collected_artifact.name, "TestArtifactGroup") self.assertEqual(len(collected_artifact.action_results), 2) self.assertIsInstance(collected_artifact.action_results[0].value, rdf_client_fs.StatEntry) self.assertIsInstance(collected_artifact.action_results[1].value, rdf_client_action.ExecuteResponse) self.assertEqual(collected_artifact.action_results[1].value.stdout, "1\n")
def testUnicodeValues(self): foo_artifact_source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": "FooAction"}) foo_artifact = rdf_artifacts.Artifact(name="Foo", doc="Foo bar baz.", sources=[foo_artifact_source], provides=["os"], labels=["System"], supported_os=["Linux"]) with artifact_test_lib.PatchCleanArtifactRegistry(): artifact_registry.REGISTRY.RegisterArtifact(foo_artifact) with test_lib.ConfigOverrider( {"Artifacts.knowledge_base": ["Foo"]}): session_id = flow_test_lib.TestFlowHelper( artifact.KnowledgeBaseInitializationFlow.__name__, client_mock=action_mocks.ActionMock(FooAction), client_id=test_lib.TEST_CLIENT_ID, token=self.token) results = flow_test_lib.GetFlowResults(test_lib.TEST_CLIENT_ID, session_id) self.assertLen(results, 1) self.assertEqual(results[0].os, "zażółć gęślą jaźń 🎮")
def testCollect(self): data_store.REL_DB.WriteClientMetadata( client_id=ClientTest.FAKE_CLIENT_ID, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot( client_id=ClientTest.FAKE_CLIENT_ID) client.knowledge_base.os = 'test-os' data_store.REL_DB.WriteClientSnapshot(client) with mock.patch.object(artifact_registry, 'REGISTRY', artifact_registry.ArtifactRegistry()): source = rdf_artifacts.ArtifactSource( type=artifact_pb2.ArtifactSource.COMMAND, attributes={ 'cmd': '/bin/echo', 'args': ['1'] }) artifact = rdf_artifacts.Artifact(name='FakeArtifact', sources=[source], doc='fake artifact doc') artifact_registry.REGISTRY.RegisterArtifact(artifact) client = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) results = client.collect('FakeArtifact') self.assertNotEmpty(results) self.assertEqual(results[0].stdout, b'1\n')
def testCmdArtifactAction(self): """Test the actual client action with parsers.""" client_test_lib.Command("/bin/echo", args=["1"]) source = rdf_artifact.ArtifactSource( type=rdf_artifact.ArtifactSource.SourceType.COMMAND, attributes={ "cmd": "/bin/echo", "args": ["1"] }) ext_src = rdf_artifact.ExpandedSource(base_source=source) ext_art = rdf_artifact.ExpandedArtifact(name="TestEchoCmdArtifact", sources=[ext_src]) request = rdf_artifact.ClientArtifactCollectorArgs( artifacts=[ext_art], knowledge_base=None, ignore_interpolation_errors=True, apply_parsers=True) result = self.RunAction(artifact_collector.ArtifactCollector, request)[0] self.assertIsInstance(result, rdf_artifact.ClientArtifactCollectorResult) self.assertTrue(len(result.collected_artifacts), 1) res = result.collected_artifacts[0].action_results[0].value self.assertIsInstance(res, rdf_client.SoftwarePackage) self.assertEqual(res.description, "1\n")
def testGRRClientActionEnumerateUsers(self): """Test the GRR Client Action EnumerateUsers.""" def MockedOpen(requested_path, mode="rb"): try: fixture_path = os.path.join(self.base_path, "VFSFixture", requested_path.lstrip("/")) return __builtin__.open.old_target(fixture_path, mode) except IOError: return __builtin__.open.old_target(requested_path, mode) source = rdf_artifact.ArtifactSource( type=self.source_type.GRR_CLIENT_ACTION, attributes={"client_action": "EnumerateUsers"}) request = self.GetRequest(source, "TestClientActionArtifact") with utils.MultiStubber((__builtin__, "open", MockedOpen), (glob, "glob", lambda x: ["/var/log/wtmp"])): result = self.RunAction(artifact_collector.ArtifactCollector, request)[0] collected_artifact = result.collected_artifacts[0] self.assertEqual(len(collected_artifact.action_results), 4) for action_result in collected_artifact.action_results: value = action_result.value self.assertIsInstance(value, rdf_client.User) if value.username not in ["user1", "user2", "user3", "utuser"]: self.fail("Unexpected user found: %s" % value.username) # Test that the users were added to the knowledge base self.assertEqual(len(result.knowledge_base.users), 4) for user in result.knowledge_base.users: self.assertIn(user.username, ["user1", "user2", "user3", "utuser"])
def testValidateRegistrykey(self): source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.REGISTRY_KEY, attributes={ "keys": [r"Foo\Bar\Baz"], }) source.Validate()
def testValidateDirectory(self): source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.DIRECTORY, attributes={ "paths": ["/home", "/usr"], }) source.Validate()
def testValidateCommand(self): source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.COMMAND, attributes={ "cmd": "quux", "args": ["-foo", "-bar"], }) source.Validate()
def testSourceMeetsConditions(self): """Test we can get a GRR client artifact with conditions.""" kb = rdf_client.KnowledgeBase() kb.os = "Windows" # Run with false condition. source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, conditions=["os == 'Linux'"]) self.assertFalse(collectors.MeetsConditions(kb, source)) # Run with matching or condition. source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, conditions=["os == 'Linux' or os == 'Windows'"]) self.assertTrue(collectors.MeetsConditions(kb, source))
def testEdrAgentCollection(self): client_id = db_test_utils.InitializeClient(data_store.REL_DB) artifact_source = rdf_artifacts.ArtifactSource() artifact_source.type = rdf_artifacts.ArtifactSource.SourceType.COMMAND artifact_source.attributes = {"cmd": "/bin/echo", "args": ["1337"]} artifact = rdf_artifacts.Artifact() artifact.name = "Foo" artifact.doc = "Lorem ipsum." artifact.sources = [artifact_source] class FooParser(parsers.SingleResponseParser): supported_artifacts = ["Foo"] def ParseResponse( self, knowledge_base: rdf_client.KnowledgeBase, response: rdf_client_action.ExecuteResponse, ) -> Iterator[rdf_client.EdrAgent]: edr_agent = rdf_client.EdrAgent() edr_agent.name = "echo" edr_agent.agent_id = response.stdout.decode("utf-8") yield edr_agent class EchoActionMock(action_mocks.InterrogatedClient): def ExecuteCommand( self, args: rdf_client_action.ExecuteRequest, ) -> Iterable[rdf_client_action.ExecuteResponse]: response = rdf_client_action.ExecuteResponse() response.stdout = " ".join(args.args).encode("utf-8") response.exit_status = 0 return [response] with mock.patch.object( artifact_registry, "REGISTRY", artifact_registry.ArtifactRegistry()) as registry: registry.RegisterArtifact(artifact) with test_lib.ConfigOverrider({"Artifacts.edr_agents": ["Foo"]}): with parser_test_lib._ParserContext("Foo", FooParser): flow_test_lib.TestFlowHelper( discovery.Interrogate.__name__, client_mock=EchoActionMock(), client_id=client_id, creator=self.test_username) flow_test_lib.FinishAllFlowsOnClient(client_id) snapshot = data_store.REL_DB.ReadClientSnapshot(client_id) self.assertLen(snapshot.edr_agents, 1) self.assertEqual(snapshot.edr_agents[0].name, "echo") self.assertEqual(snapshot.edr_agents[0].agent_id, "1337")