Land #4950: ls unicode and sorting in meterpreter
commit
040ef1e3e9
|
@ -9,7 +9,7 @@ PATH
|
|||
json
|
||||
metasploit-concern (~> 0.3.0)
|
||||
metasploit-model (~> 0.29.0)
|
||||
meterpreter_bins (= 0.0.14)
|
||||
meterpreter_bins (= 0.0.16)
|
||||
msgpack
|
||||
nokogiri
|
||||
packetfu (= 1.1.9)
|
||||
|
@ -132,7 +132,7 @@ GEM
|
|||
pg
|
||||
railties (< 4.0.0)
|
||||
recog (~> 1.0)
|
||||
meterpreter_bins (0.0.14)
|
||||
meterpreter_bins (0.0.16)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.6.1)
|
||||
|
|
|
@ -61,7 +61,7 @@ class Dir < Rex::Post::Dir
|
|||
response = client.send_request(request)
|
||||
|
||||
response.each(TLV_TYPE_FILE_NAME) { |file_name|
|
||||
files << client.unicode_filter_encode( file_name.value )
|
||||
files << file_name.value
|
||||
}
|
||||
|
||||
return files
|
||||
|
@ -79,6 +79,7 @@ class Dir < Rex::Post::Dir
|
|||
response = client.send_request(request)
|
||||
|
||||
fname = response.get_tlvs(TLV_TYPE_FILE_NAME)
|
||||
fsname = response.get_tlvs(TLV_TYPE_FILE_SHORT_NAME)
|
||||
fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
|
||||
|
||||
|
@ -96,8 +97,9 @@ class Dir < Rex::Post::Dir
|
|||
|
||||
files <<
|
||||
{
|
||||
'FileName' => client.unicode_filter_encode( file_name.value ),
|
||||
'FilePath' => client.unicode_filter_encode( fpath[idx].value ),
|
||||
'FileName' => file_name.value,
|
||||
'FilePath' => fpath[idx].value,
|
||||
'FileShortName' => fsname[idx] ? fsname[idx].value : nil,
|
||||
'StatBuf' => st,
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +147,7 @@ class Dir < Rex::Post::Dir
|
|||
|
||||
response = client.send_request(request)
|
||||
|
||||
return client.unicode_filter_encode( response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value )
|
||||
return response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -195,8 +197,8 @@ class Dir < Rex::Post::Dir
|
|||
def Dir.download(dst, src, recursive = false, force = true, &stat)
|
||||
|
||||
self.entries(src).each { |src_sub|
|
||||
dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
|
||||
src_item = src + client.fs.file.separator + client.unicode_filter_encode( src_sub )
|
||||
dst_item = dst + ::File::SEPARATOR + src_sub
|
||||
src_item = src + client.fs.file.separator + src_sub
|
||||
|
||||
if (src_sub == '.' or src_sub == '..')
|
||||
next
|
||||
|
@ -240,8 +242,8 @@ class Dir < Rex::Post::Dir
|
|||
#
|
||||
def Dir.upload(dst, src, recursive = false, &stat)
|
||||
::Dir.entries(src).each { |src_sub|
|
||||
dst_item = dst + client.fs.file.separator + client.unicode_filter_encode( src_sub )
|
||||
src_item = src + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
|
||||
dst_item = dst + client.fs.file.separator + src_sub
|
||||
src_item = src + ::File::SEPARATOR + src_sub
|
||||
|
||||
if (src_sub == '.' or src_sub == '..')
|
||||
next
|
||||
|
|
|
@ -91,8 +91,8 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|||
if( response.result == 0 )
|
||||
response.each( TLV_TYPE_SEARCH_RESULTS ) do | results |
|
||||
files << {
|
||||
'path' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ) ),
|
||||
'name' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_NAME ) ),
|
||||
'path' => results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ),
|
||||
'name' => results.get_tlv_value( TLV_TYPE_FILE_NAME ),
|
||||
'size' => results.get_tlv_value( TLV_TYPE_FILE_SIZE )
|
||||
}
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|||
|
||||
response = client.send_request(request)
|
||||
|
||||
return client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_FILE_PATH) )
|
||||
return response.get_tlv_value(TLV_TYPE_FILE_PATH)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ TLV_TYPE_FILE_NAME = TLV_META_TYPE_STRING | 1201
|
|||
TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202
|
||||
TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203
|
||||
TLV_TYPE_FILE_SIZE = TLV_META_TYPE_UINT | 1204
|
||||
TLV_TYPE_FILE_SHORT_NAME = TLV_META_TYPE_STRING | 1205
|
||||
|
||||
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
|
||||
|
||||
|
|
|
@ -360,21 +360,42 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|||
#
|
||||
# Lists files
|
||||
#
|
||||
# TODO: make this more useful
|
||||
#
|
||||
def cmd_ls(*args)
|
||||
|
||||
# Check sort column
|
||||
sort = args.include?('-S') ? 'Size' : 'Name'
|
||||
sort = args.include?('-t') ? 'Last modified' : sort
|
||||
args.delete('-S')
|
||||
args.delete('-t')
|
||||
|
||||
# Check whether to include the short name option
|
||||
short = args.include?('-x')
|
||||
args.delete('-x')
|
||||
|
||||
# Check sort order
|
||||
order = args.include?('-r') ? :reverse : :forward
|
||||
args.delete('-r')
|
||||
|
||||
# Check for cries of help
|
||||
if args.length > 1 || args.any? { |a| a[0] == '-' }
|
||||
print_line('Usage: ls [dir] [-x] [-S] [-t] [-r]')
|
||||
print_line(' -x Show short file names')
|
||||
print_line(' -S Sort by size')
|
||||
print_line(' -t Sort by time modified')
|
||||
print_line(' -r Reverse sort order')
|
||||
return true
|
||||
end
|
||||
|
||||
path = args[0] || client.fs.dir.getwd
|
||||
|
||||
columns = [ 'Mode', 'Size', 'Type', 'Last modified', 'Name' ]
|
||||
columns.insert(4, 'Short Name') if short
|
||||
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Header' => "Listing: #{path}",
|
||||
'SortIndex' => 4,
|
||||
'Columns' =>
|
||||
[
|
||||
'Mode',
|
||||
'Size',
|
||||
'Type',
|
||||
'Last modified',
|
||||
'Name',
|
||||
])
|
||||
'SortIndex' => columns.index(sort),
|
||||
'SortOrder' => order,
|
||||
'Columns' => columns)
|
||||
|
||||
items = 0
|
||||
stat = client.fs.file.stat(path)
|
||||
|
@ -383,14 +404,16 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|||
# No need to sort as Table will do it for us
|
||||
client.fs.dir.entries_with_info(path).each { |p|
|
||||
|
||||
tbl <<
|
||||
[
|
||||
row = [
|
||||
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'
|
||||
]
|
||||
row.insert(4, p['FileShortName'] || '') if short
|
||||
|
||||
tbl << row
|
||||
|
||||
items += 1
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ class Table
|
|||
self.colprops = []
|
||||
|
||||
self.sort_index = opts['SortIndex'] || 0
|
||||
self.sort_order = opts['SortOrder'] || :forward
|
||||
|
||||
# Default column properties
|
||||
self.columns.length.times { |idx|
|
||||
|
@ -187,21 +188,22 @@ class Table
|
|||
# If the supplied index is an IPv4 address, handle it differently, but
|
||||
# avoid actually resolving domain names.
|
||||
#
|
||||
def sort_rows(index=sort_index)
|
||||
def sort_rows(index = sort_index, order = sort_order)
|
||||
return if index == -1
|
||||
return unless rows
|
||||
rows.sort! do |a,b|
|
||||
if a[index].nil?
|
||||
-1
|
||||
cmp = -1
|
||||
elsif b[index].nil?
|
||||
1
|
||||
cmp = 1
|
||||
elsif Rex::Socket.dotted_ip?(a[index]) and Rex::Socket.dotted_ip?(b[index])
|
||||
Rex::Socket::addr_atoi(a[index]) <=> Rex::Socket::addr_atoi(b[index])
|
||||
cmp = Rex::Socket::addr_atoi(a[index]) <=> Rex::Socket::addr_atoi(b[index])
|
||||
elsif a[index] =~ /^[0-9]+$/ and b[index] =~ /^[0-9]+$/
|
||||
a[index].to_i <=> b[index].to_i
|
||||
cmp = a[index].to_i <=> b[index].to_i
|
||||
else
|
||||
a[index] <=> b[index] # assumes otherwise comparable.
|
||||
cmp = a[index] <=> b[index] # assumes otherwise comparable.
|
||||
end
|
||||
order == :forward ? cmp : -cmp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -243,7 +245,7 @@ class Table
|
|||
attr_accessor :columns, :rows, :colprops # :nodoc:
|
||||
attr_accessor :width, :indent, :cellpad # :nodoc:
|
||||
attr_accessor :prefix, :postfix # :nodoc:
|
||||
attr_accessor :sort_index # :nodoc:
|
||||
attr_accessor :sort_index, :sort_order # :nodoc:
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
|
||||
# Needed for Meterpreter on Windows, soon others.
|
||||
spec.add_runtime_dependency 'meterpreter_bins', '0.0.14'
|
||||
spec.add_runtime_dependency 'meterpreter_bins', '0.0.16'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
|
Loading…
Reference in New Issue