Beispiel #1
0
    def testUnknownAttributeScopeNotARealScope(self):
        kb = rdf_client.KnowledgeBase(os="Linux")

        with self.assertRaisesUnknownAttrs() as context:
            artifact_utils.InterpolateKbAttributes("%%os.version%%", kb)

        self.assertEqual(context.exception.attrs, ["os"])
Beispiel #2
0
  def GetRegistryValue(self, source):
    """Retrieve directly specified registry values, returning Stat objects."""
    new_paths = set()
    has_glob = False
    for kvdict in source.attributes["key_value_pairs"]:
      if "*" in kvdict["key"] or rdf_paths.GROUPING_PATTERN.search(
          kvdict["key"]):
        has_glob = True

      if kvdict["value"]:
        # This currently only supports key value pairs specified using forward
        # slash.
        path = "\\".join((kvdict["key"], kvdict["value"]))
      else:
        # If value is not set, we want to get the default value. In
        # GRR this is done by specifying the key only, so this is what
        # we do here.
        path = kvdict["key"]

      expanded_paths = artifact_utils.InterpolateKbAttributes(
          path,
          self.state.knowledge_base,
          ignore_errors=self.args.ignore_interpolation_errors)
      new_paths.update(expanded_paths)

    if has_glob:
      self.CallFlow(
          filesystem.Glob.__name__,
          paths=new_paths,
          pathtype=rdf_paths.PathSpec.PathType.REGISTRY,
          request_data={
              "artifact_name": self.current_artifact_name,
              "source": source.ToPrimitiveDict()
          },
          next_state="ProcessCollected")
    else:
      # We call statfile directly for keys that don't include globs because it
      # is faster and some artifacts rely on getting an IOError to trigger
      # fallback processing.
      for new_path in new_paths:
        pathspec = rdf_paths.PathSpec(
            path=new_path, pathtype=rdf_paths.PathSpec.PathType.REGISTRY)

        # TODO(hanuszczak): Support for old clients ends on 2021-01-01.
        # This conditional should be removed after that date.
        if self.client_version >= 3221:
          stub = server_stubs.GetFileStat
          request = rdf_client.GetFileStatRequest(pathspec=pathspec)
        else:
          stub = server_stubs.StatFile
          request = rdf_client.ListDirRequest(pathspec=pathspec)

        self.CallClient(
            stub,
            request,
            request_data={
                "artifact_name": self.current_artifact_name,
                "source": source.ToPrimitiveDict()
            },
            next_state="ProcessCollectedRegistryStatEntry")
Beispiel #3
0
    def testUnknownAttributeScopeVar(self):
        kb = rdf_client.KnowledgeBase()

        with self.assertRaisesUnknownAttrs() as context:
            artifact_utils.InterpolateKbAttributes("%%users.nonexistent%%", kb)

        self.assertEqual(context.exception.attrs, ["users.nonexistent"])
  def testEmptyAttribute(self):
    kb = rdf_client.KnowledgeBase(environ_allusersprofile="")

    with self.assertRaisesMissingAttrs() as context:
      artifact_utils.InterpolateKbAttributes("%%environ_allusersprofile%%", kb)

    self.assertEqual(context.exception.attrs, ["environ_allusersprofile"])
  def testMissingAttributeScope(self):
    kb = rdf_client.KnowledgeBase()

    with self.assertRaisesMissingAttrs() as context:
      artifact_utils.InterpolateKbAttributes("test%%users.username%%test", kb)

    self.assertEqual(context.exception.attrs, ["users"])
  def testMissingAttributeScopeVar(self):
    kb = rdf_client.KnowledgeBase()
    kb.users.Append(rdf_client.User(username="******", uid=42))
    with self.assertRaisesMissingAttrs() as context:
      artifact_utils.InterpolateKbAttributes("test%%users.temp%%test", kb)

    self.assertEqual(context.exception.attrs, ["users.temp"])
