Пример #1
0
def ExecuteCommandFromClient(command):
    """Executes one of the predefined commands.

  Args:
    command: An `ExecuteRequest` object.

  Yields:
    `rdf_client_action.ExecuteResponse` objects.
  """
    cmd = command.cmd
    args = command.args
    time_limit = command.time_limit

    res = client_utils_common.Execute(cmd, args, time_limit)
    (stdout, stderr, status, time_used) = res

    # Limit output to 10MB so our response doesn't get too big.
    stdout = stdout[:10 * 1024 * 1024]
    stderr = stderr[:10 * 1024 * 1024]

    yield rdf_client_action.ExecuteResponse(
        request=command,
        stdout=stdout,
        stderr=stderr,
        exit_status=status,
        # We have to return microseconds.
        time_used=int(1e6 * time_used))
Пример #2
0
  def testLaunchBinaryFlowResultsHaveReadableStdOutAndStdErr(self):
    flow_urn = flow.StartAFF4Flow(
        client_id=self.client_id,
        flow_name=gui_test_lib.RecursiveTestFlow.__name__,
        token=self.token)

    stderr = "Oh, ok, this is just a string 昨"
    stdout = "\00\00\00\00"
    response = rdf_client_action.ExecuteResponse(
        stderr=stderr.encode("utf-8"), stdout=stdout.encode("utf-8"))

    with data_store.DB.GetMutationPool() as pool:
      flow.GRRFlow.ResultCollectionForFID(flow_urn).Add(
          response, mutation_pool=pool)

    self.Open("/#/clients/%s/flows/%s/results" % (self.client_id,
                                                  flow_urn.Basename()))
    # jQuery treats the backslash ('\') character as a special one, hence we
    # have to escape it twice: once for Javascript itself and second time
    # for jQuery.
    self.WaitUntil(
        self.IsElementPresent, r"css=grr-flow-inspector:contains('Oh, ok, "
        r"this is just a string \\\\xe6\\\\x98\\\\xa8')")
    self.WaitUntil(
        self.IsElementPresent,
        r"css=grr-flow-inspector:contains('\\\\x00\\\\x00\\\\x00\\\\x00')")
Пример #3
0
    def testLaunchBinaryFlowResultsHaveReadableStdOutAndStdErr(self):
        flow_id = flow_test_lib.StartFlow(gui_test_lib.RecursiveTestFlow,
                                          client_id=self.client_id)

        stderr = "Oh, ok, this is just a string 昨"
        stdout = "\00\00\00\00"
        response = rdf_client_action.ExecuteResponse(
            stderr=stderr.encode("utf-8"), stdout=stdout.encode("utf-8"))

        if data_store.RelationalDBEnabled():
            data_store.REL_DB.WriteFlowResults([
                rdf_flow_objects.FlowResult(client_id=self.client_id,
                                            flow_id=flow_id,
                                            payload=response)
            ])
        else:
            with data_store.DB.GetMutationPool() as pool:
                flow.GRRFlow.ResultCollectionForFID(
                    rdfvalue.RDFURN(
                        self.client_id).Add("flows").Add(flow_id)).Add(
                            response, mutation_pool=pool)

        self.Open("/#/clients/%s/flows/%s/results" % (self.client_id, flow_id))
        # jQuery treats the backslash ('\') character as a special one, hence we
        # have to escape it twice: once for Javascript itself and second time
        # for jQuery.
        self.WaitUntil(
            self.IsElementPresent, r"css=grr-flow-inspector:contains('Oh, ok, "
            r"this is just a string \\\\xe6\\\\x98\\\\xa8')")
        self.WaitUntil(
            self.IsElementPresent,
            r"css=grr-flow-inspector:contains('\\\\x00\\\\x00\\\\x00\\\\x00')")
Пример #4
0
    def testCmdArtifact(self):
        """Test the parsing of an Echo Command with a TestParser."""
        client_test_lib.Command("/bin/echo", args=["1"])

        processor = parser.Parser.GetClassesByArtifact(
            "TestEchoCmdArtifact")[0]()

        self.assertIsInstance(processor, TestEchoCmdParser)

        request = rdf_client_action.ExecuteRequest(cmd="/bin/echo", args=["1"])
        res = client_utils_common.Execute(request.cmd, request.args)
        (stdout, stderr, status, time_used) = res

        response = rdf_client_action.ExecuteResponse(request=request,
                                                     stdout=stdout,
                                                     stderr=stderr,
                                                     exit_status=status,
                                                     time_used=int(1e6 *
                                                                   time_used))

        path_type = rdf_paths.PathSpec.PathType.OS
        results = []
        for res in artifact_collector.ParseSingleResponse(
                processor, response, {}, path_type):
            results.append(res)

        self.assertEqual(len(results), 1)
        self.assertIsInstance(results[0], rdf_client.SoftwarePackage)
        self.assertEqual(results[0].description, "1\n")
