Beispiel #1
0
    def setUp(self):
        super(ApiGetHuntFileHandlerTest, self).setUp()

        self.handler = hunt_plugin.ApiGetHuntFileHandler()

        self.file_path = os.path.join(self.base_path, "test.plist")
        self.hunt = hunts.GRRHunt.StartHunt(
            hunt_name="GenericHunt",
            flow_runner_args=flow_runner.FlowRunnerArgs(
                flow_name=file_finder.FileFinder.__name__),
            flow_args=file_finder.FileFinderArgs(
                paths=[self.file_path],
                action=file_finder.FileFinderAction(action_type="DOWNLOAD"),
            ),
            client_rate=0,
            token=self.token)
        self.hunt.Run()

        self.results_urn = self.hunt.state.context.results_collection_urn
        self.aff4_file_path = rdfvalue.RDFURN("os").Add(self.file_path)

        self.client_id = self.SetupClients(1)[0]
        self.AssignTasksToClients(client_ids=[self.client_id])
        action_mock = action_mocks.ActionMock("TransferBuffer", "StatFile",
                                              "HashFile", "HashBuffer")
        test_lib.TestHuntHelper(action_mock, [self.client_id],
                                token=self.token)
Beispiel #2
0
    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,
                )),
                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")
Beispiel #3
0
  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 testAlertEmailIsSentWhenClientKilledDuringHunt(self):
    """Test that client killed messages are handled correctly for hunts."""
    self.email_messages = []

    def SendEmail(address, sender, title, message, **_):
      self.email_messages.append(dict(address=address,
                                      sender=sender,
                                      title=title,
                                      message=message))

    with hunts.GRRHunt.StartHunt(hunt_name="GenericHunt",
                                 flow_runner_args=flow_runner.FlowRunnerArgs(
                                     flow_name="FlowWithOneClientRequest"),
                                 client_rate=0,
                                 crash_alert_email="*****@*****.**",
                                 token=self.token) as hunt:
      hunt.Run()
      hunt.StartClients(hunt.session_id, self.client_id)

    with utils.Stubber(email_alerts.EMAIL_ALERTER, "SendEmail", SendEmail):
      client = test_lib.CrashClientMock(self.client_id, self.token)
      test_lib.TestHuntHelper(client, [self.client_id],
                              token=self.token,
                              check_flow_errors=False)

    self.assertEqual(len(self.email_messages), 2)
    self.assertListEqual(
        [self.email_messages[0]["address"], self.email_messages[1]["address"]],
        ["*****@*****.**", config_lib.CONFIG["Monitoring.alert_email"]])
Beispiel #5
0
  def testStoppingHuntMarksAllStartedFlowsAsPendingForTermination(self):
    with hunts.GRRHunt.StartHunt(
        hunt_name="GenericHunt",
        flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="InfiniteFlow"),
        regex_rules=[
            rdf_foreman.ForemanAttributeRegex(attribute_name="GRR client",
                                              attribute_regex="GRR"),
        ],
        client_rate=0, token=self.token) as hunt:
      hunt.Run()

    self.AssignTasksToClients()

    # Run long enough for InfiniteFlows to start.
    self.RunHunt(iteration_limit=len(self.client_ids) * 2)
    self.StopHunt(hunt.urn)

    # All flows should be marked for termination now. RunHunt should raise.
    # If something is wrong with GRRFlow.MarkForTermination mechanism, then
    # this will run forever.
    self.RunHunt()

    for client_id in self.client_ids:
      flows_root = aff4.FACTORY.Open(client_id.Add("flows"), token=self.token)
      flows_list = list(flows_root.ListChildren())
      # Only one flow (issued by the hunt) is expected.
      self.assertEqual(len(flows_list), 1)

      flow_obj = aff4.FACTORY.Open(flows_list[0], aff4_type="InfiniteFlow",
                                   token=self.token)
      self.assertEqual(flow_obj.state.context.state, "ERROR")
      self.assertEqual(flow_obj.state.context.backtrace,
                       "Parent hunt stopped.")
