예제 #1
0
    def render(self, renderer):
        if self.plugin_args.converter:
            cls = ProfileConverter.classes.get(self.plugin_args.converter)
            if not cls:
                raise IOError("Unknown converter %s" %
                              self.plugin_args.converter)

            return cls(self.plugin_args.source,
                       profile_class=self.plugin_args.profile_class).Convert()

        try:
            input = io_manager.Factory(self.plugin_args.source,
                                       session=self.session,
                                       mode="r")
        except IOError:
            self.session.logging.critical(
                "Input profile file %s could not be opened.",
                self.plugin_args.source)
            return

        with input:
            profile = self.ConvertProfile(input)
            if profile:
                with renderer.open(filename=self.plugin_args.out_file,
                                   mode="wt") as output:
                    output.write(utils.PPrint(profile))
                    self.session.logging.info("Converted %s to %s", input,
                                              output.name)
예제 #2
0
    def Build(self, renderer):
        """Linux profile location"""
        convert_profile = self.session.plugins.convert_profile(
            session=self.session, source="/dev/null",
            out_file="dummy file")  # We don't really output the profile.

        changed_files = False
        total_profiles = 0
        new_profiles = 0

        for source_profile in self.args.repository.ListFiles():
            # Find all source profiles.
            if (source_profile.startswith("src/Linux")
                    and source_profile.endswith(".zip")):

                total_profiles += 1
                profile_id = source_profile.lstrip("src/").rstrip(".zip")

                # Skip already built profiles.
                if self.args.repository.Metadata(profile_id):
                    continue

                # Convert the profile
                self.session.report_progress(
                    "Found new raw Linux profile %s. Converting...",
                    profile_id)
                self.session.logging.info("Found new raw Linux profile %s",
                                          profile_id)

                profile_fullpath = self.args.repository.GetAbsolutePathName(
                    source_profile)
                profile = convert_profile.ConvertProfile(
                    io_manager.Factory(profile_fullpath,
                                       session=self.session,
                                       mode="r"))
                if not profile:
                    self.session.logging.info(
                        "Skipped %s, Unable to convert to a Rekall profile.",
                        profile_fullpath)
                    continue

                # Add profile to the repository and the inventory
                self.args.repository.StoreData(profile_id, profile)
                new_profiles += 1
                changed_files = True

        self.session.logging.info("Found %d profiles. %d are new.",
                                  total_profiles, new_profiles)

        # Now rebuild the index
        if changed_files and self.args.index or self.args.force_build_index:
            self.BuildIndex()
예제 #3
0
    def repository_managers(self):
        """The IO managers that are used to fetch profiles from the profile
        repository.

        """
        if self._repository_managers:
            return self._repository_managers

        # The profile path is specified in search order.
        repository_path = (self.state.Get("repository_path")
                           or self.state.Get("profile_path") or [])

        for path in repository_path:
            self._repository_managers.append(
                (path, io_manager.Factory(path, session=self)))

        return self._repository_managers
예제 #4
0
    def repository_managers(self):
        """The IO managers that are used to fetch profiles from the profile
        repository.

        """
        if self._repository_managers:
            return self._repository_managers

        # The profile path is specified in search order.
        repository_path = (self.GetParameter("repository_path")
                           or self.GetParameter("profile_path") or [])

        for path in repository_path:
            # TODO(scudette): remove this hack for 1.6 release.  Github has
            # changed their static URL access. If the user is using an old URL
            # we warn and correct it.
            if path in constants.OLD_DEPRECATED_URLS:
                self.logging.warn(
                    "Rekall's profile repository is pointing to deprecated URL "
                    "(%s). Please update your ~/.rekallrc file.", path)
                path = constants.PROFILE_REPOSITORIES[0]

            try:
                self._repository_managers.append(
                    (path, io_manager.Factory(path, session=self)))
            except ValueError:
                pass

        if not self._repository_managers:
            try:
                self.logging.warn(
                    "No usable repositories were found. "
                    "Rekall Will attempt to use the local cache. "
                    "This is likely to fail if profiles are missing locally!")
                self._repository_managers = [
                    (None,
                     io_manager.DirectoryIOManager(urn=cache.GetCacheDir(self),
                                                   session=self))
                ]
            except IOError:
                self._repository_managers = []

        return self._repository_managers
예제 #5
0
    def render(self, renderer):
        if self.converter:
            cls = ProfileConverter.classes.get(self.converter)
            if not cls:
                raise IOError("Unknown converter %s" % self.converter)

            return cls(self.source,
                       self.output,
                       profile_class=self.profile_class).Convert()

        try:
            input = io_manager.Factory(self.source, mode="r")
        except IOError:
            logging.critical("Input profile file %s could not be opened.",
                             self.source)
            return

        with input, self.output:
            self.ConvertProfile(input, self.output)