Beispiel #7
0
  def GetFiles(self, source, path_type, implementation_type, max_size):
    """Get a set of files."""
    new_path_list = []
    for path in source.attributes["paths"]:
      try:
        interpolated = artifact_utils.InterpolateKbAttributes(
            path, self.state.knowledge_base)
      except artifact_utils.KbInterpolationMissingAttributesError as error:
        logging.error(str(error))
        if not self.args.ignore_interpolation_errors:
          raise
        else:
          interpolated = []

      new_path_list.extend(interpolated)

    action = rdf_file_finder.FileFinderAction.Download(max_size=max_size)

    self.CallFlow(
        file_finder.FileFinder.__name__,
        paths=new_path_list,
        pathtype=path_type,
        implementation_type=implementation_type,
        action=action,
        request_data={
            "artifact_name": self.current_artifact_name,
            "source": source.ToPrimitiveDict()
        },
        next_state=compatibility.GetName(self.ProcessFileFinderResults))
Beispiel #8
0
  def _Interpolate(self,
                   pattern: Text,
                   knowledgebase: Optional[rdf_client.KnowledgeBase] = None)\
  -> Sequence[Text]:
    """Performs a knowledgebase interpolation.

    Args:
      pattern: A pattern to interpolate.
      knowledgebase: Knowledgebase to use for interpolation. If no knowledgebase
        is provided, the one provided as a flow argument is used.

    Returns:
      A list of possible interpolation results.
    """
    if knowledgebase is None:
      knowledgebase = self.state.knowledge_base

    try:
      return artifact_utils.InterpolateKbAttributes(pattern, knowledgebase)
    except artifact_utils.KbInterpolationMissingAttributesError as error:
      if self.args.old_client_snapshot_fallback:
        return []
      if self.args.ignore_interpolation_errors:
        logging.error(str(error))
        return []
      raise
Beispiel #9
0
    def ExplainComponents(
            self, example_count: int,
            knowledge_base) -> Sequence[GlobComponentExplanation]:
        """Returns a list of GlobComponentExplanations with examples."""
        parts = _COMPONENT_SPLIT_PATTERN.split(self._value)
        components = []

        for glob_part in parts:
            if not glob_part:
                continue

            component = GlobComponentExplanation(glob_expression=glob_part)

            if GROUPING_PATTERN.match(glob_part):
                examples = self.InterpolateGrouping(glob_part)
            elif _VAR_PATTERN.match(glob_part):
                # Examples for variable substitutions might not be 100 % accurate,
                # because the scope is not shared between two variables. Thus,
                # if a GlobExpression uses %%users.a%% and %%users.b%%, the underlying
                # user might be different for a and b. For the sake of explaining
                # possible values, this should still be enough.
                examples = artifact_utils.InterpolateKbAttributes(
                    glob_part, knowledge_base)
            else:
                examples = []

            component.examples = list(itertools.islice(examples,
                                                       example_count))
            components.append(component)

        return components
Beispiel #10
0
 def _ProcessRegistryValueSource(self, args):
   new_paths = set()
   has_glob = False
   for kvdict in args.base_source.attributes["key_value_pairs"]:
     if "*" in kvdict["key"] or rdf_paths.GROUPING_PATTERN.search(
         kvdict["key"]):
       has_glob = True
     if kvdict["value"]:
       path = "\\".join((kvdict["key"], kvdict["value"]))
     else:
       path = kvdict["key"]
     expanded_paths = artifact_utils.InterpolateKbAttributes(
         path,
         self.knowledge_base,
         ignore_errors=self.ignore_interpolation_errors)
     new_paths.update(expanded_paths)
   if has_glob:
     # TODO(user): If a path has a wildcard we need to glob the filesystem
     # for patterns to collect matching files. The corresponding flow is
     # filesystem.Glob.
     pass
   else:
     action = standard.GetFileStat
     for new_path in new_paths:
       pathspec = rdf_paths.PathSpec(
           path=new_path, pathtype=rdf_paths.PathSpec.PathType.REGISTRY)
       request = rdf_client.GetFileStatRequest(pathspec=pathspec)
       yield action, request
Beispiel #11
0
    def _InterpolatePaths(self, globs):
        client = aff4.FACTORY.Open(self.client_id, token=self.token)
        kb = client.Get(client.Schema.KNOWLEDGE_BASE)

        for glob in globs:
            param_path = glob.SerializeToString()
            for path in artifact_utils.InterpolateKbAttributes(param_path, kb):
                yield path