Beispiel #6
0
  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
Beispiel #7
0
 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), ))
Beispiel #8
0
  def testCreatorPropagation(self):
    self.CreateAdminUser("adminuser")
    admin_token = access_control.ACLToken(username="******",
                                          reason="testing")
    # Start a flow that requires admin privileges in the hunt. The
    # parameters are not valid so the flow will error out but it's
    # enough to check if the flow was actually run (i.e., it passed
    # the label test).
    with hunts.GRRHunt.StartHunt(
        hunt_name="GenericHunt",
        flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="UpdateClient"),
        flow_args=administrative.UpdateClientArgs(),
        regex_rules=[
            rdf_foreman.ForemanAttributeRegex(attribute_name="GRR client",
                                              attribute_regex="GRR"),
        ],
        client_rate=0, token=admin_token) as hunt:
      hunt.Run()

    self.CreateUser("nonadmin")
    nonadmin_token = access_control.ACLToken(username="******",
                                             reason="testing")
    self.AssignTasksToClients()

    client_mock = test_lib.SampleHuntMock()
    test_lib.TestHuntHelper(client_mock, self.client_ids, False,
                            nonadmin_token)

    errors = list(hunt.GetClientsErrors())
    # Make sure there are errors...
    self.assertTrue(errors)
    # but they are not UnauthorizedAccess.
    for e in errors:
      self.assertTrue("UnauthorizedAccess" not in e.backtrace)
Beispiel #9
0
    def Run(self):
        runner_args = flow_runner.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 = 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"})
Beispiel #10
0
    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.")
Beispiel #11
0
    def Handle(self, args, token=None):
        client_urn = self.GetClientTarget(args, token=token)

        size_condition = file_finder.FileFinderCondition(
            condition_type=file_finder.FileFinderCondition.Type.SIZE,
            size=file_finder.FileFinderSizeCondition(
                max_file_size=args.max_file_size))

        file_finder_args = file_finder.FileFinderArgs(
            paths=args.paths,
            action=file_finder.FileFinderAction(action_type=args.action),
            conditions=[size_condition])

        # Check our flow throttling limits, will raise if there are problems.
        throttler = throttle.FlowThrottler()
        throttler.EnforceLimits(client_urn,
                                token.username,
                                file_finder.FileFinder.__name__,
                                file_finder_args,
                                token=token)

        # Limit the whole flow to 200MB so if a glob matches lots of small files we
        # still don't have too much impact.
        runner_args = flow_runner.FlowRunnerArgs(
            client_id=client_urn,
            flow_name=file_finder.FileFinder.__name__,
            network_bytes_limit=200 * 1000 * 1000)

        flow_id = flow.GRRFlow.StartFlow(runner_args=runner_args,
                                         token=token,
                                         args=file_finder_args)

        return ApiStartRobotGetFilesOperationResult(
            operation_id=utils.SmartUnicode(flow_id))
