Example #1
0
  def ParseFile(
      self,
      knowledge_base: rdf_client.KnowledgeBase,
      pathspec: rdf_paths.PathSpec,
      filedesc: IO[bytes],
  ) -> Iterator[rdf_webhistory.BrowserHistoryItem]:
    del knowledge_base  # Unused.

    # TODO(user): Convert this to use the far more intelligent plaso parser.
    chrome = ChromeParser()
    path = pathspec.CollapsePath()
    for timestamp, entry_type, url, data1, _, _ in chrome.Parse(path, filedesc):
      if entry_type == "CHROME_DOWNLOAD":
        yield rdf_webhistory.BrowserHistoryItem(
            url=url,
            domain=urlparse.urlparse(url).netloc,
            access_time=timestamp,
            program_name="Chrome",
            source_path=pathspec.CollapsePath(),
            download_path=data1)
      elif entry_type == "CHROME_VISIT":
        yield rdf_webhistory.BrowserHistoryItem(
            url=url,
            domain=urlparse.urlparse(url).netloc,
            access_time=timestamp,
            program_name="Chrome",
            source_path=pathspec.CollapsePath(),
            title=data1)
Example #2
0
    def _OpenPathSpec(self, pathspec: rdf_paths.PathSpec) -> client.File:
        if pathspec.HasField("stream_name"):
            stream_name = pathspec.stream_name
        else:
            stream_name = None

        if pathspec.HasField("inode"):
            return self.client.OpenByInode(pathspec.inode, stream_name)
        else:
            path = self._ToClientPath(pathspec.last.path)
            return self.client.Open(path, stream_name)
Example #3
0
    def Open(
        cls,
        fd: Optional[vfs_base.VFSHandler],
        component: rdf_paths.PathSpec,
        handlers: Dict[Any, Type[vfs_base.VFSHandler]],
        pathspec: Optional[rdf_paths.PathSpec] = None,
        progress_callback: Optional[Callable[[], None]] = None
    ) -> Optional[vfs_base.VFSHandler]:
        # A Pathspec which starts with NTFS means we need to resolve the mount
        # point at runtime.
        if (fd is None
                and component.pathtype == rdf_paths.PathSpec.PathType.NTFS
                and pathspec is not None):
            # We are the top level handler. This means we need to check the system
            # mounts to work out the exact mount point and device we need to
            # open. We then modify the pathspec so we get nested in the raw
            # pathspec.
            raw_pathspec, corrected_path = client_utils.GetRawDevice(
                component.path)

            # Insert the raw device before the component in the pathspec and correct
            # the path
            component.path = corrected_path
            pathspec.Insert(0, component)
            pathspec.Insert(0, raw_pathspec)

            # Allow incoming pathspec to be given in the local system path
            # conventions.
            for component in pathspec:
                if component.path:
                    component.path = client_utils.LocalPathToCanonicalPath(
                        component.path)

            # We have not actually opened anything in this iteration, but modified the
            # pathspec. Next time we should be able to open it properly.
            return fd

        # If an inode is specified, just use it directly.
        # This is necessary so that component.path is ignored.
        elif component.HasField("inode"):
            return NTFSFile(fd,
                            handlers,
                            component,
                            progress_callback=progress_callback)
        else:
            return super(NTFSFile,
                         cls).Open(fd=fd,
                                   component=component,
                                   handlers=handlers,
                                   pathspec=pathspec,
                                   progress_callback=progress_callback)
Example #4
0
    def _OpenStreamCaseInsensitive(
            self, pathspec: rdf_paths.PathSpec) -> Tuple[client.File, str]:
        """Opens a stream by pathspec with a case-insensitvie stream name.

    Args:
      pathspec: Pathspec for stream.

    Returns:
      A tuple: the opened file, the case sensitive stream name.
    """
        stream_name = pathspec.stream_name
        file_pathspec = pathspec.Copy()
        file_pathspec.stream_name = None
        result = pathspec.Copy()
        result.stream_name = self._GetStreamNameCaseLiteral(
            file_pathspec, stream_name)
        return self._OpenPathSpec(result), result.stream_name
