Land #7125, Add timestamping to downloaded files

Fixes MS-1744.
bug/bundler_fix
Pearce Barry 2016-07-25 22:24:53 -05:00
commit f7562c09b2
No known key found for this signature in database
GPG Key ID: 0916F4DEA5C5DE0A
3 changed files with 26 additions and 9 deletions

View File

@ -195,7 +195,7 @@ class Dir < Rex::Post::Dir
# Downloads the contents of a remote directory a
# local directory, optionally in a recursive fashion.
#
def Dir.download(dst, src, recursive = false, force = true, glob = nil, &stat)
def Dir.download(dst, src, recursive = false, force = true, glob = nil, timestamp = nil, &stat)
self.entries(src, glob).each { |src_sub|
dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)
@ -208,7 +208,12 @@ class Dir < Rex::Post::Dir
src_stat = client.fs.filestat.new(src_item)
if (src_stat.file?)
if timestamp
dst_item << timestamp
end
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)
@ -231,7 +236,7 @@ class Dir < Rex::Post::Dir
end
stat.call('mirroring', src_item, dst_item) if (stat)
download(dst_item, src_item, recursive, force, glob, &stat)
download(dst_item, src_item, recursive, force, glob, timestamp, &stat)
stat.call('mirrored', src_item, dst_item) if (stat)
end
}

View File

@ -280,14 +280,19 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
# If a block is given, it will be called before each file is downloaded and
# again when each download is complete.
#
def File.download(dest, *src_files, &stat)
src_files.each { |src|
def File.download(dest, src_files, timestamp = nil, &stat)
[*src_files].each { |src|
if (::File.basename(dest) != File.basename(src))
# The destination when downloading is a local file so use this
# system's separator
dest += ::File::SEPARATOR + File.basename(src)
end
# XXX: dest can be the same object as src, so we use += instead of <<
if timestamp
dest += timestamp
end
stat.call('downloading', src, dest) if (stat)
result = download_file(dest, src)
stat.call(result, src, dest) if (stat)

View File

@ -24,7 +24,8 @@ class Console::CommandDispatcher::Stdapi::Fs
#
@@download_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
"-r" => [ false, "Download recursively." ])
"-r" => [ false, "Download recursively." ],
"-t" => [ false, "Timestamp downloaded files." ])
#
# Options for the upload command.
#
@ -332,6 +333,7 @@ class Console::CommandDispatcher::Stdapi::Fs
end
recursive = false
timestamp = false
src_items = []
last = nil
dest = nil
@ -340,6 +342,8 @@ class Console::CommandDispatcher::Stdapi::Fs
case opt
when "-r"
recursive = true
when "-t"
timestamp = true
when nil
src_items << last if (last)
last = val
@ -367,6 +371,10 @@ class Console::CommandDispatcher::Stdapi::Fs
dest = ::File.dirname(dest)
end
if timestamp
ts = '_' + Time.now.iso8601
end
# Go through each source item and download them
src_items.each { |src|
glob = nil
@ -389,8 +397,7 @@ class Console::CommandDispatcher::Stdapi::Fs
src_path = file['path'] + client.fs.file.separator + file['name']
dest_path = src_path.tr(src_separator, ::File::SEPARATOR)
client.fs.file.download(dest_path, src_path) do |step, src, dst|
puts step
client.fs.file.download(dest_path, src_path, ts) do |step, src, dst|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
client.framework.events.on_session_download(client, src, dest) if msf_loaded?
end
@ -404,12 +411,12 @@ class Console::CommandDispatcher::Stdapi::Fs
# Perform direct matching
stat = client.fs.file.stat(src)
if (stat.directory?)
client.fs.dir.download(dest, src, recursive, true, glob) do |step, src, dst|
client.fs.dir.download(dest, src, recursive, true, glob, ts) do |step, src, dst|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
client.framework.events.on_session_download(client, src, dest) if msf_loaded?
end
elsif (stat.file?)
client.fs.file.download(dest, src) do |step, src, dst|
client.fs.file.download(dest, src, ts) do |step, src, dst|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
client.framework.events.on_session_download(client, src, dest) if msf_loaded?
end