Exemplo n.º 1
0
  def RunFlow(self,
              flow_name=None,
              plugins=None,
              flow_args=None,
              client_mock=None):
    runner_args = rdf_flow_runner.FlowRunnerArgs(
        flow_name=flow_name or transfer.GetFile.__name__,
        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 = hunt_test_lib.SampleHuntMock()

    return flow_test_lib.TestFlowHelper(
        flow_name,
        args=flow_args,
        runner_args=runner_args,
        client_mock=client_mock,
        client_id=self.client_id,
        token=self.token)
Exemplo n.º 2
0
    def setUp(self):
        super(DeleteGRRTempFiles, self).setUp()
        filename = "%s_blah" % config.CONFIG["Client.tempfile_prefix"]
        self.tempfile = utils.JoinPath(self.temp_dir, "delete_test", filename)
        self.dirname = os.path.dirname(self.tempfile)
        os.makedirs(self.dirname)
        self.tempdir_overrider = test_lib.ConfigOverrider({
            "Client.tempdir_roots": [os.path.dirname(self.dirname)],
            "Client.grr_tempdir":
            os.path.basename(self.dirname)
        })
        self.tempdir_overrider.Start()

        self.not_tempfile = os.path.join(self.temp_dir, "notatempfile")
        open(self.not_tempfile, "wb").write("something")

        self.temp_fd = tempfiles.CreateGRRTempFile(filename="file1")
        self.temp_fd2 = tempfiles.CreateGRRTempFile(filename="file2")
        self.assertTrue(os.path.exists(self.not_tempfile))
        self.assertTrue(os.path.exists(self.temp_fd.name))
        self.assertTrue(os.path.exists(self.temp_fd2.name))

        self.pathspec = rdf_paths.PathSpec(
            path=self.dirname, pathtype=rdf_paths.PathSpec.PathType.OS)
Exemplo n.º 3
0
    def testShowsNotificationIfArchiveStreamingFailsInProgress(self):
        pathspec = rdf_paths.PathSpec(path=os.path.join(
            self.base_path, "test.plist"),
                                      pathtype=rdf_paths.PathSpec.PathType.OS)
        flow_urn = flow.StartAFF4Flow(
            flow_name=flows_transfer.GetFile.__name__,
            client_id=self.client_id,
            pathspec=pathspec,
            token=self.token)

        flow_test_lib.TestFlowHelper(flow_urn,
                                     self.action_mock,
                                     client_id=self.client_id,
                                     token=self.token)

        def RaisingStub(*unused_args, **unused_kwargs):
            yield b"foo"
            yield b"bar"
            raise RuntimeError("something went wrong")

        with utils.Stubber(api_call_handler_utils.CollectionArchiveGenerator,
                           "Generate", RaisingStub):
            self.Open("/#/clients/%s" % self.client_id)

            self.Click("css=a[grrtarget='client.flows']")
            self.Click("css=td:contains('GetFile')")
            self.Click("link=Results")
            self.Click("css=button.DownloadButton")

            self.WaitUntil(
                self.IsUserNotificationPresent,
                "Archive generation failed for flow %s" % flow_urn.Basename())
            # There will be no failure message, as we can't get a status from an
            # iframe that triggers the download.
            self.WaitUntilNot(self.IsTextPresent,
                              "Can't generate archive: Unknown error")
Exemplo n.º 4
0
    def testShowsNotificationWhenArchiveGenerationIsDone(self):
        pathspec = rdf_paths.PathSpec(path=os.path.join(
            self.base_path, "test.plist"),
                                      pathtype=rdf_paths.PathSpec.PathType.OS)
        flow_urn = flow.StartAFF4Flow(
            flow_name=flows_transfer.GetFile.__name__,
            client_id=self.client_id,
            pathspec=pathspec,
            token=self.token)

        flow_test_lib.TestFlowHelper(flow_urn,
                                     self.action_mock,
                                     client_id=self.client_id,
                                     token=self.token)

        self.Open("/#/clients/%s" % self.client_id)

        self.Click("css=a[grrtarget='client.flows']")
        self.Click("css=td:contains('GetFile')")
        self.Click("link=Results")
        self.Click("css=button.DownloadButton")
        self.WaitUntil(self.IsTextPresent, "Generation has started")
        self.WaitUntil(self.IsUserNotificationPresent,
                       "Downloaded archive of flow %s" % flow_urn.Basename())
Exemplo n.º 5
0
    def testNestedProtobufAssignment(self):
        """Check that we can assign a nested protobuf."""
        container = rdf_client.BufferReference()
        test_path = "C:\\test"
        pathspec = rdf_paths.PathSpec(path=test_path, pathtype=1)

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

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

        # Assign directly.
        container.device = pathspec

        self.assertEqual(container.device.path, test_path)

        # Clear the field.
        container.device = None

        # Check the protobuf does not have the field set at all.
        self.assertFalse(container.HasField("pathspec"))
Exemplo n.º 6
0
    def testExistingFileStat(self):
        bash_stat = {
            "st_ctime":
            rdfvalue.RDFDatetimeSeconds(1299502221),
            "st_rdev":
            0,
            "st_mtime":
            rdfvalue.RDFDatetimeSeconds(1284154642),
            "st_blocks":
            16,
            "st_nlink":
            1,
            "st_gid":
            0,
            "st_blksize":
            4096,
            "pathspec":
            rdf_paths.PathSpec(path="/bin/bash",
                               pathtype="OS",
                               path_options="CASE_LITERAL"),
            "st_dev":
            51713,
            "st_size":
            4874,
            "st_ino":
            1026148,
            "st_uid":
            0,
            "st_mode":
            rdf_client_fs.StatMode(33261),
            "st_atime":
            rdfvalue.RDFDatetimeSeconds(1299502220)
        }

        bash_path = os.path.join("/", self.client_name, "fs/os/c/bin/bash")
        self.assertItemsEqual(self.passthrough.getattr(bash_path), bash_stat)
Exemplo n.º 7
0
    def Run(self, args):
        """Use eficheck to extract the binary image of the flash.

    Args:
      args: EficheckConfig
    Returns:
      DumpEfiImageResponse

    This action executes eficheck multiple times:
      * First to get the binary version, using --version.
      * Use --save -b firmware.bin to save the image.
    """

        eficheck_version = self._GetVersion(args)
        if not eficheck_version:
            return False

        with tempfiles.TemporaryDirectory(cleanup=False) as tmp_dir:
            res = client_utils_common.Execute(args.cmd_path,
                                              ["--save", "-b", "firmware.bin"],
                                              cwd=tmp_dir.path)
            stdout, stderr, exit_status, time_used = res
            binary_response = rdf_client_action.ExecuteBinaryResponse(
                stdout=stdout,
                stderr=stderr,
                exit_status=exit_status,
                time_used=time_used)
            response = rdf_apple_firmware.DumpEfiImageResponse(
                eficheck_version=eficheck_version, response=binary_response)
            if exit_status:
                tmp_dir.cleanup = True
            else:
                response.path = rdf_paths.PathSpec(
                    path=os.path.join(tmp_dir.path, "firmware.bin"),
                    pathtype=rdf_paths.PathSpec.PathType.TMPFILE)
            self.SendReply(response)
Exemplo n.º 8
0
  def testGuessPathSpecPartial(self):
    """Test that we can guess a pathspec from a partial pathspec."""
    path = os.path.join(self.base_path, "test_img.dd")
    pathspec = rdf_paths.PathSpec(
        path=path, pathtype=rdf_paths.PathSpec.PathType.OS)
    pathspec.nested_path.path = "/home/image2.img/home/a.txt"
    pathspec.nested_path.pathtype = rdf_paths.PathSpec.PathType.TSK

    fd = vfs.VFSOpen(pathspec)
    self.assertEqual(fd.read(3), "yay")

    # Open as a directory
    pathspec.nested_path.path = "/home/image2.img/home/"

    fd = vfs.VFSOpen(pathspec)

    names = []
    for s in fd.ListFiles():
      # Make sure that the stat pathspec is correct - it should be 3 levels
      # deep.
      self.assertEqual(s.pathspec.nested_path.path, "/home/image2.img")
      names.append(s.pathspec.nested_path.nested_path.path)

    self.assertIn("home/a.txt", names)
Exemplo n.º 9
0
    def testCopyHuntPreservesRuleType(self):
        implementation.StartHunt(
            hunt_name=standard.GenericHunt.__name__,
            description="model hunt",
            flow_runner_args=rdf_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.TSK,
            )),
            client_rule_set=foreman_rules.ForemanClientRuleSet(rules=[
                foreman_rules.ForemanClientRule(
                    rule_type=foreman_rules.ForemanClientRule.Type.OS,
                    os=foreman_rules.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.IsElementPresent,
                       "css=grr-wizard-form:contains('Hunt parameters')")
        # Click on "Next" button.
        self.Click("css=grr-new-hunt-wizard-form button.Next")
        self.WaitUntil(self.IsTextPresent, "How to process results")
        # 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")
Exemplo n.º 10
0
    def checkClickingOnDownloadAsStartsDownloadForType(self, mock_method,
                                                       plugin,
                                                       plugin_display_name):
        pathspec = rdf_paths.PathSpec(path=os.path.join(
            self.base_path, "test.plist"),
                                      pathtype=rdf_paths.PathSpec.PathType.OS)
        session_id = flow_test_lib.TestFlowHelper(
            flows_transfer.GetFile.__name__,
            pathspec=pathspec,
            client_mock=self.action_mock,
            client_id=self.client_id,
            token=self.token)
        if not data_store.RelationalDBFlowsEnabled():
            session_id = session_id.Basename()

        self.Open("/#/clients/%s/flows/%s" % (self.client_id, session_id))
        self.Click("link=Results")
        self.Select("id=plugin-select", plugin_display_name)
        self.Click("css=grr-download-collection-as button[name='download-as']")

        def MockMethodIsCalled():
            try:
                # Mock should be called twice: once for HEAD (to check permissions)
                # and once for GET methods.
                mock_method.assert_called_with(
                    api_flow.ApiGetExportedFlowResultsArgs(
                        client_id=self.client_id,
                        flow_id=session_id,
                        plugin_name=plugin),
                    token=mock.ANY)

                return True
            except AssertionError:
                return False

        self.WaitUntil(MockMethodIsCalled)
Exemplo n.º 11
0
  def testStartVariableHuntRaisesIfMoreThanOneFlowPerClient(self):
    client_id = self.SetupClients(1)[0]

    hunt_obj = rdf_hunt_objects.Hunt(client_rate=0)
    hunt_obj.args.hunt_type = hunt_obj.args.HuntType.VARIABLE
    for index in range(2):
      hunt_obj.args.variable.flow_groups.append(
          rdf_hunt_objects.VariableHuntFlowGroup(
              client_ids=[client_id.Basename()],
              flow_name=compatibility.GetName(transfer.GetFile),
              flow_args=transfer.GetFileArgs(
                  pathspec=rdf_paths.PathSpec(
                      path="/tmp/evil_%d.txt" % index,
                      pathtype=rdf_paths.PathSpec.PathType.OS,
                  ))))

    data_store.REL_DB.WriteHuntObject(hunt_obj)

    with self.assertRaises(hunt.CanStartAtMostOneFlowPerClientError):
      hunt.StartHunt(hunt_obj.hunt_id)

    # Check that no flows were scheduled on the client.
    flows = data_store.REL_DB.ReadAllFlowObjects(client_id.Basename())
    self.assertEmpty(flows)
Exemplo n.º 12
0
  def ListDeviceDirectories(self, responses):
    """Flow state that calls ListDirectory action for each shadow copy."""

    if not responses.success:
      raise flow_base.FlowError(
          "Unable to query Volume Shadow Copy information.")

    shadows_found = False
    for response in responses:
      device_object = response.GetItem("DeviceObject", "")
      global_root = r"\\?\GLOBALROOT\Device"

      if device_object.startswith(global_root):
        # The VSC device path is returned as \\?\GLOBALROOT\Device\
        # HarddiskVolumeShadowCopy1 and need to pass it as
        #  \\.\HarddiskVolumeShadowCopy1 to the ListDirectory flow
        device_object = r"\\." + device_object[len(global_root):]

        path_spec = rdf_paths.PathSpec(
            path=device_object, pathtype=rdf_paths.PathSpec.PathType.OS)

        path_spec.Append(path="/", pathtype=rdf_paths.PathSpec.PathType.TSK)

        self.Log("Listing Volume Shadow Copy device: %s.", device_object)
        self.CallClient(
            server_stubs.ListDirectory,
            pathspec=path_spec,
            next_state=compatibility.GetName(self.ProcessListDirectory))

        shadows_found = True

    if not shadows_found:
      raise flow_base.FlowError("No Volume Shadow Copies were found.\n"
                                "The volume could have no Volume Shadow Copies "
                                "as Windows versions pre Vista or the Volume "
                                "Shadow Copy Service has been disabled.")
Exemplo n.º 13
0
  def testVariableHuntSchedulesAllFlowsOnStart(self):
    client_ids = self.SetupClients(10)

    hunt_obj = rdf_hunt_objects.Hunt(client_rate=0)
    hunt_obj.args.hunt_type = hunt_obj.args.HuntType.VARIABLE

    for index, pair in enumerate(collection.Batch(client_ids, 2)):
      hunt_obj.args.variable.flow_groups.append(
          rdf_hunt_objects.VariableHuntFlowGroup(
              client_ids=pair,
              flow_name=compatibility.GetName(transfer.GetFile),
              flow_args=transfer.GetFileArgs(
                  pathspec=rdf_paths.PathSpec(
                      path="/tmp/evil_%d.txt" % index,
                      pathtype=rdf_paths.PathSpec.PathType.OS,
                  ))))

    data_store.REL_DB.WriteHuntObject(hunt_obj)
    hunt.StartHunt(hunt_obj.hunt_id)

    hunt_counters = data_store.REL_DB.ReadHuntCounters(hunt_obj.hunt_id)
    self.assertEqual(hunt_counters.num_clients, 10)

    all_flows = data_store.REL_DB.ReadHuntFlows(hunt_obj.hunt_id, 0,
                                                sys.maxsize)
    self.assertItemsEqual(client_ids, [f.client_id for f in all_flows])

    for index, pair in enumerate(collection.Batch(client_ids, 2)):
      for client_id in pair:
        all_flows = data_store.REL_DB.ReadAllFlowObjects(client_id)
        self.assertLen(all_flows, 1)

        self.assertEqual(all_flows[0].flow_class_name,
                         compatibility.GetName(transfer.GetFile))
        self.assertEqual(all_flows[0].args.pathspec.path,
                         "/tmp/evil_%d.txt" % index)
Exemplo n.º 14
0
    def testDownloadFilesPanelIsShownWhenNewResultsAreAdded(self):
        f = flow.StartFlow(client_id=self.client_id,
                           flow_name=gui_test_lib.RecursiveTestFlow.__name__,
                           token=self.token)

        with data_store.DB.GetMutationPool() as pool:
            flow.GRRFlow.ResultCollectionForFID(f).Add(
                rdfvalue.RDFString("foo-result"), mutation_pool=pool)

        self.Open("/#/clients/%s" % self.client_id)
        # Ensure auto-refresh updates happen every second.
        self.GetJavaScriptValue(
            "grrUi.core.resultsCollectionDirective.setAutoRefreshInterval(1000);"
        )

        # Go to the flows page without refreshing the page, so that
        # AUTO_REFRESH_INTERVAL_MS setting is not reset.
        self.Click("css=a[grrtarget='client.flows']")
        self.Click("css=tr:contains('%s')" % f.Basename())
        self.Click("css=li[heading=Results]:not([disabled]")

        self.WaitUntil(self.IsElementPresent,
                       "css=grr-results-collection td:contains('foo-result')")
        self.WaitUntilNot(
            self.IsElementPresent,
            "css=grr-results-collection grr-download-collection-files")

        stat_entry = rdf_client_fs.StatEntry(pathspec=rdf_paths.PathSpec(
            path="/foo/bar", pathtype=rdf_paths.PathSpec.PathType.OS))
        with data_store.DB.GetMutationPool() as pool:
            flow.GRRFlow.ResultCollectionForFID(f).Add(stat_entry,
                                                       mutation_pool=pool)

        self.WaitUntil(
            self.IsElementPresent,
            "css=grr-results-collection grr-download-collection-files")
Exemplo n.º 15
0
    def _Recurse(self, path, depth):
        """Recurses to the given path if necessary up to the given depth."""
        if self.opts.pathtype == rdf_paths.PathSpec.PathType.OS:
            try:
                stat_entry = os.stat(path)
            except OSError:
                # Can happen for links pointing to non existent files/directories.
                return

            if (self._allowed_devices is not _XDEV_ALL_ALLOWED
                    and stat_entry.st_dev not in self._allowed_devices):
                return

            if not stat.S_ISDIR(stat_entry.st_mode):
                return

            # Cannot use S_ISLNK here because we uses os.stat above which resolves
            # links.
            if not self.opts.follow_links and os.path.islink(path):
                return

        elif self.opts.pathtype == rdf_paths.PathSpec.PathType.REGISTRY:
            pathspec = rdf_paths.PathSpec(
                path=path, pathtype=rdf_paths.PathSpec.PathType.REGISTRY)
            try:
                with vfs.VFSOpen(pathspec) as filedesc:
                    if not filedesc.IsDirectory():
                        return
            except IOError:
                return  # Skip inaccessible Registry parts (e.g. HKLM\SAM\SAM) silently.
        else:
            raise AssertionError("Invalid pathtype {}".format(
                self.opts.pathtype))

        for childpath in self._Generate(path, depth + 1):
            yield childpath
Exemplo n.º 16
0
  def testFindAction(self):
    """Test the find action."""
    # First get all the files at once
    pathspec = rdf_paths.PathSpec(
        path="/mock2/", pathtype=rdf_paths.PathSpec.PathType.OS)
    request = rdf_client_fs.FindSpec(pathspec=pathspec, path_regex=".")
    request.iterator.number = 200
    result = self.RunAction(searching.Find, request)
    all_files = [x.hit for x in result if isinstance(x, rdf_client_fs.FindSpec)]

    # Ask for the files one at the time
    files = []
    request = rdf_client_fs.FindSpec(pathspec=pathspec, path_regex=".")
    request.iterator.number = 1

    while True:
      result = self.RunAction(searching.Find, request)
      if request.iterator.state == rdf_client_action.Iterator.State.FINISHED:
        break

      self.assertLen(result, 2)
      self.assertIsInstance(result[0], rdf_client_fs.FindSpec)
      self.assertIsInstance(result[1], rdf_client_action.Iterator)
      files.append(result[0].hit)

      request.iterator = result[1].Copy()

    for x, y in zip(all_files, files):
      self.assertEqual(x, y)

    # Make sure the iterator is finished
    self.assertEqual(request.iterator.state,
                     rdf_client_action.Iterator.State.FINISHED)

    # Ensure we remove old states from client_state
    self.assertEmpty(request.iterator.client_state.dat)
Exemplo n.º 17
0
def StatFSFromClient(args):
  """Call os.statvfs for a given list of paths.

  Args:
    args: An `rdf_client_action.StatFSRequest`.

  Yields:
    `rdf_client_fs.UnixVolume` instances.

  Raises:
    RuntimeError: if called on a Windows system.
  """
  if platform.system() == "Windows":
    raise RuntimeError("os.statvfs not available on Windows")

  for path in args.path_list:

    try:
      fd = vfs.VFSOpen(rdf_paths.PathSpec(path=path, pathtype=args.pathtype))
      st = fd.StatFS()
      mount_point = fd.GetMountPoint()
    except (IOError, OSError):
      continue

    unix = rdf_client_fs.UnixVolume(mount_point=mount_point)

    # On linux pre 2.6 kernels don't have frsize, so we fall back to bsize.
    # The actual_available_allocation_units attribute is set to blocks
    # available to the unprivileged user, root may have some additional
    # reserved space.
    yield rdf_client_fs.Volume(
        bytes_per_sector=(st.f_frsize or st.f_bsize),
        sectors_per_allocation_unit=1,
        total_allocation_units=st.f_blocks,
        actual_available_allocation_units=st.f_bavail,
        unixvolume=unix)
Exemplo n.º 18
0
    def CreateSampleHunt(self,
                         path=None,
                         stopped=False,
                         output_plugins=None,
                         client_limit=0,
                         client_count=10,
                         creator=None):
        self.client_ids = self.SetupClients(client_count)

        self.hunt_urn = self.StartHunt(
            flow_runner_args=rdf_flow_runner.FlowRunnerArgs(
                flow_name=compatibility.GetName(transfer.GetFile)),
            flow_args=transfer.GetFileArgs(pathspec=rdf_paths.PathSpec(
                path=path or "/tmp/evil.txt",
                pathtype=rdf_paths.PathSpec.PathType.OS,
            )),
            client_rule_set=self._CreateForemanClientRuleSet(),
            output_plugins=output_plugins or [],
            client_rate=0,
            client_limit=client_limit,
            creator=creator or self.token.username,
            paused=stopped)

        return self.hunt_urn
Exemplo n.º 19
0
  def testNotificationWhenListingRegistry(self):
    # Change the username so notifications get written.
    token = self.token.Copy()
    token.username = "******"
    acl_test_lib.CreateUser(token.username)

    with vfs_test_lib.RegistryVFSStubber():
      client_id = self.SetupClient(0)
      pb = rdf_paths.PathSpec(
          path="/HKEY_LOCAL_MACHINE/SOFTWARE/ListingTest",
          pathtype=rdf_paths.PathSpec.PathType.REGISTRY)

      client_mock = action_mocks.ListDirectoryClientMock()

      flow_test_lib.TestFlowHelper(
          compatibility.GetName(filesystem.ListDirectory),
          client_mock,
          client_id=client_id,
          pathspec=pb,
          token=token)

    if data_store.RelationalDBEnabled():
      notifications = data_store.REL_DB.ReadUserNotifications(token.username)
      self.assertLen(notifications, 1)
      n = notifications[0]
      self.assertEqual(n.reference.vfs_file.path_type,
                       rdf_objects.PathInfo.PathType.REGISTRY)
      self.assertEqual(n.reference.vfs_file.path_components,
                       ["HKEY_LOCAL_MACHINE", "SOFTWARE", "ListingTest"])
    else:
      user = aff4.FACTORY.Open("aff4:/users/%s" % token.username, token=token)
      notifications = user.Get(user.Schema.PENDING_NOTIFICATIONS)
      self.assertLen(notifications, 1)
      expected_urn = ("aff4:/C.1000000000000000/registry/"
                      "HKEY_LOCAL_MACHINE/SOFTWARE/ListingTest")
      self.assertEqual(notifications[0].subject, expected_urn)
Exemplo n.º 20
0
    def testExtAttrsCollection(self):
        with temp.AutoTempDirPath(remove_non_empty=True) as temp_dirpath:
            foo_filepath = temp.TempFilePath(dir=temp_dirpath)
            client_test_lib.SetExtAttr(foo_filepath,
                                       name="user.quux",
                                       value="foo")

            bar_filepath = temp.TempFilePath(dir=temp_dirpath)
            client_test_lib.SetExtAttr(bar_filepath,
                                       name="user.quux",
                                       value="bar")

            baz_filepath = temp.TempFilePath(dir=temp_dirpath)
            client_test_lib.SetExtAttr(baz_filepath,
                                       name="user.quux",
                                       value="baz")

            request = rdf_client_fs.FindSpec(pathspec=rdf_paths.PathSpec(
                path=temp_dirpath, pathtype=rdf_paths.PathSpec.PathType.OS),
                                             path_glob="*",
                                             collect_ext_attrs=True)
            request.iterator.number = 100

            hits = []
            for response in self.RunAction(searching.Find, request):
                if isinstance(response, rdf_client_fs.FindSpec):
                    hits.append(response.hit)

            self.assertLen(hits, 3)

            values = []
            for hit in hits:
                self.assertLen(hit.ext_attrs, 1)
                values.append(hit.ext_attrs[0].value)

            self.assertCountEqual(values, ["foo", "bar", "baz"])
Exemplo n.º 21
0
    def testRegistryListing(self):
        """Test our ability to list registry keys."""
        reg = rdf_paths.PathSpec.PathType.REGISTRY
        with vfs_test_lib.VFSOverrider(reg,
                                       vfs_test_lib.FakeRegistryVFSHandler):
            pathspec = rdf_paths.PathSpec(
                pathtype=rdf_paths.PathSpec.PathType.REGISTRY,
                path=("/HKEY_USERS/S-1-5-20/Software/Microsoft"
                      "/Windows/CurrentVersion/Run"))

            expected_names = {
                "MctAdmin": stat.S_IFDIR,
                "Sidebar": stat.S_IFDIR
            }
            expected_data = [
                u"%ProgramFiles%\\Windows Sidebar\\Sidebar.exe /autoRun",
                u"%TEMP%\\Sidebar.exe"
            ]

            for f in vfs.VFSOpen(pathspec).ListFiles():
                base, name = os.path.split(f.pathspec.CollapsePath())
                self.assertEqual(base, pathspec.CollapsePath())
                self.assertIn(name, expected_names)
                self.assertIn(f.registry_data.GetValue(), expected_data)
Exemplo n.º 22
0
    def testGetFile(self):
        """Test that the GetFile flow works."""

        client_mock = action_mocks.GetFileClientMock()
        pathspec = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS,
                                      path=os.path.join(
                                          self.base_path, "test_img.dd"))

        flow_test_lib.TestFlowHelper(transfer.GetFile.__name__,
                                     client_mock,
                                     token=self.token,
                                     client_id=self.client_id,
                                     pathspec=pathspec)

        # Fix path for Windows testing.
        pathspec.path = pathspec.path.replace("\\", "/")
        # Test the AFF4 file that was created.
        urn = pathspec.AFF4Path(self.client_id)
        fd1 = aff4.FACTORY.Open(urn, token=self.token)
        fd2 = open(pathspec.path, "rb")
        fd2.seek(0, 2)

        self.assertEqual(fd2.tell(), int(fd1.Get(fd1.Schema.SIZE)))
        self.CompareFDs(fd1, fd2)
Exemplo n.º 23
0
 def Start(self):
     self.SendReply(
         rdf_client_fs.StatEntry(pathspec=rdf_paths.PathSpec(
             path="/some/unique/path",
             pathtype=rdf_paths.PathSpec.PathType.OS)))
Exemplo n.º 24
0
  def testUnicodeSupport(self):
    pathspec = rdf_paths.PathSpec(
        path="/foobar", pathtype=rdf_paths.PathSpec.PathType.TSK)
    pathspec.path = u"Grüezi"

    self.assertEqual(pathspec.path, u"Grüezi")
Exemplo n.º 25
0
 def CreateStat(self, path, uid=0, gid=0, mode=0o0100640):
   """Given path, uid, gid and file mode, this returns a StatEntry."""
   pathspec = rdf_paths.PathSpec(path=path, pathtype="OS")
   return rdf_client_fs.StatEntry(
       pathspec=pathspec, st_uid=uid, st_gid=gid, st_mode=mode)
Exemplo n.º 26
0
    def StoreResults(self, responses):
        """Stores the results."""
        if not responses.success:
            self.state.plugin_errors.append(
                unicode(responses.status.error_message))
            # Keep processing to read out the debug messages from the json.

        self.Log("Rekall returned %s responses." % len(responses))
        for response in responses:
            if response.missing_profile:
                profile = self.GetProfileByName(response.missing_profile,
                                                response.repository_version)
                if profile:
                    self.CallClient(server_stubs.WriteRekallProfile,
                                    profile,
                                    next_state="UpdateProfile")
                else:
                    self.Log(
                        "Needed profile %s not found! See "
                        "https://github.com/google/grr-doc/blob/master/"
                        "troubleshooting.adoc#missing-rekall-profiles",
                        response.missing_profile)

            if response.json_messages:
                response.client_urn = self.client_id
                if self.state.rekall_context_messages:
                    response.json_context_messages = json.dumps(
                        list(iteritems(self.state.rekall_context_messages)),
                        separators=(",", ":"))

                json_data = json.loads(response.json_messages)
                for message in json_data:
                    if len(message) >= 1:
                        if message[0] in ["t", "s"]:
                            self.state.rekall_context_messages[
                                message[0]] = message[1]

                        if message[0] == "file":
                            pathspec = rdf_paths.PathSpec(**message[1])
                            self.state.output_files.append(pathspec)

                        if message[0] == "L":
                            if len(message) > 1:
                                log_record = message[1]
                                self.Log("%s:%s:%s", log_record["level"],
                                         log_record["name"], log_record["msg"])

                self.SendReply(response)

        if (responses.iterator and  # This will be None if an error occurred.
                responses.iterator.state !=
                rdf_client.Iterator.State.FINISHED):
            self.state.rekall_request.iterator = responses.iterator
            self.CallClient(server_stubs.RekallAction,
                            self.state.rekall_request,
                            next_state="StoreResults")
        else:
            if self.state.output_files:
                self.Log("Getting %i files.", len(self.state.output_files))
                self.CallFlow(transfer.MultiGetFile.__name__,
                              pathspecs=self.state.output_files,
                              file_size=self.args.max_file_size_download,
                              next_state="DeleteFiles")
Exemplo n.º 27
0
    def testMultiGetFileMultiFiles(self):
        """Test MultiGetFile downloading many files at once."""
        client_mock = action_mocks.MultiGetFileClientMock()

        pathspecs = []
        # Make 30 files to download.
        for i in range(30):
            path = os.path.join(self.temp_dir, "test_%s.txt" % i)
            with open(path, "wb") as fd:
                fd.write("Hello")

            pathspecs.append(
                rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS,
                                   path=path))

        args = transfer.MultiGetFileArgs(pathspecs=pathspecs,
                                         maximum_pending_files=10)
        session_id = flow_test_lib.TestFlowHelper(
            transfer.MultiGetFile.__name__,
            client_mock,
            token=self.token,
            client_id=self.client_id,
            args=args)

        if data_store.RelationalDBReadEnabled():
            # Now open each file and make sure the data is there.
            for pathspec in pathspecs:
                cp = db.ClientPath.FromPathSpec(self.client_id.Basename(),
                                                pathspec)
                fd_rel_db = file_store.OpenFile(cp)
                self.assertEqual("Hello", fd_rel_db.read())

                # Check that SHA256 hash of the file matches the contents
                # hash and that MD5 and SHA1 are set.
                history = data_store.REL_DB.ReadPathInfoHistory(
                    cp.client_id, cp.path_type, cp.components)
                self.assertEqual(history[-1].hash_entry.sha256,
                                 fd_rel_db.hash_id.AsBytes())
                self.assertIsNotNone(history[-1].hash_entry.sha1)
                self.assertIsNotNone(history[-1].hash_entry.md5)
        else:
            # Check up on the internal flow state.
            flow_state = flow_test_lib.GetFlowState(self.client_id,
                                                    session_id,
                                                    token=self.token)
            # All the pathspecs should be in this list.
            self.assertLen(flow_state.indexed_pathspecs, 30)

            # At any one time, there should not be more than 10 files or hashes
            # pending.
            self.assertLessEqual(len(flow_state.pending_files), 10)
            self.assertLessEqual(len(flow_state.pending_hashes), 10)

            # When we finish there should be no pathspecs stored in the flow state.
            for flow_pathspec in flow_state.indexed_pathspecs:
                self.assertIsNone(flow_pathspec)
            for flow_request_data in flow_state.request_data_list:
                self.assertIsNone(flow_request_data)

            for pathspec in pathspecs:
                urn = pathspec.AFF4Path(self.client_id)
                fd = aff4.FACTORY.Open(urn, token=self.token)
                self.assertEqual("Hello", fd.read())