Example #5
0
 def _CheckHasImplementationType(
         self, pathspec: rdf_paths.PathSpec,
         implementation_type: rdf_paths.PathSpec.ImplementationType
 ) -> None:
     if implementation_type is None:
         self.assertFalse(pathspec.HasField("implementation_type"))
     else:
         self.assertEqual(pathspec.implementation_type, implementation_type)
     for i, component in enumerate(pathspec):
         if i > 0:
             self.assertFalse(component.HasField("implementation_type"))
Example #6
0
    def ParseFile(
        self,
        knowledge_base: rdf_client.KnowledgeBase,
        pathspec: rdf_paths.PathSpec,
        filedesc: IO[bytes],
    ) -> Iterator[rdf_webhistory.BrowserHistoryItem]:
        del knowledge_base  # Unused.

        # TODO(user): Convert this to use the far more intelligent plaso parser.
        ie = IEParser(filedesc)
        for dat in ie.Parse():
            yield rdf_webhistory.BrowserHistoryItem(
                url=dat["url"],
                domain=urlparse.urlparse(dat["url"]).netloc,
                access_time=dat.get("mtime"),
                program_name="Internet Explorer",
                source_path=pathspec.CollapsePath())
Example #7
0
    def ParseFile(
        self,
        knowledge_base: rdf_client.KnowledgeBase,
        pathspec: rdf_paths.PathSpec,
        filedesc: IO[bytes],
    ) -> Iterator[rdf_webhistory.BrowserHistoryItem]:
        del knowledge_base  # Unused.

        # TODO(user): Convert this to use the far more intelligent plaso parser.
        ff = Firefox3History()
        for timestamp, unused_entry_type, url, title in ff.Parse(filedesc):
            yield rdf_webhistory.BrowserHistoryItem(
                url=url,
                domain=urlparse.urlparse(url).netloc,
                access_time=timestamp,
                program_name="Firefox",
                source_path=pathspec.CollapsePath(),
                title=title)
Example #8
0
def _ConvertStatEntry(entry: filesystem_pb2.StatEntry,
                      pathspec: rdf_paths.PathSpec) -> rdf_client_fs.StatEntry:
    """Converts a stat entry from a filesystem_pb2 protobuf to RDF."""
    st = rdf_client_fs.StatEntry()
    st.pathspec = pathspec.Copy()

    if entry.HasField("st_mode"):
        st.st_mode = entry.st_mode
    # TODO: Expose st_ino as well.
    # It's not exposed at the moment for compatibility with
    # vfs_handlers/ntfs.py, which doesn't expose it.
    if entry.HasField("st_dev"):
        st.st_dev = entry.st_dev
    if entry.HasField("st_nlink"):
        st.st_nlink = entry.st_nlink
    if entry.HasField("st_uid"):
        st.st_uid = entry.st_uid
    if entry.HasField("st_gid"):
        st.st_gid = entry.st_gid
    if entry.HasField("st_size"):
        st.st_size = entry.st_size

    st.st_atime = rdfvalue.RDFDatetimeSeconds(entry.st_atime.seconds)
    st.st_mtime = rdfvalue.RDFDatetimeSeconds(entry.st_mtime.seconds)
    st.st_btime = rdfvalue.RDFDatetimeSeconds(entry.st_btime.seconds)
    st.st_ctime = rdfvalue.RDFDatetimeSeconds(entry.st_ctime.seconds)

    if entry.HasField("ntfs"):
        if entry.ntfs.is_directory:
            st.st_mode |= stat.S_IFDIR
        else:
            st.st_mode |= stat.S_IFREG

        flags = entry.ntfs.flags
        st.st_mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
        if (flags & stat.FILE_ATTRIBUTE_READONLY) == 0:
            st.st_mode |= stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
        if (flags & stat.FILE_ATTRIBUTE_HIDDEN) == 0:
            st.st_mode |= stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH

    return st