예제 #6
0
파일: core.py 프로젝트: imclab/rekall
    def render_profile_info(self, renderer):
        for path in self.session.state.profile_path:
            manager = io_manager.Factory(path)
            renderer.section()
            renderer.format("Profile Repository {0}\n\n", path)
            renderer.table_header([('Profile', 'profile', "40"),
                                   ('Docs', 'docs', '[wrap:70]'),
                                   ])

            try:
                # If the repository contains a proper metadata list we show it.
                repository_metadata = manager.GetData("metadata")
                if repository_metadata:
                    for name, profile_metadata in sorted(
                        repository_metadata.get("inventory", {}).items()):

                        renderer.table_row(
                            name, profile_metadata.get("description", ""))
            except IOError:
                # Otherwise we just list the files in the repository.
                for name in sorted(manager.ListFiles()):
                    renderer.table_row(name)
예제 #7
0
    def LoadProfile(self, filename, use_cache=True):
        """Try to load a profile directly from a filename.

        Args:
          filename: A string which will be used to get an io_manager
            container. If it contains a path sepearator we open the file
            directly, otherwise we search in the profile_path specification.

        Returns:
          a Profile() instance or a NoneObject()
        """
        if not filename:
            return

        if isinstance(filename, obj.Profile):
            return filename

        # We only want to deal with unix paths.
        filename = filename.replace("\\", "/")
        canonical_name = os.path.splitext(filename)[0]

        try:
            if use_cache:
                cached_profile = self.profile_cache[canonical_name]
                if cached_profile:
                    return cached_profile.copy()
                else:
                    raise ValueError(
                        "Unable to load profile %s from any repository." %
                        filename)

        except KeyError:
            pass

        # If the filename is a path we try to open it directly:
        if os.access(filename, os.R_OK):
            container = io_manager.Factory(os.path.dirname(filename))
            result = obj.Profile.LoadProfileFromData(container.GetData(
                os.path.basename(filename)),
                                                     self,
                                                     name=canonical_name)

        # Traverse the profile path until one works.
        else:
            result = None

            # The profile path is specified in search order.
            profile_path = self.state.Get("profile_path") or []

            # Add the last supported repository as the last fallback path.
            for path in profile_path:
                path = "%s/%s" % (path, constants.PROFILE_REPOSITORY_VERSION)
                try:
                    manager = io_manager.Factory(path)
                    try:
                        # The inventory allows us to fail fetching the profile
                        # quickly - without making the round trip.
                        if path not in self.inventories:
                            # Fetch the profile inventory.
                            self.inventories[path] = manager.GetData(
                                "inventory")

                        inventory = self.inventories[path]["$INVENTORY"]
                        if (filename not in inventory
                                and filename + ".gz" not in inventory):
                            continue

                    # No inventory in that repository - just try anyway.
                    except IOError:
                        pass

                    result = obj.Profile.LoadProfileFromData(
                        manager.GetData(filename), self, name=canonical_name)
                    logging.info("Loaded profile %s from %s", filename,
                                 manager)

                    break

                except (IOError, KeyError) as e:
                    result = obj.NoneObject(e)
                    logging.debug("Could not find profile %s in %s", filename,
                                  path)

                    continue

        # Cache it for later. Note that this also caches failures so we do not
        # retry again.
        self.profile_cache[canonical_name] = result
        if result == None:
            raise ValueError("Unable to load profile %s from any repository." %
                             filename)

        return result