Пример #5
0
  def testExportsValueCorrectly(self):
    sample = rdf_client_action.ExecuteResponse(
        request=rdf_client_action.ExecuteRequest(
            cmd="some cmd",
            args=["-foo", "-bar"],
            time_limit=42,
        ),
        exit_status=-1,
        stdout=b"stdout",
        stderr=b"stderr",
        time_used=420,
    )

    converter = execute_response.ExecuteResponseConverter()
    converted = list(converter.Convert(self.metadata, sample))
    self.assertLen(converted, 1)
    c = converted[0]

    self.assertEqual(c.metadata, self.metadata)
    self.assertEqual(c.cmd, "some cmd")
    self.assertEqual(c.args, "-foo -bar")
    self.assertEqual(c.exit_status, -1)
    self.assertEqual(c.stdout, b"stdout")
    self.assertEqual(c.stderr, b"stderr")
    self.assertEqual(c.time_used_us, 420)
Пример #6
0
            def ExecuteCommand(
                self,
                args: rdf_client_action.ExecuteRequest,
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                response = rdf_client_action.ExecuteResponse()
                response.stdout = " ".join(args.args).encode("utf-8")
                response.exit_status = 0

                return [response]
Пример #7
0
        def ExecuteCommand(
            self,
            args: rdf_client_action.ExecuteRequest,
        ) -> Iterable[rdf_client_action.ExecuteResponse]:
            if args.cmd != "/bin/echo":
                raise ValueError(f"Unsupported command: {args.cmd}")

            stdout = " ".join(args.args).encode("utf-8")
            return [rdf_client_action.ExecuteResponse(stdout=stdout)]
Пример #8
0
      def ParseResponse(
          self,
          knowledge_base: rdf_client.KnowledgeBase,
          response: rdf_client_action.ExecuteResponse,
      ) -> Iterable[rdf_client_action.ExecuteResponse]:
        precondition.AssertType(response, rdf_client_action.ExecuteResponse)

        parsed_response = rdf_client_action.ExecuteResponse()
        parsed_response.stdout = response.stdout
        parsed_response.stderr = knowledge_base.os.encode("utf-8")
        return [parsed_response]
Пример #9
0
  def testOSXSPHardwareDataTypeParserInvalidInput(self):
    parser = osx_file_parser.OSXSPHardwareDataTypeParser()

    response = rdf_client_action.ExecuteResponse()
    response.request.cmd = "/usr/sbin/system_profiler"
    response.request.args = ["-xml", "SPHardwareDataType"]
    response.stdout = "chrząszcz brzmi w trzcinie".encode("utf-8")
    response.stdout = b""
    response.exit_status = 0

    with self.assertRaises(parsers.ParseError) as context:
      list(parser.ParseResponse(None, response))

    exception = context.exception
    self.assertIsInstance(exception.cause, plistlib.InvalidFileException)
Пример #10
0
  def testExportsEmptyValueCorrectly(self):
    sample = rdf_client_action.ExecuteResponse()

    converter = execute_response.ExecuteResponseConverter()
    converted = list(converter.Convert(self.metadata, sample))
    self.assertLen(converted, 1)
    c = converted[0]

    self.assertEqual(c.metadata, self.metadata)
    self.assertEqual(c.cmd, "")
    self.assertEqual(c.args, "")
    self.assertEqual(c.exit_status, 0)
    self.assertEqual(c.stdout, b"")
    self.assertEqual(c.stderr, b"")
    self.assertEqual(c.time_used_us, 0)
Пример #11
0
            def ParseResponse(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                response: rdf_client_action.ExecuteResponse,
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                del knowledge_base  # Unused.

                if not isinstance(response, rdf_client_action.ExecuteResponse):
                    raise TypeError(
                        f"Unexpected response type: {type(response)}")

                parsed_response = rdf_client_action.ExecuteResponse()
                parsed_response.stdout = response.stderr

                return [parsed_response]
Пример #12
0
    def Start(cls, command):
        cmd = command.cmd
        args = command.args
        time_limit = command.time_limit

        res = client_utils_common.Execute(cmd, args, time_limit)
        (stdout, stderr, status, time_used) = res

        # Limit output to 10MB so our response doesn't get too big.
        stdout = stdout[:10 * 1024 * 1024]
        stderr = stderr[:10 * 1024 * 1024]

        yield rdf_client_action.ExecuteResponse(
            request=command,
            stdout=stdout,
            stderr=stderr,
            exit_status=status,
            # We have to return microseconds.
            time_used=int(1e6 * time_used))
Пример #13
0
    def testListFlowApplicableParsers(self):
        client_id = self.SetupClient(0)
        flow_id = "4815162342ABCDEF"

        flow = rdf_flow_objects.Flow()
        flow.client_id = client_id
        flow.flow_id = flow_id
        flow.flow_class_name = collectors.ArtifactCollectorFlow.__name__
        flow.args = rdf_artifacts.ArtifactCollectorFlowArgs(
            apply_parsers=False)
        data_store.REL_DB.WriteFlowObject(flow)

        result = rdf_flow_objects.FlowResult()
        result.client_id = client_id
        result.flow_id = flow_id
        result.tag = "artifact:Fake"
        result.payload = rdf_client_action.ExecuteResponse(stderr=b"foobar")
        data_store.REL_DB.WriteFlowResults([result])

        class FakeParser(parser.SingleResponseParser[None]):

            supported_artifacts = ["Fake"]

            def ParseResponse(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                response: rdfvalue.RDFValue,
            ) -> Iterable[None]:
                raise NotImplementedError()

        with parser_test_lib._ParserContext("Fake", FakeParser):
            results = self.api.Client(client_id).Flow(
                flow_id).ListApplicableParsers()

        self.assertLen(results.parsers, 1)

        result = results.parsers[0]
        self.assertEqual(result.name, "Fake")
        self.assertEqual(result.type,
                         flow_pb2.ApiParserDescriptor.SINGLE_RESPONSE)
Пример #14
0
  def testLaunchBinaryFlowResultsHaveReadableStdOutAndStdErr(self):
    flow_id = flow.StartFlow(
        client_id=self.client_id, flow_cls=gui_test_lib.RecursiveTestFlow)

    stderr = "Oh, ok, this is just a string 昨"
    stdout = "\00\00\00\00"
    response = rdf_client_action.ExecuteResponse(
        stderr=stderr.encode("utf-8"), stdout=stdout.encode("utf-8"))
    flow_result = rdf_flow_objects.FlowResult(tag="tag", payload=response)

    data_store.REL_DB.WriteFlowResults(self.client_id, flow_id, [flow_result])

    self.Open("/#/clients/%s/flows/%s/results" % (self.client_id, flow_id))
    # jQuery treats the backslash ('\') character as a special one, hence we
    # have to escape it twice: once for Javascript itself and second time
    # for jQuery.
    self.WaitUntil(
        self.IsElementPresent, r"css=grr-flow-inspector:contains('Oh, ok, "
        r"this is just a string \\\\xe6\\\\x98\\\\xa8')")
    self.WaitUntil(
        self.IsElementPresent,
        r"css=grr-flow-inspector:contains('\\\\x00\\\\x00\\\\x00\\\\x00')")
Пример #15
0
    def testListParsedFlowResults(self):
        client_id = self.SetupClient(0)
        flow_id = "4815162342ABCDEF"

        flow = rdf_flow_objects.Flow()
        flow.client_id = client_id
        flow.flow_id = flow_id
        flow.flow_class_name = collectors.ArtifactCollectorFlow.__name__
        flow.args = rdf_artifacts.ArtifactCollectorFlowArgs(
            apply_parsers=False)
        flow.persistent_data = {"knowledge_base": rdf_client.KnowledgeBase()}
        data_store.REL_DB.WriteFlowObject(flow)

        result = rdf_flow_objects.FlowResult()
        result.client_id = client_id
        result.flow_id = flow_id
        result.tag = "artifact:Echo"

        response = rdf_client_action.ExecuteResponse()
        response.stderr = "Lorem ipsum.".encode("utf-8")

        result.payload = response
        data_store.REL_DB.WriteFlowResults([result])

        response = rdf_client_action.ExecuteResponse()
        response.stderr = "Dolor sit amet.".encode("utf-8")

        result.payload = response
        data_store.REL_DB.WriteFlowResults([result])

        class StderrToStdoutParser(
                parser.SingleResponseParser[rdf_client_action.ExecuteResponse]
        ):

            supported_artifacts = ["Echo"]

            def ParseResponse(
                self,
                knowledge_base: rdf_client.KnowledgeBase,
                response: rdf_client_action.ExecuteResponse,
            ) -> Iterable[rdf_client_action.ExecuteResponse]:
                del knowledge_base  # Unused.

                if not isinstance(response, rdf_client_action.ExecuteResponse):
                    raise TypeError(
                        f"Unexpected response type: {type(response)}")

                parsed_response = rdf_client_action.ExecuteResponse()
                parsed_response.stdout = response.stderr

                return [parsed_response]

        with parser_test_lib._ParserContext("StderrToStdout",
                                            StderrToStdoutParser):
            results = self.api.Client(client_id).Flow(
                flow_id).ListParsedResults()

        stdouts = [result.payload.stdout.decode("utf-8") for result in results]
        self.assertLen(stdouts, 2)
        self.assertEqual(stdouts[0], "Lorem ipsum.")
        self.assertEqual(stdouts[1], "Dolor sit amet.")