Exemplo n.º 28
0
    def testMultiGetFileOfSpecialFiles(self):
        """Test that special /proc/ files are handled correctly.

    /proc/ files have the property that they are non seekable from their end
    (i.e. seeking them relative to the end is not supported). They also return
    an st_size of 0. For example:

    $ stat /proc/self/maps
    File: '/proc/self/maps'
    Size: 0   Blocks: 0   IO Block: 1024 regular empty file

    $ head /proc/self/maps
    00400000-00409000 r-xp 00000000 fc:01 9180740 /usr/bin/head
    00608000-00609000 r--p 00008000 fc:01 9180740 /usr/bin/head
    ...

    When we try to use the MultiGetFile flow, it deduplicates the files and
    since it thinks the file has a zero size, the flow will not download the
    file, and instead copy the zero size file into it.
    """
        client_mock = action_mocks.MultiGetFileClientMock()

        # # Create a zero sized file.
        zero_sized_filename = os.path.join(self.temp_dir, "zero_size")
        with open(zero_sized_filename, "wb") as fd:
            pass

        pathspec = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS,
                                      path=zero_sized_filename)

        flow_test_lib.TestFlowHelper(transfer.MultiGetFile.__name__,
                                     client_mock,
                                     token=self.token,
                                     file_size="1MiB",
                                     client_id=self.client_id,
                                     pathspecs=[pathspec])

        # Now if we try to fetch a real /proc/ filename this will fail because the
        # filestore already contains the zero length file
        # aff4:/files/nsrl/da39a3ee5e6b4b0d3255bfef95601890afd80709.
        pathspec = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS,
                                      path="/proc/self/environ")

        flow_test_lib.TestFlowHelper(transfer.MultiGetFile.__name__,
                                     client_mock,
                                     token=self.token,
                                     file_size=1024 * 1024,
                                     client_id=self.client_id,
                                     pathspecs=[pathspec])

        data = open(pathspec.last.path, "rb").read()

        if data_store.RelationalDBReadEnabled():
            cp = db.ClientPath.FromPathSpec(self.client_id.Basename(),
                                            pathspec)
            fd_rel_db = file_store.OpenFile(cp)
            self.assertEqual(fd_rel_db.size, len(data))
            self.assertMultiLineEqual(fd_rel_db.read(), data)

            # Check that SHA256 hash of the file matches the contents
            # hash and that MD5 and SHA1 are set.
            history = data_store.REL_DB.ReadPathInfoHistory(
                cp.client_id, cp.path_type, cp.components)
            self.assertEqual(history[-1].hash_entry.sha256,
                             fd_rel_db.hash_id.AsBytes())
            self.assertIsNotNone(history[-1].hash_entry.sha1)
            self.assertIsNotNone(history[-1].hash_entry.md5)
        else:
            # Test the AFF4 file that was created - it should be empty since by
            # default we judge the file size based on its stat.st_size.
            urn = pathspec.AFF4Path(self.client_id)
            fd = aff4.FACTORY.Open(urn, token=self.token)
            self.assertEqual(fd.size, len(data))
            self.assertMultiLineEqual(fd.read(len(data)), data)
Exemplo n.º 29
0
 def testReadMaxDword(self):
   fd = vfs.VFSOpen(
       rdf_paths.PathSpec(
           path=r"/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/maxdword",
           pathtype="REGISTRY"))
   self.assertEqual(fd.value, 0xFFFFFFFF)
Exemplo n.º 30
0
 def testFileReadLongUnicodeValue(self):
   fd = vfs.VFSOpen(
       rdf_paths.PathSpec(
           path=r"/HKEY_LOCAL_MACHINE/SOFTWARE/GRR_TEST/{}".format(_LONG_KEY),
           pathtype="REGISTRY"))
   self.assertEqual(fd.Read(-1).decode("utf-8"), _LONG_STRING_VALUE)