Skip to content

Commit c774038

Browse files
author
Brent Cook
committed
improve ls output by providing various new options
1 parent d22231b commit c774038

File tree

4 files changed

+48
-20
lines changed

4 files changed

+48
-20
lines changed

lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def Dir.entries_with_info(name = getwd)
7979
response = client.send_request(request)
8080

8181
fname = response.get_tlvs(TLV_TYPE_FILE_NAME)
82+
fsname = response.get_tlvs(TLV_TYPE_FILE_SHORT_NAME)
8283
fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
8384
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
8485

@@ -98,6 +99,7 @@ def Dir.entries_with_info(name = getwd)
9899
{
99100
'FileName' => file_name.value,
100101
'FilePath' => fpath[idx].value,
102+
'FileShortName' => fsname[idx] ? fsname[idx].value : nil,
101103
'StatBuf' => st,
102104
}
103105
}

lib/rex/post/meterpreter/extensions/stdapi/tlv.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ module Stdapi
2929
TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202
3030
TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203
3131
TLV_TYPE_FILE_SIZE = TLV_META_TYPE_UINT | 1204
32+
TLV_TYPE_FILE_SHORT_NAME = TLV_META_TYPE_STRING | 1205
3233

3334
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
3435

lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,21 +360,42 @@ def cmd_lpwd(*args)
360360
#
361361
# Lists files
362362
#
363-
# TODO: make this more useful
364-
#
365363
def cmd_ls(*args)
364+
365+
# Check sort column
366+
sort = args.include?('-S') ? 'Size' : 'Name'
367+
sort = args.include?('-t') ? 'Last modified' : sort
368+
args.delete('-S')
369+
args.delete('-t')
370+
371+
# Check whether to include the short name option
372+
short = args.include?('-x')
373+
args.delete('-x')
374+
375+
# Check sort order
376+
order = args.include?('-r') ? :reverse : :forward
377+
args.delete('-r')
378+
379+
# Check for cries of help
380+
if args.length > 1 || args.any? { |a| a[0] == '-' }
381+
print_line('Usage: ls [dir] [-x] [-S] [-t] [-r]')
382+
print_line(' -x Show short file names')
383+
print_line(' -S Sort by size')
384+
print_line(' -t Sort by time modified')
385+
print_line(' -r Reverse sort order')
386+
return true
387+
end
388+
366389
path = args[0] || client.fs.dir.getwd
390+
391+
columns = [ 'Mode', 'Size', 'Type', 'Last modified', 'Name' ]
392+
columns.insert(4, 'Short Name') if short
393+
367394
tbl = Rex::Ui::Text::Table.new(
368395
'Header' => "Listing: #{path}",
369-
'SortIndex' => 4,
370-
'Columns' =>
371-
[
372-
'Mode',
373-
'Size',
374-
'Type',
375-
'Last modified',
376-
'Name',
377-
])
396+
'SortIndex' => columns.index(sort),
397+
'SortOrder' => order,
398+
'Columns' => columns)
378399

379400
items = 0
380401
stat = client.fs.file.stat(path)
@@ -383,14 +404,16 @@ def cmd_ls(*args)
383404
# No need to sort as Table will do it for us
384405
client.fs.dir.entries_with_info(path).each { |p|
385406

386-
tbl <<
387-
[
407+
row = [
388408
p['StatBuf'] ? p['StatBuf'].prettymode : '',
389409
p['StatBuf'] ? p['StatBuf'].size : '',
390410
p['StatBuf'] ? p['StatBuf'].ftype[0,3] : '',
391411
p['StatBuf'] ? p['StatBuf'].mtime : '',
392412
p['FileName'] || 'unknown'
393413
]
414+
row.insert(4, p['FileShortName'] || '') if short
415+
416+
tbl << row
394417

395418
items += 1
396419
}

lib/rex/ui/text/table.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def initialize(opts = {})
7474
self.colprops = []
7575

7676
self.sort_index = opts['SortIndex'] || 0
77+
self.sort_order = opts['SortOrder'] || :forward
7778

7879
# Default column properties
7980
self.columns.length.times { |idx|
@@ -187,21 +188,22 @@ def add_row(fields = [])
187188
# If the supplied index is an IPv4 address, handle it differently, but
188189
# avoid actually resolving domain names.
189190
#
190-
def sort_rows(index=sort_index)
191+
def sort_rows(index = sort_index, order = sort_order)
191192
return if index == -1
192193
return unless rows
193194
rows.sort! do |a,b|
194195
if a[index].nil?
195-
-1
196+
cmp = -1
196197
elsif b[index].nil?
197-
1
198+
cmp = 1
198199
elsif Rex::Socket.dotted_ip?(a[index]) and Rex::Socket.dotted_ip?(b[index])
199-
Rex::Socket::addr_atoi(a[index]) <=> Rex::Socket::addr_atoi(b[index])
200+
cmp = Rex::Socket::addr_atoi(a[index]) <=> Rex::Socket::addr_atoi(b[index])
200201
elsif a[index] =~ /^[0-9]+$/ and b[index] =~ /^[0-9]+$/
201-
a[index].to_i <=> b[index].to_i
202+
cmp = a[index].to_i <=> b[index].to_i
202203
else
203-
a[index] <=> b[index] # assumes otherwise comparable.
204+
cmp = a[index] <=> b[index] # assumes otherwise comparable.
204205
end
206+
order == :forward ? cmp : -cmp
205207
end
206208
end
207209

@@ -243,7 +245,7 @@ def [](*col_names)
243245
attr_accessor :columns, :rows, :colprops # :nodoc:
244246
attr_accessor :width, :indent, :cellpad # :nodoc:
245247
attr_accessor :prefix, :postfix # :nodoc:
246-
attr_accessor :sort_index # :nodoc:
248+
attr_accessor :sort_index, :sort_order # :nodoc:
247249

248250
protected
249251

0 commit comments

Comments
 (0)