Beispiel #12
0
    def Start(self):
        self.state.Register("hunt_id", None)
        self.state.Register("client_ids", set())
        self.state.Register("client_ids_failures", set())
        self.state.Register("client_ids_result_reported", set())

        self.state.client_ids = base.GetClientTestTargets(token=self.token)

        if not self.state.client_ids:
            self.Log("No clients to test on, define them in "
                     "Test.end_to_end_client_ids")
            return

        # SetUID is required to run a hunt on the configured end-to-end client
        # targets without an approval.
        token = access_control.ACLToken(
            username="******", reason="Running endtoend tests.").SetUID()
        runner_args = flow_runner.FlowRunnerArgs(flow_name="EndToEndTestFlow")

        flow_request = hunts_standard.FlowRequest(
            client_ids=self.state.client_ids,
            args=flows_endtoend.EndToEndTestFlowArgs(),
            runner_args=runner_args)

        bogus_rule = rdf_foreman.ForemanRegexClientRule(
            attribute_name="System", attribute_regex="Does not match anything")

        client_rule_set = rdf_foreman.ForemanClientRuleSet(rules=[
            rdf_foreman.ForemanClientRule(
                rule_type=rdf_foreman.ForemanClientRule.Type.REGEX,
                regex=bogus_rule)
        ])

        hunt_args = hunts_standard.VariableGenericHuntArgs(
            flows=[flow_request])

        hunt_args.output_plugins = self.GetOutputPlugins()

        with hunts.GRRHunt.StartHunt(hunt_name="VariableGenericHunt",
                                     args=hunt_args,
                                     client_rule_set=client_rule_set,
                                     client_rate=0,
                                     expiry_time="1d",
                                     token=token) as hunt:

            self.state.hunt_id = hunt.session_id
            hunt.SetDescription("EndToEnd tests run by cron")
            hunt.Run()
            hunt.ManuallyScheduleClients(token=token)

        # Set a callback to check the results after 50 minutes.  This should be
        # plenty of time for the clients to receive the hunt and run the tests, but
        # not so long that the flow lease will expire.

        wait_duration = rdfvalue.Duration(
            config_lib.CONFIG.Get("Test.end_to_end_result_check_wait"))
        completed_time = rdfvalue.RDFDatetime().Now() + wait_duration

        self.CallState(next_state="CheckResults", start_time=completed_time)
Beispiel #13
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=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")
Beispiel #14
0
 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)
Beispiel #15
0
 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)
Beispiel #16
0
 def _CreateHunt(self, description):
     output_plugins = [
         output_plugin.OutputPluginDescriptor(
             plugin_name="TestOutputPlugin")
     ]
     with hunts.GRRHunt.StartHunt(
             hunt_name=standard.GenericHunt.__name__,
             flow_runner_args=flow_runner.FlowRunnerArgs(
                 flow_name="GetFile"),
             output_plugins=output_plugins,
             description=description,
             client_rate=0,
             token=self.token) as hunt:
         return hunt
Beispiel #17
0
  def Start(self):
    with hunts.GRRHunt.StartHunt(
        hunt_name="GenericHunt",
        flow_runner_args=flow_runner.FlowRunnerArgs(flow_name="Interrogate"),
        flow_args=flows_discovery.InterrogateArgs(lightweight=False),
        regex_rules=[],
        output_plugins=self.GetOutputPlugins(),
        token=self.token) as hunt:

      runner = hunt.GetRunner()
      runner.args.client_rate = 50
      runner.args.expiry_time = "1w"
      runner.args.description = ("Interrogate run by cron to keep host"
                                 "info fresh.")
      runner.Start()
Beispiel #18
0
class TestFileFinderOSHomedir(TestFileFinderOSLinux):
  """List files in homedir with FileFinder.

  Exercise globbing and interpolation.
  """
  platforms = ["Linux", "Darwin", "Windows"]
  test_output_path = "/analysis/test/homedirs"
  action = file_finder.FileFinderAction(
      action_type=file_finder.FileFinderAction.Action.STAT)
  args = {"paths": ["%%users.homedir%%/*"],
          "action": action,
          "runner_args": flow_runner.FlowRunnerArgs(output=test_output_path)}

  def CheckFlow(self):
    results = aff4.FACTORY.Open(
        self.client_id.Add(self.test_output_path),
        token=self.token)
    self.assertEqual(type(results), aff4.RDFValueCollection)
    self.assertTrue(len(results) > 1)
