def testCaseInsensitivitiy(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/AaA"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertLen(results, 1) self.assertEqual(results[0].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa") self.assertEqual(results[0].stat_entry.pathspec.pathtype, "REGISTRY")
def _GlobForPaths(self, paths): 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): request = rdf_file_finder.FileFinderArgs( paths=paths, action=self.stat_action, follow_links=True, pathtype=rdf_paths.PathSpec.PathType.REGISTRY) return list(client_file_finder.GetExpandedPaths(request))
def testStatRecursiveGlobDefaultLevel(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/**/aaa"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertCountEqual( [res.stat_entry.pathspec.path for res in results], [ "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/1/aaa", "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/1/2/aaa", "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/1/2/3/aaa", ])
def testStatExactPathInWindowsNativeFormat(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=[r"HKEY_LOCAL_MACHINE\SOFTWARE\GRR_TEST\aaa"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertLen(results, 1) self.assertEqual(results[0].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa") self.assertEqual(results[0].stat_entry.pathspec.pathtype, "REGISTRY") self.assertEqual(results[0].stat_entry.st_size, 6)
def testStatKeyWithDefaultValue(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/1"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertLen(results, 1) self.assertEqual(results[0].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/1") self.assertEqual(results[0].stat_entry.pathspec.pathtype, "REGISTRY") self.assertEqual(results[0].stat_entry.st_size, 13)
def testDownloadExactPath(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction( action_type="DOWNLOAD"))) self.assertLen(results, 2) self.assertEqual(_DecodeDataBlob(results[0]), "lolcat") self.assertEqual(results[1].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa")
def testQuestionMarkIsWildcard(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/a?a"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertCountEqual( [res.stat_entry.pathspec.path for res in results], [ "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa", "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aba", ])
def testHuntViewDoesShowsNothingForRapidLikeHuntWithClientRateNon0(self): hunt_id = self.StartHunt( flow_runner_args=rdf_flow_runner.FlowRunnerArgs( flow_name=file_finder.FileFinder.__name__), flow_args=rdf_file_finder.FileFinderArgs(paths=["/tmp/foo"]), client_rate=42) self.Open("/#/hunts/%s" % hunt_id) self.WaitUntil(self.IsElementPresent, "css=dt:contains('Client Rate')") self.WaitUntilNot( self.IsElementPresent, "css=dt:contains('Client Rate') + " "dd:contains('rapid hunting')")
def testMetadataConditionMatch(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/*"], pathtype="REGISTRY", conditions=[ rdf_file_finder.FileFinderCondition.Size(min_file_size=6, max_file_size=6) ], action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertCountEqual( [res.stat_entry.pathspec.path for res in results], ["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa"])
def testSkipsIfMetadataConditionDoesNotMatch(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/*"], pathtype="REGISTRY", conditions=[ rdf_file_finder.FileFinderCondition.Size(min_file_size=6, max_file_size=6), rdf_file_finder.FileFinderCondition.Size(min_file_size=0, max_file_size=0), ], action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertEmpty(results)
def testSkipsIfContentConditionDoesNotMatch(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/*"], pathtype="REGISTRY", conditions=[ rdf_file_finder.FileFinderCondition.ContentsLiteralMatch( literal=b"lol"), rdf_file_finder.FileFinderCondition.ContentsLiteralMatch( literal=b"foo") ], action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertEmpty(results)
def _ProcessFileSource(self, args): if args.path_type != rdf_paths.PathSpec.PathType.OS: raise ValueError("Only supported path type is OS.") file_finder_action = rdf_file_finder.FileFinderAction.Stat() request = rdf_file_finder.FileFinderArgs( paths=args.base_source.attributes["paths"], pathtype=args.path_type, action=file_finder_action) action = file_finder.FileFinderOS yield action, request
def _RunFileFinder(self, paths, action, conditions=None, follow_links=True, **kw): return self.RunAction(client_file_finder.FileFinderOS, arg=rdf_file_finder.FileFinderArgs( paths=paths, action=action, conditions=conditions, process_non_regular_files=True, follow_links=follow_links, **kw))
def _ProcessFileSource(self, source): """Glob paths and return StatEntry objects.""" if source.path_type != rdf_paths.PathSpec.PathType.OS: raise ValueError("Only supported path type is OS.") paths = self._InterpolateMany(source.base_source.attributes["paths"]) file_finder_action = rdf_file_finder.FileFinderAction.Stat() request = rdf_file_finder.FileFinderArgs( paths=paths, pathtype=source.path_type, action=file_finder_action) action = file_finder.FileFinderOSFromClient yield action, request
def testStatLongUnicodeName(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=[ "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/{}".format( _LONG_KEY) ], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertLen(results, 1) self.assertEqual( results[0].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/{}".format(_LONG_KEY)) self.assertEqual(results[0].stat_entry.pathspec.pathtype, "REGISTRY")
def _ProcessGrepSource(self, source): """Find files fulfilling regex conditions.""" attributes = source.base_source.attributes paths = self._InterpolateMany(attributes["paths"]) regex = utils.RegexListDisjunction(attributes["content_regex_list"]) condition = rdf_file_finder.FileFinderCondition.ContentsRegexMatch( regex=regex, mode="ALL_HITS") file_finder_action = rdf_file_finder.FileFinderAction.Stat() request = rdf_file_finder.FileFinderArgs(paths=paths, action=file_finder_action, conditions=[condition], follow_links=True) action = file_finder.FileFinderOSFromClient yield action, request
def testHashExactPath(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction.Hash())) self.assertLen(results, 1) self.assertEqual(results[0].hash_entry.num_bytes, 6) self.assertEqual(results[0].hash_entry.md5.HexDigest(), hashlib.md5(b"lolcat").hexdigest()) self.assertEqual(results[0].hash_entry.sha1.HexDigest(), hashlib.sha1(b"lolcat").hexdigest()) self.assertEqual(results[0].hash_entry.sha256.HexDigest(), hashlib.sha256(b"lolcat").hexdigest())
def testListRootDirectory(self): with mock.patch.object(client_utils, "GetRawDevice", new=self._MockGetRawDevice): results = _RunFileFinder( rdf_file_finder.FileFinderArgs( paths=[self._paths_expr], pathtype=self.pathtype, action=rdf_file_finder.FileFinderAction.Stat())) names = [ result.stat_entry.pathspec.nested_path.path for result in results ] self.assertIn("/numbers.txt", names) files.FlushHandleCache()
def testHuntViewShowsEligibilityNoteForNonRapidHuntWithClientRate0(self): # CreateHunt sets client rate to 0. Thus we have a non-eligible hunt: # FileFinder with a recursive glob expression and client rate 0. hunt_id = self.StartHunt( flow_runner_args=rdf_flow_runner.FlowRunnerArgs( flow_name=file_finder.FileFinder.__name__), flow_args=rdf_file_finder.FileFinderArgs(paths=["/tmp/**"])) self.Open("/#/hunts/%s" % hunt_id) self.WaitUntil( self.IsElementPresent, "css=dt:contains('Client Rate') + " "dd:contains('is not eligible for rapid hunting')") self.assertTrue( self.GetText("css=dt:contains('Client Rate') + dd").startswith("0 "))
def testTSKFile(self): path = os.path.join(config.CONFIG["Test.data_dir"], "test_img.dd", "Test Directory", "numbers.txt") results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=[path], pathtype="TSK", action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertNotEmpty(results) last_path = results[0].stat_entry.pathspec while last_path.HasField("nested_path"): last_path = last_path.nested_path self.assertEndsWith(last_path.path, "numbers.txt") self.assertEqual(results[0].stat_entry.st_size, 3893)
def testHashTruncateExactPath(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction.Hash( max_size=5, oversized_file_policy="HASH_TRUNCATED"))) self.assertLen(results, 1) self.assertEqual(results[0].hash_entry.md5.HexDigest(), hashlib.md5(b"lolca").hexdigest()) self.assertEqual(results[0].hash_entry.sha1.HexDigest(), hashlib.sha1(b"lolca").hexdigest()) self.assertEqual(results[0].hash_entry.sha256.HexDigest(), hashlib.sha256(b"lolca").hexdigest())
def testHuntViewDoesNotShowAnythingForRapidLikeHunts(self): # CreateHunt sets client rate to 0. Thus we have a rapid-hunting-like hunt: # FileFinder without download and client rate 0. hunt_id = self.StartHunt( flow_runner_args=rdf_flow_runner.FlowRunnerArgs( flow_name=file_finder.FileFinder.__name__), flow_args=rdf_file_finder.FileFinderArgs(paths=["/tmp/evil.txt"])) self.Open("/#/hunts/%s" % hunt_id) self.WaitUntil(self.IsElementPresent, "css=dt:contains('Client Rate') + dd:contains(0)") self.WaitUntilNot( self.IsElementPresent, "css=dt:contains('Client Rate') + dd:contains('rapid hunting')")
def testNoThrottlingDoneByDefault(self): self.InitRouterConfig(self.__class__.FILE_FINDER_ROUTER_CONFIG % self.token.username) args = rdf_file_finder.FileFinderArgs( action=rdf_file_finder.FileFinderAction(action_type="STAT"), paths=["tests.plist"]).AsPrimitiveProto() client_ref = self.api.Client(client_id=self.client_id.Basename()) # Create 60 flows in a row to check that no throttling is applied. for _ in range(20): flow_obj = client_ref.CreateFlow( name=file_finder.FileFinder.__name__, args=args) self.assertEqual(flow_obj.data.state, flow_obj.data.RUNNING)
def testContentConditionMatch(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/*"], pathtype="REGISTRY", conditions=[ rdf_file_finder.FileFinderCondition.ContentsLiteralMatch( literal=b"lol") ], action=rdf_file_finder.FileFinderAction(action_type="STAT"))) self.assertCountEqual( [res.stat_entry.pathspec.path for res in results], ["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aaa"]) self.assertCountEqual([match.data for match in results[0].matches], [b"lol"])
def _ProcessFileSource(self, source): """Glob paths and return StatEntry objects.""" if source.path_type != rdf_paths.PathSpec.PathType.OS: raise ValueError("Only supported path type is OS.") paths = artifact_utils.InterpolateListKbAttributes( source.base_source.attributes["paths"], self.knowledge_base, self.ignore_interpolation_errors) file_finder_action = rdf_file_finder.FileFinderAction.Stat() request = rdf_file_finder.FileFinderArgs( paths=paths, pathtype=source.path_type, action=file_finder_action) action = file_finder.FileFinderOSFromClient yield action, request
def testFileFinderMaxFileSizeOverrideWorks(self): self.InitRouterConfig(self.__class__.FILE_FINDER_MAX_SIZE_OVERRIDE_CONFIG % self.token.username) args = rdf_file_finder.FileFinderArgs( action=rdf_file_finder.FileFinderAction(action_type="DOWNLOAD"), paths=["tests.plist"]).AsPrimitiveProto() client_ref = self.api.Client(client_id=self.client_id) flow_obj = client_ref.CreateFlow( name=file_finder.FileFinder.__name__, args=args) flow_args = self.api.types.UnpackAny(flow_obj.data.args) self.assertEqual(flow_args.action.download.max_size, 5000000) self.assertEqual(flow_args.action.download.oversized_file_policy, flow_args.action.download.SKIP)
def testDownloadDword(self): results = self.RunFileFinder( rdf_file_finder.FileFinderArgs( paths=["/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aba"], pathtype="REGISTRY", action=rdf_file_finder.FileFinderAction( action_type="DOWNLOAD"))) self.assertLen(results, 2) res_by_type = _GroupItemsByType(results) self.assertEqual(_DecodeDataBlob(res_by_type["DataBlob"][0]), "4294967295") self.assertEqual( res_by_type["FileFinderResult"][0].stat_entry.pathspec.path, "/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/aba")
def testClientFileFinderIndicatesCollectedSizeAfterCollection(self): client_ref = self.api.Client(client_id=self.client_id) args = rdf_file_finder.FileFinderArgs( paths=[os.path.join(self.base_path, "numbers.txt")], action=rdf_file_finder.FileFinderAction.Download(), follow_links=True).AsPrimitiveProto() client_ref.CreateFlow(name=file_finder.ClientFileFinder.__name__, args=args) flow_test_lib.FinishAllFlowsOnClient( self.client_id, client_mock=action_mocks.ClientFileFinderClientMock()) 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 testDownloadActionDefault(self): action = rdf_file_finder.FileFinderAction.Download() args = rdf_file_finder.FileFinderArgs( action=action, paths=[os.path.join(self.base_path, "hello.exe")], process_non_regular_files=True) transfer_store = MockTransferStore() executor = ClientActionExecutor() executor.RegisterWellKnownFlow(transfer_store) results = executor.Execute(client_file_finder.FileFinderOS, args) self.assertLen(results, 1) with open(os.path.join(self.base_path, "hello.exe"), "rb") as filedesc: actual = transfer_store.Retrieve(results[0].transferred_file) expected = filedesc.read() self.assertEqual(actual, expected)
def testDownloadActionSkip(self): action = rdf_file_finder.FileFinderAction.Download( max_size=0, oversized_file_policy="SKIP") args = rdf_file_finder.FileFinderArgs( action=action, paths=[os.path.join(self.base_path, "hello.exe")], process_non_regular_files=True) transfer_store = MockTransferStore() executor = ClientActionExecutor() executor.RegisterWellKnownFlow(transfer_store) results = executor.Execute(client_file_finder.FileFinderOS, args) self.assertEmpty(transfer_store.blobs) self.assertLen(results, 1) self.assertFalse(results[0].HasField("transferred_file")) self.assertTrue(results[0].HasField("stat_entry"))