def testLiteralMatchConditionWithHexEncodedValue(self): match = file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode.FIRST_HIT, bytes_before=10, bytes_after=10, literal="\x4D\x5A\x90") literal_condition = file_finder.FileFinderCondition( condition_type=file_finder.FileFinderCondition.Type. CONTENTS_LITERAL_MATCH, contents_literal_match=match) paths = [os.path.join(os.path.dirname(self.fixture_path), "hello.exe")] for _ in test_lib.TestFlowHelper("FileFinder", self.client_mock, client_id=self.client_id, paths=paths, pathtype=rdf_paths.PathSpec.PathType.OS, conditions=[literal_condition], token=self.token, output=self.output_path): pass # Check that the results' matches fields are correctly filled. Expecting a # match from hello.exe fd = aff4.FACTORY.Open( self.client_id.Add(self.output_path), aff4_type=collects.RDFValueCollection, token=self.token) self.assertEqual(len(fd[0].matches), 1) self.assertEqual(fd[0].matches[0].offset, 0) self.assertEqual(fd[0].matches[0].data, "MZ\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff")
def testFindsKeyWithLiteralAndModificationTimeConditions(self): modification_time = file_finder.FileFinderModificationTimeCondition( min_last_modified_time= rdfvalue.RDFDatetime().FromSecondsFromEpoch(1247546054 - 1), max_last_modified_time= rdfvalue.RDFDatetime().FromSecondsFromEpoch(1247546054 + 1)) value_literal_match = file_finder.FileFinderContentsLiteralMatchCondition( bytes_before=10, bytes_after=10, literal="Windows Sidebar\\Sidebar.exe") self.RunFlow( ["HKEY_USERS/S-1-5-20/Software/Microsoft/Windows/CurrentVersion/Run/*"], [registry.RegistryFinderCondition( condition_type= registry.RegistryFinderCondition.Type.MODIFICATION_TIME, modification_time=modification_time), registry.RegistryFinderCondition( condition_type= registry.RegistryFinderCondition.Type.VALUE_LITERAL_MATCH, value_literal_match=value_literal_match)]) results = self.GetResults() self.assertEqual(len(results), 1) # We expect Sidebar and MctAdmin keys here (see # test_data/client_fixture.py). self.assertEqual(results[0].stat_entry.aff4path, "aff4:/C.1000000000000000/registry/HKEY_USERS/S-1-5-20/" "Software/Microsoft/Windows/CurrentVersion/Run/Sidebar")
def testLiteralMatchConditionWithDifferentActions(self): expected_files = ["auth.log"] non_expected_files = ["dpkg.log", "dpkg_false.log"] match = file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode.ALL_HITS, bytes_before=10, bytes_after=10, literal="session opened for user dearjohn") literal_condition = file_finder.FileFinderCondition( condition_type=file_finder.FileFinderCondition.Type. CONTENTS_LITERAL_MATCH, contents_literal_match=match) for action in sorted(file_finder.FileFinderAction.Action.enum_dict.values( )): self.RunFlowAndCheckResults(action=action, conditions=[literal_condition], expected_files=expected_files, non_expected_files=non_expected_files) # Check that the results' matches fields are correctly filled. fd = aff4.FACTORY.Open( self.client_id.Add(self.output_path), aff4_type=collects.RDFValueCollection, token=self.token) self.assertEqual(len(fd), 1) self.assertEqual(len(fd[0].matches), 1) self.assertEqual(fd[0].matches[0].offset, 350) self.assertEqual(fd[0].matches[0].data, "session): session opened for user dearjohn by (uid=0")
def testMemoryImageLiteralMatchConditionWithSendToSocketAction(self): literal_condition = memory.MemoryCollectorCondition( condition_type=memory.MemoryCollectorCondition.Type.LITERAL_MATCH, literal_match=file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode. ALL_HITS, literal="session opened for user dearjohn")) dump_option = memory.MemoryCollectorDumpOption( option_type=memory.MemoryCollectorDumpOption.Option. WITH_LOCAL_COPY, with_local_copy=memory.MemoryCollectorWithLocalCopyDumpOption( gzip=False)) flow_urn, encrypted, decrypted = self.RunWithSendToSocket( dump_option, conditions=[literal_condition]) # Check that matches are in the collection output = aff4.FACTORY.Open(self.client_id.Add(self.output_path), aff4_type="RDFValueCollection", token=self.token) self.assertEqual(len(output), 1) self.assertEqual(output[0].offset, 350) self.assertEqual(output[0].length, 52) self.assertEqual( output[0].data, "session): session opened for user " "dearjohn by (uid=0") flow_obj = aff4.FACTORY.Open(flow_urn, token=self.token) # There was a local file, so dest_path should not be empty self.assertTrue(flow_obj.state.memory_src_path is not None) # Data should be encrypted, so they're not equal self.assertNotEqual(encrypted, self.memory_dump) # Decrypted data should be equal to the memory dump self.assertEqual(decrypted, self.memory_dump)
def testFindsKeyIfItMatchesLiteralMatchCondition(self): value_literal_match = file_finder.FileFinderContentsLiteralMatchCondition( bytes_before=10, bytes_after=10, literal="Windows Sidebar\\Sidebar.exe") self.RunFlow( ["HKEY_USERS/S-1-5-20/Software/Microsoft/Windows/CurrentVersion/Run/*"], [registry.RegistryFinderCondition( condition_type= registry.RegistryFinderCondition.Type.VALUE_LITERAL_MATCH, value_literal_match=value_literal_match)]) results = self.GetResults() self.assertEqual(len(results), 1) self.assertEqual(len(results[0].matches), 1) self.assertEqual(results[0].matches[0].offset, 15) self.assertEqual(results[0].matches[0].data, "ramFiles%\\Windows Sidebar\\Sidebar.exe /autoRun") self.assertEqual(results[0].stat_entry.aff4path, "aff4:/C.1000000000000000/registry/HKEY_USERS/S-1-5-20/" "Software/Microsoft/Windows/CurrentVersion/Run/Sidebar") self.assertEqual(results[0].stat_entry.pathspec.path, "/HKEY_USERS/S-1-5-20/Software/Microsoft/Windows/" "CurrentVersion/Run/Sidebar") self.assertEqual(results[0].stat_entry.pathspec.pathtype, rdf_paths.PathSpec.PathType.REGISTRY)
def testMemoryImageLiteralMatchConditionWithDownloadAction(self): literal_condition = memory.MemoryCollectorCondition( condition_type=memory.MemoryCollectorCondition.Type.LITERAL_MATCH, literal_match=file_finder.FileFinderContentsLiteralMatchCondition( mode= file_finder.FileFinderContentsLiteralMatchCondition.Mode.ALL_HITS, bytes_before=10, bytes_after=10, literal="session opened for user dearjohn")) dump_option = memory.MemoryCollectorDumpOption( option_type=memory.MemoryCollectorDumpOption.Option.WITH_LOCAL_COPY, with_local_copy=memory.MemoryCollectorWithLocalCopyDumpOption( gzip=False)) flow_obj = self.RunWithDownload(dump_option, conditions=[literal_condition]) # Check that matches are in the collection output = aff4.FACTORY.Open(self.client_id.Add(self.output_path), aff4_type="RDFValueCollection", token=self.token) # First item of the collection is the BufferReference, second is the # path of the downloaded self.assertEqual(len(output), 2) self.assertEqual(output[0].offset, 350) self.assertEqual(output[0].length, 52) self.assertEqual(output[0].data, "session): session opened for user " "dearjohn by (uid=0") self.assertTrue(isinstance(output[1], rdf_client.StatEntry)) self.assertTrue(flow_obj.state.memory_src_path is not None) self.assertEqual( flow_obj.state.downloaded_file, self.client_id.Add("temp").Add(flow_obj.state.memory_src_path.path)) fd = aff4.FACTORY.Open(flow_obj.state.downloaded_file, token=self.token) self.assertEqual(fd.Read(1024 * 1024), self.memory_dump)
def testLiteralMatchConditionWithDifferentActions(self): expected_files = ["auth.log"] non_expected_files = ["dpkg.log", "dpkg_false.log"] match = file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode. ALL_HITS, bytes_before=10, bytes_after=10, literal="session opened for user dearjohn") literal_condition = file_finder.FileFinderCondition( condition_type=file_finder.FileFinderCondition.Type. CONTENTS_LITERAL_MATCH, contents_literal_match=match) for action in self.CONDITION_TESTS_ACTIONS: self.RunFlowAndCheckResults(action=action, conditions=[literal_condition], expected_files=expected_files, non_expected_files=non_expected_files) # Check that the results' matches fields are correctly filled. fd = aff4.FACTORY.Open( self.last_session_id.Add(flow_runner.RESULTS_SUFFIX), aff4_type=sequential_collection.GeneralIndexedCollection, token=self.token) self.assertEqual(len(fd), 1) self.assertEqual(len(fd[0].matches), 1) self.assertEqual(fd[0].matches[0].offset, 350) self.assertEqual( fd[0].matches[0].data, "session): session opened for user dearjohn by (uid=0")
def testDoesNothingWhenConditionDoesNotMatch(self): literal_condition = memory.MemoryCollectorCondition( condition_type=memory.MemoryCollectorCondition.Type.LITERAL_MATCH, literal_match=file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode. ALL_HITS, bytes_before=10, bytes_after=10, literal="session opened for user foobar")) dump_option = memory.MemoryCollectorDumpOption( option_type=memory.MemoryCollectorDumpOption.Option. WITH_LOCAL_COPY, with_local_copy=memory.MemoryCollectorWithLocalCopyDumpOption( gzip=False)) flow_obj = self.RunWithDownload(dump_option, conditions=[literal_condition]) # Check that there are no matches with self.assertRaises(aff4.InstantiationError): aff4.FACTORY.Open(self.client_id.Add(self.output_path), aff4_type="RDFValueCollection", token=self.token) # Assert nothing got downloaded self.assertTrue("dest_path" not in flow_obj.state) self.assertTrue("downloaded_file" not in flow_obj.state)
def testFindsNothingIfNothingMatchesLiteralMatchCondition(self): value_literal_match = file_finder.FileFinderContentsLiteralMatchCondition( literal="CanNotFindMe") self.RunFlow( ["HKEY_USERS/S-1-5-20/Software/Microsoft/Windows/CurrentVersion/Run/*"], [registry.RegistryFinderCondition( condition_type= registry.RegistryFinderCondition.Type.VALUE_LITERAL_MATCH, value_literal_match=value_literal_match)]) self.AssertNoResults()
def testFileFinderListActionRaisesWithConditions(self): match = file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode. ALL_HITS, bytes_before=10, bytes_after=10, literal="session opened for user dearjohn") literal_condition = file_finder.FileFinderCondition( condition_type=file_finder.FileFinderCondition.Type. CONTENTS_LITERAL_MATCH, contents_literal_match=match) # RuntimeError: The LIST FileFinder action doesn't support conditions. with self.assertRaises(RuntimeError): self.RunFlow(action=file_finder.FileFinderAction.Action.LIST, conditions=[literal_condition])
def testMemoryImageLiteralMatchConditionWithNoAction(self): literal_condition = memory.MemoryCollectorCondition( condition_type=memory.MemoryCollectorCondition.Type.LITERAL_MATCH, literal_match=file_finder.FileFinderContentsLiteralMatchCondition( mode=file_finder.FileFinderContentsLiteralMatchCondition.Mode. ALL_HITS, literal="session opened for user dearjohn")) self.RunWithNoAction(conditions=[literal_condition]) output = aff4.FACTORY.Open(self.client_id.Add(self.output_path), aff4_type="RDFValueCollection", token=self.token) self.assertEqual(len(output), 1) self.assertEqual(output[0].offset, 350) self.assertEqual(output[0].length, 52) self.assertEqual( output[0].data, "session): session opened for user " "dearjohn by (uid=0")
def testCopyHuntHandlesLiteralExpressionCorrectly(self): """Literals are raw bytes. Testing that raw bytes are processed right.""" literal_match = file_finder.FileFinderContentsLiteralMatchCondition( literal="foo\x0d\xc8bar") with self.ACLChecksDisabled(): hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description="model hunt", flow_runner_args=rdf_flows.FlowRunnerArgs( flow_name=file_finder.FileFinder.__name__), flow_args=file_finder.FileFinderArgs(conditions=[ file_finder.FileFinderCondition( condition_type="CONTENTS_LITERAL_MATCH", contents_literal_match=literal_match) ], paths=["/tmp/evil.txt"]), token=self.token) self.Open("/#main=ManageHunts") self.Click("css=tr:contains('model hunt')") self.Click("css=button[name=CopyHunt]:not([disabled])") # Wait until dialog appears. self.WaitUntil(self.IsTextPresent, "What to run?") # Check that non-default values of sample hunt are prefilled. self.WaitUntilEqual( "foo\\x0d\\xc8bar", self.GetValue, "css=grr-new-hunt-wizard-form " "label:contains('Literal') ~ * input:text") # Click on "Next" button. self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Output Processing") # Click on "Next" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Where to run?") # Click on "Next" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Review") # Check that the arguments summary is present. self.WaitUntil(self.IsTextPresent, file_finder.FileFinder.__name__) self.WaitUntil(self.IsTextPresent, "foo\\x0d\\xc8bar") # Click on "Run" button self.Click("css=grr-new-hunt-wizard-form button.Next") self.WaitUntil(self.IsTextPresent, "Created Hunt") # Close the window and check that the hunt was created. self.Click("css=button.Next") hunts_root = aff4.FACTORY.Open("aff4:/hunts", token=self.token) hunts_list = sorted(list(hunts_root.ListChildren()), key=lambda x: x.age) self.assertEqual(len(hunts_list), 2) last_hunt = aff4.FACTORY.Open(hunts_list[-1], token=self.token) # Check that the hunt was created with a correct literal value. self.assertEqual(last_hunt.args.flow_runner_args.flow_name, file_finder.FileFinder.__name__) self.assertEqual( last_hunt.args.flow_args.conditions[0].contents_literal_match. literal, "foo\x0d\xc8bar")