예제 #1
0
    def testRekallModules(self):
        """Tests the end to end Rekall memory analysis."""
        request = rdf_rekall_types.RekallRequest()
        request.plugins = [
            # Only use these methods for listing processes.
            rdf_rekall_types.PluginRequest(
                plugin="pslist",
                args=dict(method=["PsActiveProcessHead", "CSRSS"])),
            rdf_rekall_types.PluginRequest(plugin="modules")
        ]
        self.LaunchRekallPlugin(request)

        # Get the result collection - it should be a RekallResponseCollection.
        fd = aff4.FACTORY.Open(self.client_id.Add("analysis/memory"),
                               token=self.token)

        # Ensure that the client_id is set on each message. This helps us demux
        # messages from different clients, when analyzing the collection from a
        # hunt.
        json_blobs = []
        for x in fd:
            self.assertEqual(x.client_urn, self.client_id)
            json_blobs.append(x.json_messages)

        json_blobs = "".join(json_blobs)

        for knownresult in ["DumpIt.exe", "DumpIt.sys"]:
            self.assertTrue(knownresult in json_blobs)
예제 #2
0
  def Start(self):
    self.state.Register("memory_information", None)
    self.state.Register(
        "destdir",
        self.args.action.download.dump_option.with_local_copy.destdir)

    # If it is a Linux client, use Rekall instead to grab memory.
    # Unlike AnalyzeClientMemory, we skip manually checking for kcore's
    # existence since Rekall does it for us and runs additionally checks (like
    # the actual usability of kcore).
    client = aff4.FACTORY.Open(self.client_id, token=self.token)
    system = client.Get(client.Schema.SYSTEM)
    if system == "Linux":
      if (self.args.action.action_type !=
          MemoryCollectorAction.Action.DOWNLOAD):
        raise ValueError("Linux only supports downloading memory.")
      plugin = rekall_types.PluginRequest(plugin="ewfacquire")
      request = rekall_types.RekallRequest(plugins=[plugin])
      self.CallFlow("AnalyzeClientMemory", request=request,
                    max_file_size_download=self.action_options.max_file_size,
                    next_state="CheckAnalyzeClientMemory")
    else:
      self.CallFlow("LoadMemoryDriver",
                    driver_installer=self.args.driver_installer,
                    next_state="StoreMemoryInformation")
예제 #3
0
  def testNestedProtobufAssignment(self):
    """Check that we can assign a nested protobuf."""
    container = rdf_rekall_types.RekallRequest()
    pathspec = rdf_paths.PathSpec(path=r"\\.\pmem", pathtype=1)

    # Should raise - incompatible RDFType.
    self.assertRaises(ValueError, setattr, container, "device",
                      rdfvalue.RDFString("hello"))

    # Should raise - incompatible RDFProto type.
    self.assertRaises(
        ValueError,
        setattr,
        container,
        "device",
        rdf_client.StatEntry(st_size=5))

    # Assign directly.
    container.device = pathspec

    self.assertEqual(container.device.path, r"\\.\pmem")

    # Clear the field.
    container.device = None

    # Check the protobuf does not have the field set at all.
    self.assertFalse(container.HasField("device"))
예제 #4
0
파일: memory.py 프로젝트: staffzzz/grr
    def RunRekallPlugin(self):
        plugin = rekall_types.PluginRequest(plugin="aff4acquire")
        request = rekall_types.RekallRequest(plugins=[plugin])

        # Note that this will actually also retrieve the memory image.
        self.CallFlow("AnalyzeClientMemory",
                      request=request,
                      max_file_size_download=self.args.max_file_size,
                      next_state="CheckAnalyzeClientMemory")
