def testCopyHuntPreservesRuleType(self): with self.ACLChecksDisabled(): hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description="model hunt", flow_runner_args=rdf_flows.FlowRunnerArgs(flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.TSK, )), client_rule_set=rdf_foreman.ForemanClientRuleSet(rules=[ rdf_foreman.ForemanClientRule( rule_type=rdf_foreman.ForemanClientRule.Type.OS, os=rdf_foreman.ForemanOsClientRule(os_darwin=True)) ]), 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?") # 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?") self.WaitUntil( self.IsElementPresent, "css=grr-new-hunt-wizard-form " "label:contains('Os darwin') ~ * input:checked")
def RunFlow(self, flow_name=None, plugins=None, flow_args=None, client_mock=None): runner_args = flow_runner.FlowRunnerArgs(flow_name=flow_name or "GetFile", output_plugins=plugins) if flow_args is None: flow_args = transfer.GetFileArgs( pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS)) if client_mock is None: client_mock = test_lib.SampleHuntMock() flow_urn = flow.GRRFlow.StartFlow(client_id=self.client_id, args=flow_args, runner_args=runner_args, token=self.token) for _ in test_lib.TestFlowHelper(flow_urn, client_mock=client_mock, client_id=self.client_id, token=self.token): pass return flow_urn
def Run(self): runner_args = rdf_flows.FlowRunnerArgs( flow_name=transfer.GetFile.__name__) flow_args = transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS)) client_mock = hunt_test_lib.SampleHuntMock() with test_lib.FakeTime(42): flow_urn = flow.GRRFlow.StartFlow(client_id=self.client_id, args=flow_args, runner_args=runner_args, token=self.token) for _ in flow_test_lib.TestFlowHelper(flow_urn, client_mock=client_mock, client_id=self.client_id, token=self.token): pass self.Check("ListFlowResults", args=flow_plugin.ApiListFlowResultsArgs( client_id=self.client_id.Basename(), flow_id=flow_urn.Basename()), replace={flow_urn.Basename(): "W:ABCDEF"})
def _AppendFlowRequest(self, flows, client_id, file_id): flows.Append( client_ids=["C.1%015d" % client_id], runner_args=flow_runner.FlowRunnerArgs(flow_name="GetFile"), args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil%s.txt" % file_id, pathtype=rdf_paths.PathSpec.PathType.OS), ))
def testCopyHuntPreservesRuleType(self): with self.ACLChecksDisabled(): hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description="model hunt", flow_runner_args=flow_runner.FlowRunnerArgs( flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.TSK, )), regex_rules=[ rdf_foreman.ForemanAttributeRegex(attribute_name="System", attribute_regex="Darwin") ], 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?") # 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?") self.WaitUntil(self.IsTextPresent, "This rule will match all OS X systems.")
def CreateSampleHunt(self, path=None, stopped=False, output_plugins=None, client_limit=0, client_count=10, token=None): token = token or self.token self.client_ids = self.SetupClients(client_count) with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=flow_runner.FlowRunnerArgs( flow_name="GetFile"), flow_args=transfer.GetFileArgs( pathspec=rdf_paths.PathSpec( path=path or "/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS, ) ), regex_rules=[rdf_foreman.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR")], output_plugins=output_plugins or [], client_rate=0, client_limit=client_limit, token=token) as hunt: if not stopped: hunt.Run() with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=token) as foreman: for client_id in self.client_ids: foreman.AssignTasksToClient(client_id) self.hunt_urn = hunt.urn return aff4.FACTORY.Open(hunt.urn, mode="rw", token=token, age=aff4.ALL_TIMES)
def testHuntExpiration(self): """This tests that hunts with a client limit terminate correctly.""" with test_lib.FakeTime(1000): with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=flow_runner.FlowRunnerArgs( flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS)), regex_rules=[ rdf_foreman.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR") ], client_limit=5, expiry_time=rdfvalue.Duration("1000s"), token=self.token) as hunt: hunt.Run() # Pretend to be the foreman now and dish out hunting jobs to all the # clients (Note we have 10 clients here). foreman = aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) for client_id in self.client_ids: foreman.AssignTasksToClient(client_id) hunt_obj = aff4.FACTORY.Open(hunt.session_id, age=aff4.ALL_TIMES, token=self.token) self.assertEqual(hunt_obj.Get(hunt_obj.Schema.STATE), "STARTED") # Now advance the time such that the hunt expires. time.time = lambda: 5000 # Run the hunt. client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, self.client_ids, check_flow_errors=False, token=self.token) # No client should be processed since the hunt is expired. started, finished, errors = hunt_obj.GetClientsCounts() self.assertEqual(started, 0) self.assertEqual(finished, 0) self.assertEqual(errors, 0) hunt_obj = aff4.FACTORY.Open(hunt.session_id, age=aff4.ALL_TIMES, token=self.token) # Hunts are automatically stopped when they expire. self.assertEqual(hunt_obj.Get(hunt_obj.Schema.STATE), "COMPLETED")
def CreateSampleHunt(description, token=None): return hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description=description, flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS, )), client_rate=0, token=token)
def _CreateHunt(self, token): return hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS)), regex_rules=[ rdf_foreman.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="GRR"), ], client_rate=0, token=token)
def CreateSampleHunt(description, token=None): hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description=description, flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.TSK, )), regex_rules=[ rdf_foreman.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="GRR") ], output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name="DummyOutputPlugin", plugin_args=DummyOutputPlugin.args_type( filename_regex="blah!", fetch_binaries=True)) ], client_rate=60, token=token)
def CreateSampleHunt(description, token=None): implementation.GRRHunt.StartHunt( hunt_name=standard.GenericHunt.__name__, description=description, flow_runner_args=rdf_flows.FlowRunnerArgs( flow_name=transfer.GetFile.__name__), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.TSK, )), client_rule_set=rdf_foreman.ForemanClientRuleSet(rules=[ rdf_foreman.ForemanClientRule( rule_type=rdf_foreman.ForemanClientRule.Type.REGEX, regex=rdf_foreman.ForemanRegexClientRule( attribute_name="GRR client", attribute_regex="GRR")) ]), output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name="DummyOutputPlugin", plugin_args=DummyOutputPlugin.args_type( filename_regex="blah!", fetch_binaries=True)) ], client_rate=60, token=token)
def Run(self): runner_args = flow_runner.FlowRunnerArgs(flow_name="GetFile") flow_args = transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS)) client_mock = test_lib.SampleHuntMock() with test_lib.FakeTime(42): flow_urn = flow.GRRFlow.StartFlow(client_id=self.client_id, args=flow_args, runner_args=runner_args, token=self.token) for _ in test_lib.TestFlowHelper(flow_urn, client_mock=client_mock, client_id=self.client_id, token=self.token): pass self.Check("GET", "/api/clients/%s/flows/%s/results" % (self.client_id.Basename(), flow_urn.Basename()), replace={flow_urn.Basename(): "W:ABCDEF"})
def testResourceUsageStats(self): client_ids = self.SetupClients(10) with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=flow_runner.FlowRunnerArgs( flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS, )), regex_rules=[ rdf_foreman.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR") ], output_plugins=[], client_rate=0, token=self.token) as hunt: hunt.Run() with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) as foreman: for client_id in client_ids: foreman.AssignTasksToClient(client_id) client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, client_ids, False, self.token) hunt = aff4.FACTORY.Open(hunt.urn, aff4_type="GenericHunt", token=self.token) # This is called once for each state method. Each flow above runs the # Start and the StoreResults methods. usage_stats = hunt.state.context.usage_stats self.assertEqual(usage_stats.user_cpu_stats.num, 10) self.assertTrue( math.fabs(usage_stats.user_cpu_stats.mean - 5.5) < 1e-7) self.assertTrue( math.fabs(usage_stats.user_cpu_stats.std - 2.8722813) < 1e-7) self.assertEqual(usage_stats.system_cpu_stats.num, 10) self.assertTrue( math.fabs(usage_stats.system_cpu_stats.mean - 11) < 1e-7) self.assertTrue( math.fabs(usage_stats.system_cpu_stats.std - 5.7445626) < 1e-7) self.assertEqual(usage_stats.network_bytes_sent_stats.num, 10) self.assertTrue( math.fabs(usage_stats.network_bytes_sent_stats.mean - 16.5) < 1e-7) self.assertTrue( math.fabs(usage_stats.network_bytes_sent_stats.std - 8.61684396) < 1e-7) # NOTE: Not checking histograms here. RunningStatsTest tests that mean, # standard deviation and histograms are calculated correctly. Therefore # if mean/stdev values are correct histograms should be ok as well. self.assertEqual(len(usage_stats.worst_performers), 10) prev = usage_stats.worst_performers[0] for p in usage_stats.worst_performers[1:]: self.assertTrue( prev.cpu_usage.user_cpu_time + prev.cpu_usage.system_cpu_time > p.cpu_usage.user_cpu_time + p.cpu_usage.system_cpu_time) prev = p
def testHuntModificationWorksCorrectly(self): """This tests running the hunt on some clients.""" with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=flow_runner.FlowRunnerArgs( flow_name="GetFile"), flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec( path="/tmp/evil.txt", pathtype=rdf_paths.PathSpec.PathType.OS), ), regex_rules=[ rdf_foreman.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR") ], client_limit=1, client_rate=0, token=self.token) as hunt: hunt.Run() # Forget about hunt object, we'll use AFF4 for everything. hunt_session_id = hunt.session_id hunt = None # Pretend to be the foreman now and dish out hunting jobs to all the # client.. with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) as foreman: for client_id in self.client_ids: foreman.AssignTasksToClient(client_id) # Run the hunt. client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, self.client_ids, False, self.token) # Re-open the hunt to get fresh data. hunt_obj = aff4.FACTORY.Open(hunt_session_id, age=aff4.ALL_TIMES, ignore_cache=True, token=self.token) # There should be only one client, due to the limit started, _, _ = hunt_obj.GetClientsCounts() self.assertEqual(started, 1) # Check the hunt is paused. self.assertEqual(hunt_obj.Get(hunt_obj.Schema.STATE), "PAUSED") with aff4.FACTORY.Open(hunt_session_id, mode="rw", token=self.token) as hunt_obj: runner = hunt_obj.GetRunner() runner.args.client_limit = 10 runner.Start() # Pretend to be the foreman now and dish out hunting jobs to all the # clients. with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.token) as foreman: for client_id in self.client_ids: foreman.AssignTasksToClient(client_id) test_lib.TestHuntHelper(client_mock, self.client_ids, False, self.token) hunt_obj = aff4.FACTORY.Open(hunt_session_id, age=aff4.ALL_TIMES, token=self.token) # There should be only one client, due to the limit started, _, _ = hunt_obj.GetClientsCounts() self.assertEqual(started, 10)