예제 #8
0
    def LoadProfile(self, name, use_cache=True):
        """Try to load a profile directly by its name.

        Args:

          name: A string which represents the canonical name for the profile. We
              ask all repositories in the repository_path to resolve this name
              into a profile.

        Returns:
          a Profile() instance or a NoneObject()

        """
        if not name:
            return obj.NoneObject("No filename")

        if isinstance(name, obj.Profile):
            return name

        # We only want to deal with unix paths.
        name = name.replace("\\", "/")

        try:
            if use_cache:
                cached_profile = self.profile_cache[name]
                if cached_profile:
                    return cached_profile

                else:
                    return obj.NoneObject(
                        "Unable to load profile %s from any repository." %
                        name)

        except KeyError:
            pass

        result = None

        try:
            # If the name is a path we try to open it directly:
            container = io_manager.DirectoryIOManager(os.path.dirname(name),
                                                      version=None)
            result = obj.Profile.LoadProfileFromData(container.GetData(
                os.path.basename(name)),
                                                     self,
                                                     name=name)
        except IOError:
            pass

        # Traverse the profile path until one works.
        if not result:
            # The profile path is specified in search order.
            repository_path = (self.state.Get("repository_path")
                               or self.state.Get("profile_path") or [])

            # Add the last supported repository as the last fallback path.
            for path in repository_path:
                try:
                    if path not in self.repository_managers:
                        self.repository_managers[path] = io_manager.Factory(
                            path, session=self)

                    manager = self.repository_managers[path]

                    # The inventory allows us to fail fetching the profile
                    # quickly - without making the round trip.
                    if not manager.CheckInventory(name):
                        logging.debug(
                            "Skipped profile %s from %s (Not in inventory)",
                            name, path)
                        continue

                    result = obj.Profile.LoadProfileFromData(
                        manager.GetData(name), self, name=name)
                    logging.info("Loaded profile %s from %s", name, manager)

                    break

                except (IOError, KeyError) as e:
                    result = obj.NoneObject(e)
                    logging.debug("Could not find profile %s in %s: %s", name,
                                  path, e)

                    continue

        # Cache it for later. Note that this also caches failures so we do not
        # retry again.
        self.profile_cache[name] = result
        if result == None:
            return obj.NoneObject(
                "Unable to load profile %s from any repository." % name)

        return result
예제 #9
0
    def LoadProfile(self, filename, use_cache=True):
        """Try to load a profile directly from a filename.

        Args:
          filename: A string which will be used to get an io_manager
            container. If it contains a path sepearator we open the file
            directly, otherwise we search in the profile_path specification.

        Returns:
          a Profile() instance or a NoneObject()
        """
        if not filename:
            return

        if isinstance(filename, obj.Profile):
            return filename

        # We only want to deal with unix paths.
        filename = filename.replace("\\", "/")

        # Only strip the extension if it is one of the recognized
        # extensions. Otherwise ignore it - this allows the profile name to have
        # . characters in it (e.g. Linux-3.1.13).
        canonical_name, extension = os.path.splitext(filename)
        if extension not in [".gz", ".json"]:
            canonical_name = filename

        try:
            if use_cache:
                cached_profile = self.profile_cache[canonical_name]
                if cached_profile:
                    return cached_profile

                else:
                    return obj.NoneObject(
                        "Unable to load profile %s from any repository." %
                        filename)

        except KeyError:
            pass

        # If the filename is a path we try to open it directly:
        if os.access(filename, os.R_OK):
            container = io_manager.Factory(os.path.dirname(filename))
            result = obj.Profile.LoadProfileFromData(
                container.GetData(os.path.basename(filename)),
                self, name=canonical_name)

        # Traverse the profile path until one works.
        else:
            result = None

            # The profile path is specified in search order.
            profile_path = self.state.Get("profile_path") or []

            # Add the last supported repository as the last fallback path.
            for path in profile_path:
                path = "%s/%s" % (path, constants.PROFILE_REPOSITORY_VERSION)

                # For now, print a warning when the user has an out of date
                # config file. TODO: Remove this in a future version.
                if "profiles.rekall.googlecode.com" in path:
                    logging.warn(
                        "Rekall profiles have moved to %s, but your .rekallrc "
                        "file still points to %s. You should update your "
                        "config file.",
                        constants.PROFILE_REPOSITORIES[0],
                        path)

                try:
                    manager = io_manager.Factory(path)
                    try:
                        # The inventory allows us to fail fetching the profile
                        # quickly - without making the round trip.
                        if path not in self.inventories:
                            # Fetch the profile inventory.
                            self.inventories[path] = manager.GetData(
                                "inventory")

                        inventory = self.inventories[path]["$INVENTORY"]
                        if (filename not in inventory and
                            filename + ".gz" not in inventory):
                            logging.debug(
                                "Skipped profile %s from %s (Not in inventory)",
                                filename, path)
                            continue

                    # No inventory in that repository - just try anyway.
                    except IOError:
                        pass

                    result = obj.Profile.LoadProfileFromData(
                        manager.GetData(filename), self,
                        name=canonical_name)
                    logging.info(
                        "Loaded profile %s from %s", filename, manager)

                    break

                except (IOError, KeyError) as e:
                    result = obj.NoneObject(e)
                    logging.debug("Could not find profile %s in %s",
                                  filename, path)

                    continue

        # Cache it for later. Note that this also caches failures so we do not
        # retry again.
        self.profile_cache[canonical_name] = result
        if result == None:
            return obj.NoneObject(
                "Unable to load profile %s from any repository." % filename)

        return result