Beispiel #1
0
    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
Beispiel #2
0
  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),
           )
       )
Beispiel #4
0
    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")
Beispiel #5
0
 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)
Beispiel #6
0
 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)
Beispiel #7
0
 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")
Beispiel #9
0
    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)