def testInterpolation(self): """Check we can interpolate values from the knowledge base.""" kb = rdfvalue.KnowledgeBase() self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes("test%%users.username%%test", kb)) kb.users.Append(rdfvalue.KnowledgeBaseUser(username="******", uid=1)) kb.users.Append(rdfvalue.KnowledgeBaseUser(username="******", uid=2)) kb.Set("environ_allusersprofile", "c:\\programdata") paths = artifact_lib.InterpolateKbAttributes( "test%%users.username%%test", kb) paths = list(paths) self.assertEqual(len(paths), 2) self.assertItemsEqual(paths, ["testjoetest", "testjimtest"]) paths = artifact_lib.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb) self.assertEqual(list(paths), ["c:\\programdata\\a"]) self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes("%%nonexistent%%\\a", kb)) kb.Set("environ_allusersprofile", "") self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb))
def _GetSingleExpansion(self, value): results = list(artifact_lib.InterpolateKbAttributes( value, self.state.knowledge_base)) 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]
def WMIQuery(self, collector): """Run a Windows WMI Query.""" query = collector.args["query"] queries = artifact_lib.InterpolateKbAttributes(query, self.state.knowledge_base) for query in queries: self.CallClient( "WmiQuery", query=query, request_data={"artifact_name": self.current_artifact_name, "collector": collector.ToPrimitiveDict()}, next_state="ProcessCollected" )
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_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes("test%%users.username%%test", kb)) # Now we have two users kb.users.Append(rdf_client.KnowledgeBaseUser(username="******", uid=1)) kb.users.Append(rdf_client.KnowledgeBaseUser(username="******", uid=2)) kb.Set("environ_allusersprofile", "c:\\programdata") paths = artifact_lib.InterpolateKbAttributes( "test%%users.username%%test", kb) paths = list(paths) self.assertEqual(len(paths), 2) self.assertItemsEqual(paths, ["testjoetest", "testjimtest"]) paths = artifact_lib.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb) self.assertEqual(list(paths), ["c:\\programdata\\a"]) # Check a bad attribute raises self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes("%%nonexistent%%\\a", kb)) # Empty values should also raise kb.Set("environ_allusersprofile", "") self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb)) # No users have temp defined, so this should raise self.assertRaises( artifact_lib.KnowledgeBaseInterpolationError, list, artifact_lib.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.KnowledgeBaseUser( username="******", uid=1, temp="C:\\Users\\jason\\AppData\\Local\\Temp")) paths = artifact_lib.InterpolateKbAttributes(r"%%users.temp%%\abcd", kb) self.assertItemsEqual(paths, ["C:\\Users\\jason\\AppData\\Local\\Temp\\abcd"])
def WMIQuery(self, source): """Run a Windows WMI Query.""" query = source.attributes["query"] queries = artifact_lib.InterpolateKbAttributes( query, self.state.knowledge_base) base_object = source.attributes.get("base_object") for query in queries: self.CallClient("WmiQuery", query=query, base_object=base_object, request_data={ "artifact_name": self.current_artifact_name, "source": source.ToPrimitiveDict() }, next_state="ProcessCollected")
def InterpolateList(self, input_list): """Interpolate all items from a given collector 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_lib.InterpolateKbAttributes( value, self.state.knowledge_base)) new_args.extend(results) else: new_args.extend(value) return new_args
def GetRegistryValue(self, collector): """Retrieve directly specified registry values, returning Stat objects.""" new_paths = set() for path in collector.args["path_list"]: expanded_paths = artifact_lib.InterpolateKbAttributes( path, self.state.knowledge_base) new_paths.update(expanded_paths) for new_path in new_paths: pathspec = rdfvalue.PathSpec(path=new_path, pathtype=rdfvalue.PathSpec.PathType.REGISTRY) self.CallClient( "StatFile", pathspec=pathspec, request_data={"artifact_name": self.current_artifact_name, "collector": collector.ToPrimitiveDict()}, next_state="ProcessCollected" )
def GetFiles(self, collector, path_type, max_size): """Get a set of files.""" new_path_list = [] for path in collector.args["path_list"]: # Interpolate any attributes from the knowledgebase. new_path_list.extend(artifact_lib.InterpolateKbAttributes( path, self.state.knowledge_base)) action = rdfvalue.FileFinderAction( action_type=rdfvalue.FileFinderAction.Action.DOWNLOAD, download=rdfvalue.FileFinderDownloadActionOptions(max_size=max_size)) self.CallFlow( "FileFinder", paths=new_path_list, pathtype=path_type, action=action, request_data={"artifact_name": self.current_artifact_name, "collector": collector.ToPrimitiveDict()}, next_state="ProcessFileFinderResults")
def GetFiles(self, collector, path_type): """Get a set of files.""" if collector.action == "GetFile": path_list = [collector.args["path"]] elif collector.action == "GetFiles": path_list = collector.args["path_list"] new_path_list = [] for path in path_list: # Interpolate any attributes from the knowledgebase. new_path_list.extend( artifact_lib.InterpolateKbAttributes( path, self.state.knowledge_base)) self.CallFlow("FetchFiles", paths=new_path_list, pathtype=path_type, request_data={ "artifact_name": self.current_artifact_name, "collector": collector.ToPrimitiveDict() }, next_state="ProcessCollected")
def GetRegistryValue(self, source): """Retrieve directly specified registry values, returning Stat objects.""" new_paths = set() for kvdict in source.attributes["key_value_pairs"]: # TODO(user): this needs to be improved to support globbing for both # key and value, and possibly also support forward slash. path = "\\".join((kvdict["key"], kvdict["value"])) expanded_paths = artifact_lib.InterpolateKbAttributes( path, self.state.knowledge_base) new_paths.update(expanded_paths) for new_path in new_paths: pathspec = paths.PathSpec( path=new_path, pathtype=paths.PathSpec.PathType.REGISTRY) self.CallClient("StatFile", pathspec=pathspec, request_data={ "artifact_name": self.current_artifact_name, "source": source.ToPrimitiveDict() }, next_state="ProcessCollected")
def Interpolate(self, client=None): try: kb = client.Get(client.Schema.KNOWLEDGE_BASE) if not kb: raise artifact_lib.KnowledgeBaseInterpolationError( "Client has no knowledge base") patterns = artifact_lib.InterpolateKbAttributes(self._value, kb) except artifact_lib.KnowledgeBaseInterpolationError: # TODO(user): Deprecate InterpolateClientAttributes() support and # make KnowledgeBase the default and only option as soon as we're # confident that it's fully populated. logging.debug( "Can't interpolate glob %s with knowledge base attributes, " "reverting to client attributes.", utils.SmartUnicode(self)) patterns = self.InterpolateClientAttributes(client=client) 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