CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/ui/console/local_file_system.rb
Views: 1904
1
# -*- coding: binary -*-
2
3
module Msf
4
module Ui
5
module Console
6
###
7
#
8
# This module provides commands for the local file system
9
#
10
###
11
module LocalFileSystem
12
#
13
# Options for the lls command
14
#
15
@@lls_opts = Rex::Parser::Arguments.new(
16
'-h' => [ false, 'Help banner' ],
17
'-S' => [ true, 'Search string on filename (as regular expression)' ],
18
'-t' => [ false, 'Sort by time' ],
19
'-s' => [ false, 'Sort by size' ],
20
'-r' => [ false, 'Reverse sort order' ]
21
)
22
23
#
24
# List of supported local commands.
25
#
26
# @return [Hash] Hash of local commands
27
def local_fs_commands
28
{
29
'getlwd' => 'Print local working directory (alias for lpwd)',
30
'lcat' => 'Read the contents of a local file to the screen',
31
'lcd' => 'Change local working directory',
32
'lmkdir' => 'Create new directory on local machine',
33
'lpwd' => 'Print local working directory',
34
'lls' => 'List local files',
35
'ldir' => 'List local files (alias for lls)'
36
}
37
end
38
39
#
40
# List local files
41
#
42
# @param [Array] args
43
# @return [Rex::Text::Table] The results lls command
44
def cmd_lls(*args)
45
# Set Defaults
46
path = ::Dir.pwd
47
sort = 'Name'
48
order = :forward
49
search_term = nil
50
51
# Parse the args
52
@@lls_opts.parse(args) do |opt, _idx, val|
53
case opt
54
# Sort options
55
when '-s'
56
sort = 'Size'
57
when '-t'
58
sort = 'Last modified'
59
# Output options
60
when '-r'
61
order = :reverse
62
# Search
63
when '-S'
64
search_term = val
65
if search_term.nil?
66
print_error('Enter a search term')
67
return true
68
else
69
search_term = /#{search_term}/nmi
70
end
71
# Help and path
72
when '-h'
73
cmd_lls_help
74
return 0
75
when nil
76
path = val
77
end
78
end
79
80
list_local_path(path, sort, order, search_term)
81
end
82
83
#
84
# Help output for lss command
85
#
86
# @return [Rex::Parser::Arguments]
87
def cmd_lls_help
88
print_line 'Usage: lls [options]'
89
print_line
90
print_line 'Lists contents of a local directory or file info'
91
print_line @@lls_opts.usage
92
end
93
94
#
95
# Alias the lls command to dir, for those of us who have windows muscle-memory
96
#
97
alias cmd_ldir cmd_lls
98
99
#
100
# Change the local working directory.
101
#
102
# @param [Array] args
103
# @return [TrueClass]
104
def cmd_lcd(*args)
105
if args.empty?
106
print_line('Usage: lcd directory')
107
return true
108
end
109
110
::Dir.chdir(args[0])
111
112
true
113
end
114
115
#
116
# Tab completion for the lcd command
117
#
118
# @param [String] str
119
# @param [Array] words
120
def cmd_lcd_tabs(str, words)
121
tab_complete_directory(str, words)
122
end
123
124
alias cmd_lls_tabs cmd_lcd_tabs
125
126
#
127
# Get list local path information for lls command
128
#
129
# @param [String] path
130
# @param [String] sort
131
# @param [Symbol] order
132
# @param [nil] search_term
133
# @return [Rex::Text::Table, String] The results lcd command
134
def list_local_path(path, sort, order, search_term = nil)
135
# Single file as path
136
unless ::File.directory?(path)
137
perms = pretty_perms(path)
138
stat = ::File.stat(path)
139
print_line("#{perms} #{stat.size} #{stat.ftype[0, 3]} #{stat.mtime} #{path}")
140
return
141
end
142
143
# Enumerate each item...
144
# No need to sort as Table will do it for us
145
columns = [ 'Mode', 'Size', 'Type', 'Last modified', 'Name' ]
146
tbl = Rex::Text::Table.new(
147
'Header' => "Listing Local: #{path}",
148
'SortIndex' => columns.index(sort),
149
'SortOrder' => order,
150
'Columns' => columns
151
)
152
153
items = 0
154
files = ::Dir.entries(path)
155
156
files.each do |file|
157
file_path = ::File.join(path, file)
158
159
perms = pretty_perms(file_path)
160
stat = ::File.stat(file_path)
161
162
row = [
163
perms || '',
164
stat.size ? stat.size.to_s : '',
165
stat.ftype ? stat.ftype[0, 3] : '',
166
stat.mtime || '',
167
file
168
]
169
if file != '.' && file != '..' && (row.join(' ') =~ /#{search_term}/)
170
tbl << row
171
items += 1
172
end
173
end
174
if items > 0
175
print_line(tbl.to_s)
176
else
177
print_line("No entries exist in #{path}")
178
end
179
end
180
181
#
182
# Reads the contents of a local file and prints them to the screen.
183
#
184
# @param [Array] args
185
# @return [TrueClass]
186
def cmd_lcat(*args)
187
if args.empty? || args.include?('-h') || args.include?('--help')
188
print_line('Usage: lcat file')
189
return true
190
end
191
192
path = args[0]
193
path = ::File.expand_path(path) if path =~ path_expand_regex
194
195
if ::File.stat(path).directory?
196
print_error("#{path} is a directory")
197
else
198
fd = ::File.new(path, 'rb')
199
begin
200
print(fd.read) until fd.eof?
201
# EOFError is raised if file is empty, do nothing, just catch
202
rescue EOFError
203
end
204
fd.close
205
end
206
207
true
208
end
209
210
#
211
# Tab completion for the lcat command
212
#
213
# @param [Object] str
214
# @param [Object] words
215
# @return [Array] List of matches
216
def cmd_lcat_tabs(str, words)
217
tab_complete_filenames(str, words)
218
end
219
220
#
221
# Create new directory on local machine
222
#
223
# @param [Array] args
224
# @return [Array]
225
def cmd_lmkdir(*args)
226
if args.empty?
227
print_line('Usage: lmkdir </path/to/directory>')
228
return
229
end
230
231
args.each do |path|
232
::FileUtils.mkdir_p(path)
233
print_line("Directory '#{path}' created successfully.")
234
rescue ::StandardError => e
235
print_error("Error creating #{path} directory: #{e}")
236
end
237
end
238
239
#
240
# Display the local working directory.
241
#
242
# @param [Array] args
243
# @return [TrueClass]
244
def cmd_lpwd(*args)
245
print_line(::Dir.pwd)
246
true
247
end
248
249
alias cmd_getlwd cmd_lpwd
250
251
#
252
# Code from prettymode in lib/rex/post/file_stat.rb
253
# adapted for local file usage
254
#
255
# @param [Object] path
256
# @return [String]
257
def pretty_perms(path)
258
m = ::File.stat(path).mode
259
om = '%04o' % m
260
perms = ''
261
262
3.times do
263
perms = ((m & 0o1) == 0o1 ? 'x' : '-') + perms
264
perms = ((m & 0o2) == 0o2 ? 'w' : '-') + perms
265
perms = ((m & 0o4) == 0o4 ? 'r' : '-') + perms
266
m >>= 3
267
end
268
269
"#{om}/#{perms}"
270
end
271
272
private
273
274
# @return [Regexp]
275
def path_expand_regex
276
if shell.session.platform == 'windows'
277
/%(\w*)%/
278
else
279
/\$(([A-Za-z0-9_]+)|\{([A-Za-z0-9_]+)\})|^~/
280
end
281
end
282
end
283
end
284
end
285
end
286
287