Beispiel #19
0
  def Layout(self, request, response):
    """Render the form for creating the flow args."""
    self.flow_name = self._GetFlowName(request)
    self.flow_cls = flow.GRRFlow.classes.get(self.flow_name)

    if aff4.issubclass(self.flow_cls, flow.GRRFlow):
      self.flow_found = True

      self.form = forms.SemanticProtoFormRenderer(
          self.flow_cls.GetDefaultArgs(token=request.token),
          prefix="args").RawHTML(request)

      self.runner_form = forms.SemanticProtoFormRenderer(
          flow_runner.FlowRunnerArgs(flow_name=self.flow_name),
          prefix="runner").RawHTML(request)

    response = super(SemanticProtoFlowForm, self).Layout(request, response)
    return self.CallJavascript(response, "SemanticProtoFlowForm.Layout",
                               renderer=self.__class__.__name__)
Beispiel #20
0
    def RenderAjax(self, request, response):
        """Parse the flow args from the form and launch the flow."""
        self.flow_name = self._GetFlowName(request)
        self.client_id = request.REQ.get("client_id", None)
        self.dom_node = request.REQ.get("dom_node")

        flow_cls = flow.GRRFlow.classes.get(self.flow_name)
        if flow_cls is not None:

            self.args = forms.SemanticProtoFormRenderer(
                flow_cls.args_type(), prefix="args").ParseArgs(request)

            try:
                self.args.Validate()
            except ValueError as e:
                return self.CallJavascript(
                    response,
                    "SemanticProtoFlowForm.RenderAjaxError",
                    error=str(e))

            self.runner_args = forms.SemanticProtoFormRenderer(
                flow_runner.FlowRunnerArgs(),
                prefix="runner_").ParseArgs(request)

            self.runner_args.Validate()

            self.flow_id = flow.GRRFlow.StartFlow(client_id=self.client_id,
                                                  flow_name=self.flow_name,
                                                  token=request.token,
                                                  args=self.args,
                                                  runner_args=self.runner_args)

        self.args_html = semantic.FindRendererForObject(
            self.args).RawHTML(request)
        self.runner_args_html = semantic.FindRendererForObject(
            self.runner_args).RawHTML(request)
        response = renderers.TemplateRenderer.Layout(
            self, request, response, apply_template=self.ajax_template)
        return self.CallJavascript(response,
                                   "SemanticProtoFlowForm.RenderAjax",
                                   renderer=self.__class__.__name__,
                                   dom_node=self.dom_node)
Beispiel #21
0
    def testHuntCollectionLogging(self):
        """This tests running the hunt on some clients."""
        with hunts.GRRHunt.StartHunt(
                hunt_name="GenericHunt",
                flow_runner_args=flow_runner.FlowRunnerArgs(
                    flow_name="DummyLogFlow"),
                client_rate=0,
                token=self.token) as hunt:
            hunt.Run()
            hunt.Log("Log from the hunt itself")

        hunt_urn = hunt.urn

        self.AssignTasksToClients()
        self.RunHunt()

        # Check logs were written to the hunt collection
        with aff4.FACTORY.Open(hunt_urn.Add("Logs"),
                               token=self.token,
                               age=aff4.ALL_TIMES) as hunt_logs:

            # Can't use len with PackedVersionCollection
            count = 0
            for log in hunt_logs:
                if log.client_id:
                    self.assertTrue(log.client_id in self.client_ids)
                    self.assertTrue(log.log_message in [
                        "First", "Second", "Third", "Fourth", "Uno", "Dos",
                        "Tres", "Cuatro"
                    ])
                    self.assertTrue(
                        log.flow_name in ["DummyLogFlow", "DummyLogFlowChild"])
                    self.assertTrue(str(hunt_urn) in str(log.urn))
                else:
                    self.assertEqual(log.log_message,
                                     "Log from the hunt itself")
                    self.assertEqual(log.flow_name, "GenericHunt")
                    self.assertEqual(log.urn, hunt_urn)

                count += 1
            # 4 logs for each flow, 2 flow run.  One hunt-level log.
            self.assertEqual(count, 8 * len(self.client_ids) + 1)