예제 #5
0
    def DisabledTestAllPlugins(self):
        """Tests that we can run a wide variety of plugins.

    Some of those plugins are very expensive to run so this test is disabled by
    default.
    """

        plugins = [
            "atoms", "atomscan", "build_index", "callbacks", "cc",
            "cert_vad_scan", "certscan", "cmdscan", "consoles",
            "convert_profile", "desktops", "devicetree", "dis", "dlldump",
            "dlllist", "driverirp", "driverscan", "dt", "dtbscan", "dtbscan2",
            "dump", "dwarfparser", "eifconfig", "enetstat", "eventhooks",
            "fetch_pdb", "filescan", "find_dtb", "gahti", "getservicesids",
            "grep", "guess_guid", "handles", "hivedump", "hives", "imagecopy",
            "imageinfo", "impscan", "info", "json_render", "kdbgscan", "kpcr",
            "l", "ldrmodules", "load_as", "load_plugin", "malfind", "memdump",
            "memmap", "messagehooks", "moddump", "modscan", "modules",
            "mutantscan", "netscan", "netstat", "notebook", "null",
            "object_tree", "object_types", "p", "parse_pdb", "pas2vas",
            "pedump", "peinfo", "pfn", "phys_map", "pool_tracker", "pools",
            "printkey", "procdump", "procinfo", "pslist", "psscan", "pstree",
            "psxview", "pte", "ptov", "raw2dmp", "regdump", "rekal",
            "sessions", "ssdt", "svcscan", "symlinkscan", "thrdscan",
            "threads", "timers", "tokens", "unloaded_modules", "userassist",
            "userhandles", "users", "vad", "vaddump", "vadinfo", "vadtree",
            "vadwalk", "version_modules", "version_scan", "vmscan", "vtop",
            "windows_stations"
        ]

        failed_plugins = []

        for plugin in plugins:
            logging.info("Running plugin: %s", plugin)
            try:
                aff4.FACTORY.Delete(output_urn, token=self.token)

                request = rdf_rekall_types.RekallRequest()
                request.plugins = [
                    rdf_rekall_types.PluginRequest(plugin=plugin)
                ]

                session_id = self.LaunchRekallPlugin(request)

                # Get the result collection - it should be a RekallResponseCollection.
                fd = aff4.FACTORY.Open(session_id.Add(
                    flow_runner.RESULTS_SUFFIX),
                                       token=self.token)
                # Try to render the result.
                fd.RenderAsText()
            except Exception:  # pylint: disable=broad-except
                failed_plugins.append(plugin)
                logging.error("Plugin %s failed.", plugin)
        if failed_plugins:
            self.fail("Some plugins failed: %s" % failed_plugins)
예제 #6
0
  def testFileOutput(self):
    """Tests that a file can be written by a plugin and retrieved."""
    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Run procdump to create one file.
        rdf_rekall_types.PluginRequest(
            plugin="procdump", args=dict(pid=2860))]

    with test_lib.Instrument(transfer.MultiGetFile,
                             "StoreStat") as storestat_instrument:
      self.LaunchRekallPlugin(request)
      # Expect one file to be downloaded.
      self.assertEqual(storestat_instrument.call_count, 1)
예제 #7
0
  def setUp(self):
    super(TestRekallViewer, self).setUp()

    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Only use these methods for listing processes.
        rdf_rekall_types.PluginRequest(
            plugin="pslist", args=dict(method=["PsActiveProcessHead",
                                               "CSRSS"])),
        rdf_rekall_types.PluginRequest(plugin="modules")
    ]

    self.LaunchRekallPlugin(request)
