class Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Stdapi::Fs

The file system portion of the standard API extension.

Constants

Klass

Public Instance Methods

cmd_cat(*args) click to toggle source

Reads the contents of a file and prints them to the screen.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 155
def cmd_cat(*args)
  if (args.length == 0)
    print_line("Usage: cat file")
    return true
  end

  if (client.fs.file.stat(args[0]).directory?)
    print_error("#{args[0]} is a directory")
  else
    fd = client.fs.file.new(args[0], "rb")
    begin
      until fd.eof?
        print(fd.read)
      end
    # EOFError is raised if file is empty, do nothing, just catch
    rescue EOFError
    end
    fd.close
  end

  true
end
cmd_cd(*args) click to toggle source

Change the working directory.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 181
def cmd_cd(*args)
  if (args.length == 0)
    print_line("Usage: cd directory")
    return true
  end
  if args[0] =~ /\%(\w*)\%/
    client.fs.dir.chdir(client.fs.file.expand_path(args[0].upcase))
  else
    client.fs.dir.chdir(args[0])
  end

  return true
end
cmd_del(*args)
Alias for: cmd_rm
cmd_download(*args) click to toggle source

Downloads a file or directory from the remote machine to the local machine.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 254
def cmd_download(*args)
  if (args.empty? or args.include? "-h")
    cmd_download_help
    return true
  end

  recursive = false
  src_items = []
  last      = nil
  dest      = nil

  @@download_opts.parse(args) { |opt, idx, val|
    case opt
    when "-r"
      recursive = true
    when nil
      src_items << last if (last)
      last = val
    end
  }

  # No files given, nothing to do
  if not last
    cmd_download_help
    return true
  end

  # Source and destination will be the same
  if src_items.empty?
    src_items << last
    # Use the basename of the remote filename so we don't end up with
    # a file named c:\\boot.ini in linux
    dest = ::Rex::Post::Meterpreter::Extensions::Stdapi::Fs::File.basename(last)
  else
    dest = last
  end

  # Go through each source item and download them
  src_items.each { |src|
    stat = client.fs.file.stat(src)

    if (stat.directory?)
      client.fs.dir.download(dest, src, recursive, true) { |step, src, dst|
        print_status("#{step.ljust(11)}: #{src} -> #{dst}")
        client.framework.events.on_session_download(client, src, dest) if msf_loaded?
      }
    elsif (stat.file?)
      client.fs.file.download(dest, src) { |step, src, dst|
        print_status("#{step.ljust(11)}: #{src} -> #{dst}")
        client.framework.events.on_session_download(client, src, dest) if msf_loaded?
      }
    end
  }

  return true
end
cmd_download_help() click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 243
def cmd_download_help
  print_line "Usage: download [options] src1 src2 src3 ... destination"
  print_line
  print_line "Downloads remote files and directories to the local machine."
  print_line @@download_opts.usage
end
cmd_edit(*args) click to toggle source

Downloads a file to a temporary file, spawns and editor, and then uploads the contents to the remote machine after completion.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 315
def cmd_edit(*args)
  if (args.length == 0)
    print_line("Usage: edit file")
    return true
  end

  # Get a temporary file path
  meterp_temp = Tempfile.new('meterp')
  meterp_temp.binmode
  temp_path = meterp_temp.path

  begin
    # Download the remote file to the temporary file
    client.fs.file.download_file(temp_path, args[0])
  rescue RequestError => re
    # If the file doesn't exist, then it's okay.  Otherwise, throw the
    # error.
    if re.result != 2
      raise $!
    end
  end

  # Spawn the editor (default to vi)
  editor = Rex::Compat.getenv('EDITOR') || 'vi'

  # If it succeeds, upload it to the remote side.
  if (system("#{editor} #{temp_path}") == true)
    client.fs.file.upload_file(args[0], temp_path)
  end

  # Get rid of that pesky temporary file
  ::File.delete(temp_path) rescue nil
end
cmd_getlwd(*args)
Alias for: cmd_lpwd
cmd_getwd(*args)
Alias for: cmd_pwd
cmd_lcd(*args) click to toggle source

Change the local working directory.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 198
def cmd_lcd(*args)
  if (args.length == 0)
    print_line("Usage: lcd directory")
    return true
  end

  ::Dir.chdir(args[0])

  return true
end
cmd_lpwd(*args) click to toggle source

Display the local working directory.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 352
def cmd_lpwd(*args)
  print_line(::Dir.pwd)
  return true
end
Also aliased as: cmd_getlwd
cmd_ls(*args) click to toggle source

Lists files

TODO: make this more useful

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 364
def cmd_ls(*args)
  path = args[0] || client.fs.dir.getwd
  tbl  = Rex::Ui::Text::Table.new(
    'Header'  => "Listing: #{path}",
    'SortIndex' => 4,
    'Columns' =>
      [
        'Mode',
        'Size',
        'Type',
        'Last modified',
        'Name',
      ])

  items = 0
  stat = client.fs.file.stat(path)
  if stat.directory?
    # Enumerate each item...
    # No need to sort as Table will do it for us
    client.fs.dir.entries_with_info(path).each { |p|

      tbl <<
        [
          p['StatBuf'] ? p['StatBuf'].prettymode : '',
          p['StatBuf'] ? p['StatBuf'].size       : '',
          p['StatBuf'] ? p['StatBuf'].ftype[0,3] : '',
          p['StatBuf'] ? p['StatBuf'].mtime      : '',
          p['FileName'] || 'unknown'
        ]

      items += 1
    }

    if (items > 0)
      print("\n" + tbl.to_s + "\n")
    else
      print_line("No entries exist in #{path}")
    end
  else
    print_line("#{stat.prettymode}  #{stat.size}  #{stat.ftype[0,3]}  #{stat.mtime}  #{path}")
  end

  return true