Beispiel #22
0
    def Render(self, args, token=None):
        client_urn = self.GetClientTarget(args, token=token)

        size_condition = file_finder.FileFinderCondition(
            condition_type=file_finder.FileFinderCondition.Type.SIZE,
            size=file_finder.FileFinderSizeCondition(
                max_file_size=args.max_file_size))

        file_finder_args = file_finder.FileFinderArgs(
            paths=args.paths,
            action=file_finder.FileFinderAction(action_type=args.action),
            conditions=[size_condition])

        # Check our flow throttling limits, will raise if there are problems.
        throttler = throttle.FlowThrottler()
        throttler.EnforceLimits(client_urn,
                                token.username,
                                "FileFinder",
                                file_finder_args,
                                token=token)

        # Limit the whole flow to 200MB so if a glob matches lots of small files we
        # still don't have too much impact.
        runner_args = flow_runner.FlowRunnerArgs(client_id=client_urn,
                                                 flow_name="FileFinder",
                                                 network_bytes_limit=200 *
                                                 1000 * 1000)

        flow_id = flow.GRRFlow.StartFlow(runner_args=runner_args,
                                         token=token,
                                         args=file_finder_args)

        # Provide a url where the caller can check on the flow status.
        status_url = urlparse.urljoin(
            config_lib.CONFIG["AdminUI.url"], "/api/flows/%s/%s/status" %
            (client_urn.Basename(), flow_id.Basename()))
        return dict(
            flow_id=api_value_renderers.RenderValue(flow_id),
            flow_args=api_value_renderers.RenderValue(file_finder_args),
            runner_args=api_value_renderers.RenderValue(runner_args),
            status_url=status_url)
Beispiel #23
0
    def ParseFlowArgs(self):
        """Parse the flow and flow_runner args."""
        if self.flow_runner_args is not None:
            return self.flow_runner_args, self.flow_args

        flow_path = self.request.REQ.get("flow_path", "")
        flow_name = os.path.basename(flow_path)
        if not flow_name:
            raise ValueError("No flow specified. Please select a flow.")

        flow_cls = flow.GRRFlow.GetPlugin(flow_name)
        self.flow_args = forms.SemanticProtoFormRenderer(
            flow_cls.args_type(), prefix="args").ParseArgs(self.request)

        self.flow_runner_args = forms.SemanticProtoFormRenderer(
            flow_runner.FlowRunnerArgs(),
            prefix="runner").ParseArgs(self.request)

        self.flow_runner_args.flow_name = flow_name

        return self.flow_runner_args, self.flow_args
Beispiel #24
0
 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)
Beispiel #25
0
    def setUp(self):
        super(ApiGetHuntFilesArchiveHandlerTest, self).setUp()

        self.handler = hunt_plugin.ApiGetHuntFilesArchiveHandler()

        self.hunt = hunts.GRRHunt.StartHunt(
            hunt_name="GenericHunt",
            flow_runner_args=flow_runner.FlowRunnerArgs(
                flow_name=file_finder.FileFinder.__name__),
            flow_args=file_finder.FileFinderArgs(
                paths=[os.path.join(self.base_path, "test.plist")],
                action=file_finder.FileFinderAction(action_type="DOWNLOAD"),
            ),
            client_rate=0,
            token=self.token)
        self.hunt.Run()

        client_ids = self.SetupClients(10)
        self.AssignTasksToClients(client_ids=client_ids)
        action_mock = action_mocks.ActionMock("TransferBuffer", "StatFile",
                                              "HashFile", "HashBuffer")
        test_lib.TestHuntHelper(action_mock, client_ids, token=self.token)
Beispiel #26
0
    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
Beispiel #27
0
    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)
Beispiel #28
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=flow_runner.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.state.args.flow_runner_args.flow_name,
                         file_finder.FileFinder.__name__)
        self.assertEqual(
            last_hunt.state.args.flow_args.conditions[0].
            contents_literal_match.literal, "foo\x0d\xc8bar")