예제 #8
0
class AbstractTestAnalyzeClientMemory(base.ClientTestBase):
    """Test AnalyzeClientMemory (Rekall).

  We use the rekall caching profile server for these tests, since we may not
  have direct internet access. It may be necessary to manually populate the
  cache with lib.rekall_profile_server.GRRRekallProfileServer.GetMissingProfiles
  on the console to make these tests pass.
  """
    flow = "AnalyzeClientMemory"
    test_output_path = "analysis/memory"
    args = {
        "request": rdf_rekall_types.RekallRequest(),
        "output": test_output_path
    }

    def setUpRequest(self):
        raise NotImplementedError("Implemented by subclasses")

    def setUp(self):
        self.setUpRequest()

        self.old_config = config_lib.CONFIG.Get("Rekall.profile_server")
        if "Test Context" in config_lib.CONFIG.context:
            # We're running in a test context, where the rekall repository server is
            # set to TestRekallRepositoryProfileServer, which won't actually work for
            # an end to end test. We change it temporarily to allow the test to pass.
            config_lib.CONFIG.Set("Rekall.profile_server",
                                  "GRRRekallProfileServer")

        # RDFValueCollections need to be deleted recursively.
        aff4.FACTORY.Delete(self.client_id.Add(self.test_output_path),
                            token=self.token)
        super(AbstractTestAnalyzeClientMemory, self).setUp()

    def tearDown(self):
        # RDFValueCollections need to be deleted recursively.
        aff4.FACTORY.Delete(self.client_id.Add(self.test_output_path),
                            token=self.token)
        config_lib.CONFIG.Set("Rekall.profile_server", self.old_config)
        super(AbstractTestAnalyzeClientMemory, self).tearDown()

    def CheckFlow(self):
        self.response = aff4.FACTORY.Open(self.client_id.Add(
            self.test_output_path),
                                          token=self.token)
        self.assertIsInstance(self.response, aff4.RDFValueCollection)
        self.assertTrue(len(self.response) >= 1)

    def OpenFlow(self):
        """Returns the flow used on this test."""
        return aff4.FACTORY.Open(str(self.session_id), token=self.token)
예제 #9
0
  def RekallPlugin(self, source):
    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Only use these methods for listing processes.
        rdf_rekall_types.PluginRequest(
            plugin=source.attributes["plugin"],
            args=source.attributes.get("args", {}))]

    self.CallFlow(
        "AnalyzeClientMemory", request=request,
        request_data={"artifact_name": self.current_artifact_name,
                      "rekall_plugin": source.attributes["plugin"],
                      "source": source.ToPrimitiveDict()},
        next_state="ProcessCollected"
    )
예제 #10
0
class AbstractTestAnalyzeClientMemory(base.ClientTestBase):
    """Test AnalyzeClientMemory (Rekall).

  We use the rekall caching profile server for these tests, since we may not
  have direct internet access. It may be necessary to manually populate the
  cache with lib.rekall_profile_server.GRRRekallProfileServer.GetMissingProfiles
  on the console to make these tests pass.
  """
    flow = memory.AnalyzeClientMemory.__name__
    args = {"request": rdf_rekall_types.RekallRequest()}

    def setUpRequest(self):
        raise NotImplementedError("Implemented by subclasses")

    def setUp(self):
        self.setUpRequest()

        self.old_config = config.CONFIG.Get("Rekall.profile_server")
        if "Test Context" in config.CONFIG.context:
            # We're running in a test context, where the rekall repository server is
            # set to TestRekallRepositoryProfileServer, which won't actually work for
            # an end to end test. We change it temporarily to allow the test to pass.
            config.CONFIG.Set("Rekall.profile_server",
                              "GRRRekallProfileServer")

        super(AbstractTestAnalyzeClientMemory, self).setUp()

    def runTest(self):
        if not config.CONFIG["Rekall.enabled"]:
            return self.skipTest(
                "Rekall disabled. Set 'Rekall.enabled=True' in your config to enable"
            )
        else:
            super(AbstractTestAnalyzeClientMemory, self).runTest()

    def tearDown(self):
        if "Test Context" in config.CONFIG.context:
            config.CONFIG.Set("Rekall.profile_server", self.old_config)
        super(AbstractTestAnalyzeClientMemory, self).tearDown()

    def CheckFlow(self):
        self.responses = self.CheckResultCollectionNotEmptyWithRetry(
            self.session_id)

    def OpenFlow(self):
        """Returns the flow used on this test."""
        return aff4.FACTORY.Open(str(self.session_id), token=self.token)