end
cmd_mkdir(*args) click to toggle source

Make one or more directory.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 412
def cmd_mkdir(*args)
  if (args.length == 0)
    print_line("Usage: mkdir dir1 dir2 dir3 ...")
    return true
  end

  args.each { |dir|
    print_line("Creating directory: #{dir}")

    client.fs.dir.mkdir(dir)
  }

  return true
end
cmd_move(*args)
Alias for: cmd_mv
cmd_mv(*args) click to toggle source

Move source to destination

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 228
def cmd_mv(*args)
        if (args.length < 2)
                print_line("Usage: mv oldfile newfile")
                return true
        end 

        client.fs.file.mv(args[0],args[1])

        return true
end
Also aliased as: cmd_move, cmd_rename
cmd_pwd(*args) click to toggle source

Display the working directory.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 430
def cmd_pwd(*args)
  print_line(client.fs.dir.getwd)
end
Also aliased as: cmd_getwd
cmd_rename(*args)
Alias for: cmd_mv
cmd_rm(*args) click to toggle source

Delete the specified file.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 212
def cmd_rm(*args)
  if (args.length == 0)
    print_line("Usage: rm file")
    return true
  end

  client.fs.file.rm(args[0])

  return true
end
Also aliased as: cmd_del
cmd_rmdir(*args) click to toggle source

Removes one or more directory if it’s empty.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 439
def cmd_rmdir(*args)
  if (args.length == 0 or args.include?("-h"))
    print_line("Usage: rmdir dir1 dir2 dir3 ...")
    return true
  end

  args.each { |dir|
    print_line("Removing directory: #{dir}")
    client.fs.dir.rmdir(dir)
  }

  return true
end
cmd_upload(*args) click to toggle source

Uploads a file or directory to the remote machine from the local machine.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 464
def cmd_upload(*args)
  if (args.empty? or args.include?("-h"))
    cmd_upload_help
    return true
  end

  recursive = false
  src_items = []
  last      = nil
  dest      = nil

  @@upload_opts.parse(args) { |opt, idx, val|
    case opt
      when "-r"
        recursive = true
      when nil
        if (last)
          src_items << last
        end

        last = val
    end
  }

  return true if not last

  # Source and destination will be the same
  src_items << last if src_items.empty?

  dest = last

  # Go through each source item and upload them
  src_items.each { |src|
    stat = ::File.stat(src)

    if (stat.directory?)
      client.fs.dir.upload(dest, src, recursive) { |step, src, dst|
        print_status("#{step.ljust(11)}: #{src} -> #{dst}")
        client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
      }
    elsif (stat.file?)
      client.fs.file.upload(dest, src) { |step, src, dst|
        print_status("#{step.ljust(11)}: #{src} -> #{dst}")
        client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
      }
    end
  }

  return true
end
cmd_upload_help() click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 453
def cmd_upload_help
  print_line "Usage: upload [options] src1 src2 src3 ... destination"
  print_line
  print_line "Uploads local files and directories to the remote machine."
  print_line @@upload_opts.usage
end
cmd_upload_tabs(str, words) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 515
def cmd_upload_tabs(str, words)
  return [] if words.length > 1

  tab_complete_filenames(str, words)
end
commands() click to toggle source

List of supported commands.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 36
def commands
  all = {
    "cat"      => "Read the contents of a file to the screen",
    "cd"       => "Change directory",
    "del"      => "Delete the specified file",
    "download" => "Download a file or directory",
    "edit"     => "Edit a file",
    "getlwd"   => "Print local working directory",
    "getwd"    => "Print working directory",
    "lcd"      => "Change local working directory",
    "lpwd"     => "Print local working directory",
    "ls"       => "List files",
    "mkdir"    => "Make directory",
    "pwd"      => "Print working directory",
    "rm"       => "Delete the specified file",
    "mv"         => "Move source to destination",
    "rmdir"    => "Remove directory",
    "search"   => "Search for files",
    "upload"   => "Upload a file or directory",
  }

  reqs = {
    "cat"      => [ ],
    "cd"       => [ "stdapi_fs_chdir" ],
    "del"      => [ "stdapi_fs_rm" ],
    "download" => [ ],
    "edit"     => [ ],
    "getlwd"   => [ ],
    "getwd"    => [ "stdapi_fs_getwd" ],
    "lcd"      => [ ],
    "lpwd"     => [ ],
    "ls"       => [ "stdapi_fs_stat", "stdapi_fs_ls" ],
    "mkdir"    => [ "stdapi_fs_mkdir" ],
    "pwd"      => [ "stdapi_fs_getwd" ],
    "rmdir"    => [ "stdapi_fs_delete_dir" ],
    "rm"       => [ "stdapi_fs_delete_file" ],
    "mv"       => [ "stdapi_fs_file_move" ],
    "search"   => [ "stdapi_fs_search" ],
    "upload"   => [ ],
  }

  all.delete_if do |cmd, desc|
    del = false
    reqs[cmd].each do |req|
      next if client.commands.include? req
      del = true
      break
    end

    del
  end

  all
end
name() click to toggle source

Name for this dispatcher.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb, line 94
def name
  "Stdapi: File system"
end