Beispiel #12
0
    def _InterpolatePaths(self, globs):

        kb = self.client_knowledge_base

        for glob in globs:
            param_path = str(glob)
            for path in artifact_utils.InterpolateKbAttributes(param_path, kb):
                yield path
Beispiel #13
0
    def testSimpleVariable(self):
        kb = rdf_client.KnowledgeBase()
        kb.environ_allusersprofile = "c:\\programdata"

        paths = artifact_utils.InterpolateKbAttributes(
            "%%environ_allusersprofile%%\\a", kb)

        self.assertEqual(list(paths), ["c:\\programdata\\a"])
Beispiel #14
0
  def testSingleUserHasValueOthersDoNot(self):
    kb = rdf_client.KnowledgeBase()
    kb.users.Append(rdf_client.User(username="******", uid=1, temp="C:\\Temp"))
    kb.users.Append(rdf_client.User(username="******", uid=2))
    kb.users.Append(rdf_client.User(username="******", uid=3))

    paths = artifact_utils.InterpolateKbAttributes(r"%%users.temp%%\abcd", kb)
    self.assertCountEqual(paths, ["C:\\Temp\\abcd"])
Beispiel #15
0
  def testMultipleUsersWithOneFullyApplicableValue(self):
    kb = rdf_client.KnowledgeBase()
    kb.users.Append(rdf_client.User(username="******", uid=1, temp="C:\\Temp"))
    kb.users.Append(rdf_client.User(username="******", uid=2))
    kb.users.Append(rdf_client.User(username="******", uid=3))

    paths = artifact_utils.InterpolateKbAttributes(
        "%%users.temp%%\\%%users.username%%.txt", kb)
    self.assertCountEqual(paths, ["C:\\Temp\\foo.txt"])
Beispiel #16
0
  def testMultipleUsersHaveValues(self):
    kb = rdf_client.KnowledgeBase()
    kb.users.Append(rdf_client.User(username="******", uid=1, sid="sid1"))
    kb.users.Append(rdf_client.User(username="******", uid=2, sid="sid2"))
    kb.Set("environ_allusersprofile", "c:\\programdata")

    paths = artifact_utils.InterpolateKbAttributes(
        "%%environ_allusersprofile%%\\%%users.sid%%\\%%users.username%%", kb)
    self.assertCountEqual(
        paths, ["c:\\programdata\\sid1\\joe", "c:\\programdata\\sid2\\jim"])
Beispiel #17
0
  def InterpolateList(self, input_list):
    """Interpolate all items from a given source array.

    Args:
      input_list: list of values to interpolate

    Returns:
      original list of values extended with strings interpolated
    """
    # We want to ignore errors either when it was explicitly requested by the
    # user or when the fallback mode is turned on (because one of the older
    # snapshot might successfully interpolate without errors).
    ignore_interpolation_errors = (
        self.args.ignore_interpolation_errors or
        self.args.old_client_snapshot_fallback)

    new_args = []
    for value in input_list:
      if isinstance(value, string_types):
        results = list(
            artifact_utils.InterpolateKbAttributes(
                value,
                self.state.knowledge_base,
                ignore_errors=ignore_interpolation_errors))

        if not results and self.args.old_client_snapshot_fallback:
          client_id = self.client_id
          snapshots = data_store.REL_DB.ReadClientSnapshotHistory(client_id)

          for snapshot in snapshots:
            results = list(
                artifact_utils.InterpolateKbAttributes(
                    value,
                    knowledge_base=snapshot.knowledge_base,
                    ignore_errors=True))

            if results:
              break

        new_args.extend(results)
      else:
        new_args.extend(value)
    return new_args
Beispiel #18
0
 def _Interpolate(self, pattern: Text) -> Sequence[Text]:
   try:
     return artifact_utils.InterpolateKbAttributes(pattern,
                                                   self.knowledge_base)
   except artifact_utils.KbInterpolationMissingAttributesError as error:
     if self.ignore_interpolation_errors:
       logging.error(str(error))
       return []
     else:
       raise
