class Rex::Post::Meterpreter::Extensions::Stdapi::Fs::Dir

This class implements directory operations against the remote endpoint. It implements the Rex::Post::Dir interface.

Attributes

client[RW]
path[R]

The path of the directory that was opened.

Public Class Methods

chdir(path) click to toggle source

Changes the working directory of the remote process.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 119
def Dir.chdir(path)
  request = Packet.create_request('stdapi_fs_chdir')

  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))

  response = client.send_request(request)

  return 0
end
delete(path) click to toggle source

Removes the supplied directory if it's empty.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 163
def Dir.delete(path)
  request = Packet.create_request('stdapi_fs_delete_dir')

  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))

  response = client.send_request(request)

  return 0
end
download(dst, src, recursive = false, force = true, glob = nil, &stat) click to toggle source

Downloads the contents of a remote directory a local directory, optionally in a recursive fashion.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 197
def Dir.download(dst, src, recursive = false, force = true, glob = nil, &stat)

  self.entries(src, glob).each { |src_sub|
    dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)
    src_item = src + client.fs.file.separator + client.unicode_filter_encode(src_sub)

    if (src_sub == '.' or src_sub == '..')
      next
    end

    src_stat = client.fs.filestat.new(src_item)

    if (src_stat.file?)
      stat.call('downloading', src_item, dst_item) if (stat)
      begin
        result = client.fs.file.download_file(dst_item, src_item)
        stat.call(result, src_item, dst_item) if (stat)
      rescue ::Rex::Post::Meterpreter::RequestError => e
        if force
          stat.call('failed', src_item, dst_item) if (stat)
        else
          raise e
        end
      end

    elsif (src_stat.directory?)
      if (recursive == false)
        next
      end

      begin
        ::Dir.mkdir(dst_item)
      rescue
      end

      stat.call('mirroring', src_item, dst_item) if (stat)
      download(dst_item, src_item, recursive, force, glob, &stat)
      stat.call('mirrored', src_item, dst_item) if (stat)
    end
  }
end
entries(name = getwd, glob = nil) click to toggle source

Enumerates all of the files/folders in a given directory.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 54
def Dir.entries(name = getwd, glob = nil)
  request = Packet.create_request('stdapi_fs_ls')
  files   = []
  name = name + ::File::SEPARATOR + glob if glob

  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))

  response = client.send_request(request)

  response.each(TLV_TYPE_FILE_NAME) { |file_name|
    files << client.unicode_filter_encode(file_name.value)
  }

  return files
end
entries_with_info(name = getwd) click to toggle source

Enumerates files with a bit more information than the default entries.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 73
def Dir.entries_with_info(name = getwd)
  request = Packet.create_request('stdapi_fs_ls')
  files   = []

  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))

  response = client.send_request(request)

  fname = response.get_tlvs(TLV_TYPE_FILE_NAME)
  fsname = response.get_tlvs(TLV_TYPE_FILE_SHORT_NAME)
  fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
  sbuf  = response.get_tlvs(TLV_TYPE_STAT_BUF)

  if (!fname or !sbuf)
    return []
  end

  fname.each_with_index { |file_name, idx|
    st = nil

    if (sbuf[idx])
      st = ::Rex::Post::FileStat.new
      st.update(sbuf[idx].value)
    end

    files <<
      {
        'FileName' => client.unicode_filter_encode(file_name.value),
        'FilePath' => client.unicode_filter_encode(fpath[idx].value),
        'FileShortName' => fsname[idx] ? fsname[idx].value : nil,
        'StatBuf'  => st,
      }
  }

  return files
end
getwd() click to toggle source

Synonym for pwd.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 156
def Dir.getwd
  pwd
end
mkdir(path) click to toggle source

Creates a directory.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 132
def Dir.mkdir(path)
  request = Packet.create_request('stdapi_fs_mkdir')

  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))

  response = client.send_request(request)

  return 0
end
new(path) click to toggle source

Initializes the directory instance.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 33
def initialize(path)
  self.path   = path
  self.client = self.class.client
end
pwd() click to toggle source

Returns the current working directory of the remote process.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 145
def Dir.pwd
  request = Packet.create_request('stdapi_fs_getwd')

  response = client.send_request(request)

  return client.unicode_filter_encode(response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value)
end
rmdir(path) click to toggle source

Synonyms for delete.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 176
def Dir.rmdir(path)
  delete(path)
end
upload(dst, src, recursive = false, &stat) click to toggle source

Uploads the contents of a local directory to a remote directory, optionally in a recursive fashion.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 243
def Dir.upload(dst, src, recursive = false, &stat)
  ::Dir.entries(src).each { |src_sub|
    dst_item = dst + client.fs.file.separator + client.unicode_filter_encode(src_sub)
    src_item = src + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)

    if (src_sub == '.' or src_sub == '..')
      next
    end

    src_stat = ::File.stat(src_item)

    if (src_stat.file?)
      stat.call('uploading', src_item, dst_item) if (stat)
      client.fs.file.upload(dst_item, src_item)
      stat.call('uploaded', src_item, dst_item) if (stat)
    elsif (src_stat.directory?)
      if (recursive == false)
        next
      end

      begin
        self.mkdir(dst_item)
      rescue
      end

      stat.call('mirroring', src_item, dst_item) if (stat)
      upload(dst_item, src_item, recursive, &stat)
      stat.call('mirrored', src_item, dst_item) if (stat)
    end
  }
end

Public Instance Methods

each(&block) click to toggle source

Enumerates all of the contents of the directory.

# File lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb, line 47
def each(&block)
  client.fs.dir.foreach(self.path, &block)
end