예제 #11
0
  def CheckFreeSpaceLinux(self, responses):
    if responses.success and responses.First():
      disk_usage = responses.First()
      if disk_usage.free < self.state.memory_size:
        raise flow.FlowError(
            "Free space may be too low for local copy. Free "
            "space for path %s is %s bytes. Mem size is: %s "
            "bytes. Override with check_disk_free_space=False."
            % (disk_usage.path, disk_usage.free, self.state.memory_size))
    else:
      logging.error(
          "Couldn't determine free disk space for temporary files.")

    plugin = rekall_types.PluginRequest(plugin="ewfacquire")
    request = rekall_types.RekallRequest(plugins=[plugin])
    self.CallFlow("AnalyzeClientMemory", request=request,
                  max_file_size_download=self.action_options.max_file_size,
                  next_state="CheckAnalyzeClientMemory")
예제 #12
0
  def testParameters(self):
    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Only use these methods for listing processes.
        rdf_rekall_types.PluginRequest(
            plugin="pslist",
            args=dict(pids=[4, 2860], method="PsActiveProcessHead")),
    ]

    session_id = self.LaunchRekallPlugin(request)

    # Get the result collection.
    fd = flow.GRRFlow.ResultCollectionForFID(session_id, token=self.token)

    json_blobs = [x.json_messages for x in fd]
    json_blobs = "".join(json_blobs)

    for knownresult in ["System", "DumpIt.exe"]:
      self.assertTrue(knownresult in json_blobs)
예제 #13
0
  def testDLLList(self):
    """Tests that we can run a simple DLLList Action."""
    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Only use these methods for listing processes.
        rdf_rekall_types.PluginRequest(
            plugin="dlllist",
            args=dict(proc_regex="dumpit", method="PsActiveProcessHead")),
    ]

    session_id = self.LaunchRekallPlugin(request)

    # Get the result collection.
    fd = flow.GRRFlow.ResultCollectionForFID(session_id, token=self.token)

    json_blobs = [x.json_messages for x in fd]
    json_blobs = "".join(json_blobs)

    for knownresult in ["DumpIt", "wow64win", "wow64", "wow64cpu", "ntdll"]:
      self.assertTrue(knownresult in json_blobs)
예제 #14
0
    def testParameters(self):
        request = rdf_rekall_types.RekallRequest()
        request.plugins = [
            # Only use these methods for listing processes.
            rdf_rekall_types.PluginRequest(plugin="pslist",
                                           args=dict(
                                               pid=[4, 2860],
                                               method="PsActiveProcessHead")),
        ]

        self.LaunchRekallPlugin(request)

        # Get the result collection - it should be a RekallResponseCollection.
        fd = aff4.FACTORY.Open(self.client_id.Add("analysis/memory"),
                               token=self.token)

        json_blobs = [x.json_messages for x in fd]
        json_blobs = "".join(json_blobs)

        for knownresult in ["System", "DumpIt.exe"]:
            self.assertTrue(knownresult in json_blobs)
예제 #15
0
  def testDLLList(self):
    """Tests that we can run a simple DLLList Action."""
    request = rdf_rekall_types.RekallRequest()
    request.plugins = [
        # Only use these methods for listing processes.
        rdf_rekall_types.PluginRequest(plugin="dlllist",
                                       args=dict(proc_regex="dumpit",
                                                 method="PsActiveProcessHead")),
    ]

    self.LaunchRekallPlugin(request)

    # Get the result collection - it should be a RekallResponseCollection.
    fd = aff4.FACTORY.Open(
        self.client_id.Add("analysis/memory"),
        token=self.token)

    json_blobs = [x.json_messages for x in fd]
    json_blobs = "".join(json_blobs)

    for knownresult in ["DumpIt", "wow64win", "wow64", "wow64cpu", "ntdll"]:
      self.assertTrue(knownresult in json_blobs)