Beispiel #19
0
    def testMultipleUsers(self):
        kb = rdf_client.KnowledgeBase()
        kb.users.Append(rdf_client.User(username="******", uid=1))
        kb.users.Append(rdf_client.User(username="******", uid=2))

        paths = artifact_utils.InterpolateKbAttributes(
            "test%%users.username%%test", kb)
        paths = list(paths)
        self.assertLen(paths, 2)
        self.assertCountEqual(paths, ["testjoetest", "testjimtest"])
Beispiel #20
0
    def Interpolate(self, knowledge_base=None):
        kb = knowledge_base
        patterns = artifact_utils.InterpolateKbAttributes(self._value, kb)

        for pattern in patterns:
            # Normalize the component path (this allows us to resolve ../
            # sequences).
            pattern = utils.NormalizePath(pattern.replace("\\", "/"))

            for p in self.InterpolateGrouping(pattern):
                yield p
Beispiel #21
0
    def Interpolate(self, client=None):
        kb = client.Get(client.Schema.KNOWLEDGE_BASE)
        patterns = artifact_utils.InterpolateKbAttributes(self._value, kb)

        for pattern in patterns:
            # Normalize the component path (this allows us to resolve ../
            # sequences).
            pattern = utils.NormalizePath(pattern.replace("\\", "/"))

            for pattern in self.InterpolateGrouping(pattern):
                yield pattern
Beispiel #22
0
 def _GetSingleExpansion(self, value):
   results = list(
       artifact_utils.InterpolateKbAttributes(
           value,
           self.state.knowledge_base,
           ignore_errors=self.args.ignore_interpolation_errors))
   if len(results) > 1:
     raise ValueError(
         "Interpolation generated multiple results, use a"
         " list for multi-value expansions. %s yielded: %s" % (value, results))
   return results[0]
Beispiel #23
0
 def _ProcessWmiSource(self, args):
   # pylint: disable= g-import-not-at-top
   from grr_response_client.client_actions.windows import windows
   # pylint: enable=g-import-not-at-top
   action = windows.WmiQuery
   query = args.base_source.attributes["query"]
   queries = artifact_utils.InterpolateKbAttributes(
       query, self.knowledge_base, self.ignore_interpolation_errors)
   base_object = args.base_source.attributes.get("base_object")
   for query in queries:
     request = rdf_client.WMIRequest(query=query, base_object=base_object)
     yield action, request
Beispiel #24
0
    def testInterpolation(self):
        """Check we can interpolate values from the knowledge base."""
        kb = rdf_client.KnowledgeBase()

        # No users yet, this should raise
        self.assertRaises(
            artifact_utils.KnowledgeBaseInterpolationError, list,
            artifact_utils.InterpolateKbAttributes(
                "test%%users.username%%test", kb))

        # Now we have two users
        kb.users.Append(rdf_client.User(username="******", uid=1))
        kb.users.Append(rdf_client.User(username="******", uid=2))
        kb.Set("environ_allusersprofile", "c:\\programdata")

        paths = artifact_utils.InterpolateKbAttributes(
            "test%%users.username%%test", kb)
        paths = list(paths)
        self.assertLen(paths, 2)
        self.assertCountEqual(paths, ["testjoetest", "testjimtest"])

        paths = artifact_utils.InterpolateKbAttributes(
            "%%environ_allusersprofile%%\\a", kb)
        self.assertEqual(list(paths), ["c:\\programdata\\a"])

        # Check a bad attribute raises
        self.assertRaises(
            artifact_utils.KnowledgeBaseInterpolationError, list,
            artifact_utils.InterpolateKbAttributes("%%nonexistent%%\\a", kb))

        # Empty values should also raise
        kb.Set("environ_allusersprofile", "")
        self.assertRaises(
            artifact_utils.KnowledgeBaseInterpolationError, list,
            artifact_utils.InterpolateKbAttributes(
                "%%environ_allusersprofile%%\\a", kb))

        # No users have temp defined, so this should raise
        self.assertRaises(
            artifact_utils.KnowledgeBaseInterpolationError, list,
            artifact_utils.InterpolateKbAttributes("%%users.temp%%\\a", kb))

        # One user has users.temp defined, the others do not.  This is common on
        # windows where users have been created but have never logged in. We should
        # get just one value back.
        kb.users.Append(
            rdf_client.User(username="******",
                            uid=1,
                            temp="C:\\Users\\jason\\AppData\\Local\\Temp"))
        paths = artifact_utils.InterpolateKbAttributes(r"%%users.temp%%\abcd",
                                                       kb)
        self.assertCountEqual(paths,
                              ["C:\\Users\\jason\\AppData\\Local\\Temp\\abcd"])
