Beispiel #1
0
    def RekallAction(self, request):
        self.rekall_request = request

        # Pretend Rekall returned the memory file.
        return [
            rdf_rekall_types.RekallResponse(json_messages="""
        [["file",{"path": "%s", "pathtype": "TMPFILE"}]]
        """ % self.memory_file,
                                            plugin="aff4acquire"),
            rdf_client.Iterator(state="FINISHED")
        ]
Beispiel #2
0
  def RekallAction(self, _):
    # Generate this file with:
    # rekal --output data -f win7_trial_64bit.raw \
    # pslist | gzip - > rekall_pslist_result.dat.gz
    ps_list_file = os.path.join(config.CONFIG["Test.data_dir"],
                                self.result_filename)
    result = rdf_rekall_types.RekallResponse(
        json_messages=gzip.open(ps_list_file).read(),
        plugin="pslist",
        client_urn=self.client_id)

    return [result, rdf_client.Iterator(state="FINISHED")]
Beispiel #3
0
    def testOverwriting(self):
        req = rdf_client.Iterator(client_state=rdf_protodict.Dict({"A": 1}))
        # There should be one element now.
        self.assertEqual(len(list(req.client_state.items())), 1)

        req.client_state = rdf_protodict.Dict({"B": 2})
        # Still one element.
        self.assertEqual(len(list(req.client_state.items())), 1)

        req.client_state = rdf_protodict.Dict({})

        # And now it's gone.
        self.assertEqual(len(list(req.client_state.items())), 0)
Beispiel #4
0
  def RekallAction(self, _):
    ps_list_file = os.path.join(config.CONFIG["Test.data_dir"],
                                "rekall_vad_result.dat.gz")
    response = rdf_rekall_types.RekallResponse(
        json_messages=gzip.open(ps_list_file, "rb").read(), plugin="pslist")

    # If we are given process names here we need to craft a Rekall result
    # containing them. This is so they point to valid files in the fixture.
    if self.process_list:
      json_data = json.loads(response.json_messages)
      template = json_data[7]
      if template[1]["filename"] != ur"\Windows\System32\ntdll.dll":
        raise RuntimeError("Test data invalid.")

      json_data = []
      for process in self.process_list:
        new_entry = copy.deepcopy(template)
        new_entry[1]["filename"] = process
        json_data.append(new_entry)
      response.json_messages = json.dumps(json_data)

    return [response, rdf_client.Iterator(state="FINISHED")]
Beispiel #5
0
    def __init__(self, request=None, responses=None):
        self.status = None  # A GrrStatus rdfvalue object.
        self.success = True
        self.request = request
        if request:
            self.request_data = rdf_protodict.Dict(request.data)
        self._responses = []
        dropped_responses = []
        # This is the raw message accessible while going through the iterator
        self.message = None
        # The iterator that was returned as part of these responses. This should
        # be passed back to actions that expect an iterator.
        self.iterator = None

        if not responses:
            return

        # This may not be needed if we can assume that responses are
        # returned in lexical order from the data_store.
        responses.sort(key=operator.attrgetter("response_id"))

        # Filter the responses by authorized states
        for msg in responses:
            # Check if the message is authenticated correctly.
            if msg.auth_state != msg.AuthorizationState.AUTHENTICATED:
                logging.warning(
                    "%s: Messages must be authenticated (Auth state %s)",
                    msg.session_id, msg.auth_state)
                dropped_responses.append(msg)
                # Skip this message - it is invalid
                continue

            # Check for iterators
            if msg.type == msg.Type.ITERATOR:
                if self.iterator:
                    raise ValueError(
                        "Received multiple iterator messages at once.")
                self.iterator = rdf_client.Iterator(msg.payload)
                continue

            # Look for a status message
            if msg.type == msg.Type.STATUS:
                # Our status is set to the first status message that we see in
                # the responses. We ignore all other messages after that.
                self.status = rdf_flows.GrrStatus(msg.payload)

                # Check this to see if the call succeeded
                self.success = self.status.status == self.status.ReturnedStatus.OK

                # Ignore all other messages
                break

            # Use this message
            self._responses.append(msg)

        if self.status is None:
            # This is a special case of de-synchronized messages.
            if dropped_responses:
                logging.error(
                    "De-synchronized messages detected:\n %s", "\n".join(
                        [utils.SmartUnicode(x) for x in dropped_responses]))

            self._LogFlowState(responses)

            raise ValueError("No valid Status message.")
Beispiel #6
0
    def FromLegacyResponses(cls, request=None, responses=None):
        """Creates a Responses object from old style flow request and responses."""
        res = cls()
        res.request = request
        if request:
            res.request_data = rdf_protodict.Dict(request.data)
        dropped_responses = []
        # The iterator that was returned as part of these responses. This should
        # be passed back to actions that expect an iterator.
        res.iterator = None

        if not responses:
            return res

        # This may not be needed if we can assume that responses are
        # returned in lexical order from the data_store.
        responses.sort(key=operator.attrgetter("response_id"))

        if request.HasField("request"):
            client_action_name = request.request.name
            action_registry = server_stubs.ClientActionStub.classes
            if client_action_name not in action_registry:
                raise RuntimeError("Got unknown client action: %s." %
                                   client_action_name)
            expected_response_classes = action_registry[
                client_action_name].out_rdfvalues

        old_response_id = None

        # Filter the responses by authorized states
        for msg in responses:
            # Check if the message is authenticated correctly.
            if msg.auth_state != msg.AuthorizationState.AUTHENTICATED:
                logging.warning(
                    "%s: Messages must be authenticated (Auth state %s)",
                    msg.session_id, msg.auth_state)
                dropped_responses.append(msg)
                # Skip this message - it is invalid
                continue

            # Handle retransmissions
            if msg.response_id == old_response_id:
                continue

            old_response_id = msg.response_id

            # Check for iterators
            if msg.type == msg.Type.ITERATOR:
                if res.iterator:
                    raise ValueError(
                        "Received multiple iterator messages at once.")
                res.iterator = rdf_client.Iterator(msg.payload)
                continue

            # Look for a status message
            if msg.type == msg.Type.STATUS:
                # Our status is set to the first status message that we see in
                # the responses. We ignore all other messages after that.
                res.status = rdf_flows.GrrStatus(msg.payload)

                # Check this to see if the call succeeded
                res.success = res.status.status == res.status.ReturnedStatus.OK

                # Ignore all other messages
                break

            if msg.type == msg.Type.MESSAGE:
                if request.HasField("request"):
                    # Let's do some verification for requests that came from clients.
                    if not expected_response_classes:
                        raise RuntimeError(
                            "Client action %s does not specify out_rdfvalue." %
                            client_action_name)
                    else:
                        args_rdf_name = msg.args_rdf_name
                        if not args_rdf_name:
                            raise RuntimeError(
                                "Deprecated message format received: "
                                "args_rdf_name is None.")
                        elif args_rdf_name not in [
                                x.__name__ for x in expected_response_classes
                        ]:
                            raise RuntimeError(
                                "Response type was %s but expected %s for %s."
                                % (args_rdf_name, expected_response_classes,
                                   client_action_name))
            # Use this message
            res.responses.append(msg.payload)

        if res.status is None:
            # This is a special case of de-synchronized messages.
            if dropped_responses:
                logging.error(
                    "De-synchronized messages detected:\n %s", "\n".join(
                        [utils.SmartUnicode(x) for x in dropped_responses]))

            res.LogFlowState(responses)

            raise ValueError("No valid Status message.")

        return res