diff --git a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb index 279a90e280..72dfe039a7 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb @@ -78,17 +78,27 @@ Separator = "\\" dest += File::SEPARATOR + ::File.basename(src) end - # Open the file on the remote side for writing and read - # all of the contents of the local file - dest_fd = client.fs.file.new(dest, "wb") - src_buf = ::IO.readlines(src).join - - dest_fd.write(src_buf) - dest_fd.close + upload_file(dest, src) stat.call('uploaded', src, dest) if (stat) } end + # + # Upload a single file. + # + def File.upload_file(dest_file, src_file) + # Open the file on the remote side for writing and read + # all of the contents of the local file + dest_fd = client.fs.file.new(dest_file, "wb") + src_buf = ::IO.readlines(src_file).join + + begin + dest_fd.write(src_buf) + ensure + dest_fd.close + end + end + # # Download one or more files from the remote computer to the local # directory supplied in destination. @@ -103,24 +113,30 @@ Separator = "\\" dest += ::File::SEPARATOR + File.basename(src) end - src_fd = client.fs.file.new(src, "rb") - dst_fd = ::File.new(dest, "wb") - - # Keep transferring until EOF is reached... - begin - while ((data = src_fd.read) != nil) - dst_fd.write(data) - end - rescue EOFError - end - - src_fd.close - dst_fd.close + download_file(dest, src) stat.call('downloaded', src, dest) if (stat) } end + # + # Download a single file. + # + def File.download_file(dest_file, src_file) + src_fd = client.fs.file.new(src_file, "rb") + dst_fd = ::File.new(dest_file, "wb") + + # Keep transferring until EOF is reached... + begin + while ((data = src_fd.read) != nil) + dst_fd.write(data) + end + rescue EOFError + ensure + src_fd.close + dst_fd.close + end + end ## # diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb index 6d165d3356..d91e099d7f 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb @@ -1,3 +1,4 @@ +require 'tempfile' require 'rex/post/meterpreter' module Rex @@ -35,6 +36,7 @@ class Console::CommandDispatcher::Stdapi::Fs "cat" => "Read the contents of a file to the screen", "cd" => "Change directory", "download" => "Download a file or directory", + "edit" => "Edit a file", "getwd" => "Print working directory", "ls" => "List files", "mkdir" => "Make directory", @@ -141,6 +143,34 @@ class Console::CommandDispatcher::Stdapi::Fs return true end + # + # Downloads a file to a temporary file, spawns and editor, and then uploads + # the contents to the remote machine after completion. + # + def cmd_edit(*args) + if (args.length == 0) + print_line("Usage: edit file") + return true + end + + # Get a temporary file path + temp_path = Tempfile.new('meterp').path + + # Download the remote file to the temporary file + client.fs.file.download_file(temp_path, args[0]) + + # Spawn the editor + editor = ENV['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.unlink(temp_path) + end + # # Lists files #