def RunHunt(self, plugin_name, plugin_args): with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS)), regex_rules=[ rdfvalue.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="GRR") ], output_plugins=[ rdfvalue.OutputPlugin(plugin_name=plugin_name, plugin_args=plugin_args) ], client_rate=0, token=self.token) as hunt: hunt.Run() hunt.StartClients(hunt.session_id, self.client_ids) # Run the hunt. client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, self.client_ids, False, self.token) # Stop the hunt now. hunt.GetRunner().Stop() # Run cron flow that executes actual output plugins for _ in test_lib.TestFlowHelper("ProcessHuntResultsCronFlow", token=self.token): pass return hunt.urn
def CreateSampleHunt(self, stopped=False): self.client_ids = self.SetupClients(10) with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=rdfvalue.FlowRunnerArgs( flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs( pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS, ) ), regex_rules=[rdfvalue.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR")], output_plugins=[], client_rate=0, token=self.token) as hunt: if not stopped: hunt.Run() with aff4.FACTORY.Open("aff4:/foreman", mode="rw", token=self.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=self.token, age=aff4.ALL_TIMES)
def _AppendFlowRequest(self, flows, client_id, file_id): flows.Append( client_ids=["C.1%015d" % client_id], runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), args=rdfvalue.GetFileArgs( pathspec=rdfvalue.PathSpec( path="/tmp/evil%s.txt" % file_id, pathtype=rdfvalue.PathSpec.PathType.OS), ) )
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=rdfvalue.FlowRunnerArgs( flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS)), regex_rules=[ rdfvalue.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), "STOPPED")
def _CreateHunt(self, token): return hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS)), regex_rules=[ rdfvalue.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="GRR"), ], client_rate=0, token=token)
def CreateSampleHunt(description, token=None): return hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description=description, flow_runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS, )), client_rate=0, token=token)
def CreateSampleHunt(self, description): hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", description=description, flow_runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS, )), regex_rules=[], output_plugins=[], client_rate=0, token=self.token)
def testHuntTermination(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=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs( pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS) ), regex_rules=[rdfvalue.ForemanAttributeRegex( attribute_name="GRR client", attribute_regex="GRR")], client_limit=5, client_rate=0, 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) # Run the hunt. client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, self.client_ids, check_flow_errors=False, token=self.token) hunt_obj = aff4.FACTORY.Open(hunt.session_id, age=aff4.ALL_TIMES, token=self.token) started = hunt_obj.GetValuesForAttribute(hunt_obj.Schema.CLIENTS) finished = hunt_obj.GetValuesForAttribute(hunt_obj.Schema.FINISHED) errors = hunt_obj.GetValuesForAttribute(hunt_obj.Schema.ERRORS) self.assertEqual(len(set(started)), 5) self.assertEqual(len(set(finished)), 5) self.assertEqual(len(set(errors)), 2) hunt_obj = aff4.FACTORY.Open(hunt.session_id, age=aff4.ALL_TIMES, token=self.token) # Hunts are automatically paused when they reach the client limit. self.assertEqual(hunt_obj.Get(hunt_obj.Schema.STATE), "PAUSED")
def RunHunt(self, plugin_args=None, responses=None, process_responses_separately=False): if responses is None: responses = [] with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs(pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS)), regex_rules=[ rdfvalue.ForemanAttributeRegex(attribute_name="GRR client", attribute_regex="GRR"), ], client_rate=0, token=self.token) as hunt: hunt_urn = hunt.urn plugin_def = rdfvalue.OutputPlugin(plugin_name="CSVOutputPlugin", plugin_args=plugin_args) plugin = plugin_def.GetPluginForHunt(hunt) # We don't want to test the whole output plugins subsystem as it's # tested in its own tests. We only want to test logic specific to # ColumnIOHuntOutputPlugin. messages = [] for response in responses: messages.append( rdfvalue.GrrMessage(source=self.client_id, payload=response)) if process_responses_separately: for message in messages: plugin.ProcessResponses([message]) else: plugin.ProcessResponses(messages) plugin.Flush() return (hunt_urn, plugin)
def testResourceUsageStats(self): client_ids = self.SetupClients(10) with hunts.GRRHunt.StartHunt( hunt_name="GenericHunt", flow_runner_args=rdfvalue.FlowRunnerArgs( flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs( pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS, ) ), regex_rules=[rdfvalue.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=rdfvalue.FlowRunnerArgs(flow_name="GetFile"), flow_args=rdfvalue.GetFileArgs( pathspec=rdfvalue.PathSpec( path="/tmp/evil.txt", pathtype=rdfvalue.PathSpec.PathType.OS), ), regex_rules=[rdfvalue.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) started = hunt_obj.GetValuesForAttribute(hunt_obj.Schema.CLIENTS) # There should be only one client, due to the limit self.assertEqual(len(set(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: with hunt_obj.GetRunner() as runner: 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) started = hunt_obj.GetValuesForAttribute(hunt_obj.Schema.CLIENTS) # There should be only one client, due to the limit self.assertEqual(len(set(started)), 10)