Example #9
0
 def _PathSpecForClient(self,
                        pathspec: rdf_paths.PathSpec) -> rdf_paths.PathSpec:
     if self.state.implementation_type:
         pathspec = pathspec.Copy()
         pathspec.implementation_type = self.state.implementation_type
     return pathspec
Example #10
0
File: vfs.py Project: swipswaps/grr
def VFSOpen(
        pathspec: rdf_paths.PathSpec,
        progress_callback: Optional[Callable[[], None]] = None) -> VFSHandler:
    """Expands pathspec to return an expanded Path.

  A pathspec is a specification of how to access the file by recursively opening
  each part of the path by different drivers. For example the following
  pathspec:

  pathtype: OS
  path: "/dev/sda1"
  nested_path {
    pathtype: TSK
    path: "/home/image2.img"
    nested_path {
      pathtype: TSK
      path: "/home/a.txt"
    }
  }

  Instructs the system to:
  1) open /dev/sda1 using the OS driver.
  2) Pass the obtained filelike object to the TSK driver to open
  "/home/image2.img".
  3) The obtained filelike object should be passed to the TSK driver to open
  "/home/a.txt".

  The problem remains how to get to this expanded path specification. Since the
  server is not aware of all the files on the client, the server may request
  this:

  pathtype: OS
  path: "/dev/sda1"
  nested_path {
    pathtype: TSK
    path: "/home/image2.img/home/a.txt"
  }

  Or even this:

  pathtype: OS
  path: "/dev/sda1/home/image2.img/home/a.txt"

  This function converts the pathspec requested by the server into an expanded
  pathspec required to actually open the file. This is done by expanding each
  component of the pathspec in turn.

  Expanding the component is done by opening each leading directory in turn and
  checking if it is a directory of a file. If its a file, we examine the file
  headers to determine the next appropriate driver to use, and create a nested
  pathspec.

  Note that for some clients there might be a virtual root specified. This
  is a directory that gets prepended to all pathspecs of a given
  pathtype. For example if there is a virtual root defined as
  ["os:/virtualroot"], a path specification like

  pathtype: OS
  path: "/home/user/*"

  will get translated into

  pathtype: OS
  path: "/virtualroot"
  is_virtualroot: True
  nested_path {
    pathtype: OS
    path: "/dev/sda1"
  }

  Args:
    pathspec: A Path() protobuf to normalize.
    progress_callback: A callback to indicate that the open call is still
      working but needs more time.

  Returns:
    The open filelike object. This will contain the expanded Path() protobuf as
    the member fd.pathspec.

  Raises:
    IOError: if one of the path components can not be opened.

  """
    # Initialize the dictionary of VFS handlers lazily, if not yet done.
    if not VFS_HANDLERS:
        Init()

    fd = None

    # Adjust the pathspec in case we are using a vfs_virtualroot.
    vroot = _VFS_VIRTUALROOTS.get(pathspec.pathtype)

    # If we have a virtual root for this vfs handler, we need to prepend
    # it to the incoming pathspec except if the pathspec is explicitly
    # marked as containing a virtual root already or if it isn't marked but
    # the path already contains the virtual root.
    if (not vroot or pathspec.is_virtualroot
            or pathspec.CollapsePath().startswith(vroot.CollapsePath())):
        # No virtual root but opening changes the pathspec so we always work on a
        # copy.
        working_pathspec = pathspec.Copy()
    else:
        # We're in a virtual root, put the target pathspec inside the virtual root
        # as a nested path.
        working_pathspec = vroot.Copy()
        working_pathspec.last.nested_path = pathspec.Copy()

    # For each pathspec step, we get the handler for it and instantiate it with
    # the old object, and the current step.
    while working_pathspec:
        component = working_pathspec.Pop()
        try:
            handler = VFS_HANDLERS[component.pathtype]
        except KeyError:
            raise UnsupportedHandlerError(component.pathtype)

        # Open the component.
        fd = handler.Open(fd=fd,
                          component=component,
                          handlers=dict(VFS_HANDLERS),
                          pathspec=working_pathspec,
                          progress_callback=progress_callback)

    if fd is None:
        raise ValueError("VFSOpen cannot be called with empty PathSpec.")

    return fd