Beispiel #25
0
  def testMultipleUserInterpolations(self):
    kb = rdf_client.KnowledgeBase()
    kb.users.Append(rdf_client.User(username="******", uid=1, sid="sid1"))
    kb.users.Append(rdf_client.User(username="******", uid=2, sid="sid2"))
    kb.Set("environ_allusersprofile", "c:\\programdata")

    paths = artifact_utils.InterpolateKbAttributes(
        "%%environ_allusersprofile%%\\%%users.sid%%\\%%users.username%%", kb)
    self.assertCountEqual(
        paths, ["c:\\programdata\\sid1\\joe", "c:\\programdata\\sid2\\jim"])

    # Only one user has a temp dir set. If we request all usernames and temp
    # dirs, we should only get one entry.
    kb.users.Append(
        rdf_client.User(
            username="******",
            uid=1,
            temp="C:\\Users\\jason\\AppData\\Local\\Temp"))

    paths = artifact_utils.InterpolateKbAttributes(
        "%%users.temp%%\\%%users.username%%.txt", kb)
    self.assertCountEqual(paths,
                          ["C:\\Users\\jason\\AppData\\Local\\Temp\\jason.txt"])
Beispiel #26
0
 def WMIQuery(self, source):
     """Run a Windows WMI Query."""
     query = source.attributes["query"]
     queries = artifact_utils.InterpolateKbAttributes(
         query,
         self.state.knowledge_base,
         ignore_errors=self.args.ignore_interpolation_errors)
     base_object = source.attributes.get("base_object")
     for query in queries:
         self.CallClient(server_stubs.WmiQuery,
                         query=query,
                         base_object=base_object,
                         request_data={
                             "artifact_name": self.current_artifact_name,
                             "source": source.ToPrimitiveDict()
                         },
                         next_state="ProcessCollected")
Beispiel #27
0
  def _ProcessFileSource(self, source):
    """Prepare a request for the client file finder."""

    if source.path_type != rdf_paths.PathSpec.PathType.OS:
      raise ValueError("Only supported path type is OS.")

    paths = []
    for path in source.base_source.attributes["paths"]:
      paths.extend(
          artifact_utils.InterpolateKbAttributes(
              path, self.knowledge_base, self.ignore_interpolation_errors))

    file_finder_action = rdf_file_finder.FileFinderAction.Stat()
    request = rdf_file_finder.FileFinderArgs(
        paths=paths, pathtype=source.path_type, action=file_finder_action)
    action = file_finder.FileFinderOSFromClient

    yield action, request
Beispiel #28
0
  def InterpolateList(self, input_list):
    """Interpolate all items from a given source array.

    Args:
      input_list: list of values to interpolate
    Returns:
      original list of values extended with strings interpolated
    """
    new_args = []
    for value in input_list:
      if isinstance(value, basestring):
        results = list(
            artifact_utils.InterpolateKbAttributes(
                value,
                self.state.knowledge_base,
                ignore_errors=self.args.ignore_interpolation_errors))
        new_args.extend(results)
      else:
        new_args.extend(value)
    return new_args
Beispiel #29
0
    def GetFiles(self, source, path_type, max_size):
        """Get a set of files."""
        new_path_list = []
        for path in source.attributes["paths"]:
            # Interpolate any attributes from the knowledgebase.
            new_path_list.extend(
                artifact_utils.InterpolateKbAttributes(
                    path,
                    self.state.knowledge_base,
                    ignore_errors=self.args.ignore_interpolation_errors))

        action = rdf_file_finder.FileFinderAction.Download(max_size=max_size)

        self.CallFlow(file_finder.FileFinder.__name__,
                      paths=new_path_list,
                      pathtype=path_type,
                      action=action,
                      request_data={
                          "artifact_name": self.current_artifact_name,
                          "source": source.ToPrimitiveDict()
                      },
                      next_state="ProcessFileFinderResults")