librex 0.0.43 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +1 -1
- data/lib/rex/exploitation/javascriptosdetect.rb +6 -0
- data/lib/rex/post/meterpreter/channels/pools/file.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +20 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +13 -13
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +37 -15
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +6 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +10 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +3 -3
- data/lib/rex/ui/text/input/readline.rb +2 -3
- data/lib/rex/ui/text/shell.rb +69 -5
- data/lib/rex/ui/text/table.rb +1 -1
- metadata +3 -3
data/README.markdown
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
A non-official re-packaging of the Rex library as a gem for easy of usage of the Metasploit REX framework in a non Metasploit application. I received permission from HDM to create this package.
|
4
4
|
|
5
5
|
Currently based on:
|
6
|
-
SVN Revision:
|
6
|
+
SVN Revision: 13354
|
7
7
|
|
8
8
|
# Credits
|
9
9
|
The Metasploit development team <http://www.metasploit.com>
|
@@ -625,6 +625,12 @@ function getVersion(){
|
|
625
625
|
os_flavor = "2003";
|
626
626
|
os_sp = "SP2";
|
627
627
|
break;
|
628
|
+
case "568837":
|
629
|
+
// IE 6.0.2900.2180, XP Professional SP2 Korean
|
630
|
+
ua_version = "6.0";
|
631
|
+
os_flavor = "XP";
|
632
|
+
os_sp = "SP2";
|
633
|
+
break;
|
628
634
|
case "575730":
|
629
635
|
// IE 7.0.5730.13, Server 2003 Standard SP2 English
|
630
636
|
// IE 7.0.5730.13, Server 2003 Standard SP1 English
|
@@ -36,7 +36,7 @@ class File < Rex::Post::Meterpreter::Channels::Pool
|
|
36
36
|
[
|
37
37
|
{
|
38
38
|
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_PATH,
|
39
|
-
'value' =>
|
39
|
+
'value' => client.unicode_filter_decode( name )
|
40
40
|
},
|
41
41
|
{
|
42
42
|
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_MODE,
|
@@ -115,6 +115,8 @@ class Client
|
|
115
115
|
|
116
116
|
self.response_timeout = opts[:timeout] || self.class.default_timeout
|
117
117
|
self.send_keepalives = true
|
118
|
+
# self.encode_unicode = opts.has_key?(:encode_unicode) ? opts[:encode_unicode] : true
|
119
|
+
self.encode_unicode = false
|
118
120
|
|
119
121
|
if opts[:passive_dispatcher]
|
120
122
|
initialize_passive_dispatcher
|
@@ -367,6 +369,20 @@ class Client
|
|
367
369
|
return items.sort
|
368
370
|
end
|
369
371
|
|
372
|
+
#
|
373
|
+
# Encodes (or not) a UTF-8 string
|
374
|
+
#
|
375
|
+
def unicode_filter_encode(str)
|
376
|
+
self.encode_unicode ? Rex::Text.unicode_filter_encode(str) : str
|
377
|
+
end
|
378
|
+
|
379
|
+
#
|
380
|
+
# Decodes (or not) a UTF-8 string
|
381
|
+
#
|
382
|
+
def unicode_filter_decode(str)
|
383
|
+
self.encode_unicode ? Rex::Text.unicode_filter_decode(str) : str
|
384
|
+
end
|
385
|
+
|
370
386
|
#
|
371
387
|
# The extension alias under which all extensions can be accessed by name.
|
372
388
|
# For example:
|
@@ -424,6 +440,10 @@ class Client
|
|
424
440
|
# The Passive Dispatcher
|
425
441
|
#
|
426
442
|
attr_accessor :passive_dispatcher
|
443
|
+
#
|
444
|
+
# Flag indicating whether to hex-encode UTF-8 file names and other strings
|
445
|
+
#
|
446
|
+
attr_accessor :encode_unicode
|
427
447
|
|
428
448
|
protected
|
429
449
|
attr_accessor :parser, :ext_aliases # :nodoc:
|
@@ -56,12 +56,12 @@ class Dir < Rex::Post::Dir
|
|
56
56
|
request = Packet.create_request('stdapi_fs_ls')
|
57
57
|
files = []
|
58
58
|
|
59
|
-
request.add_tlv(TLV_TYPE_DIRECTORY_PATH,
|
59
|
+
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))
|
60
60
|
|
61
61
|
response = client.send_request(request)
|
62
62
|
|
63
63
|
response.each(TLV_TYPE_FILE_NAME) { |file_name|
|
64
|
-
files <<
|
64
|
+
files << client.unicode_filter_encode( file_name.value )
|
65
65
|
}
|
66
66
|
|
67
67
|
return files
|
@@ -74,7 +74,7 @@ class Dir < Rex::Post::Dir
|
|
74
74
|
request = Packet.create_request('stdapi_fs_ls')
|
75
75
|
files = []
|
76
76
|
|
77
|
-
request.add_tlv(TLV_TYPE_DIRECTORY_PATH,
|
77
|
+
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))
|
78
78
|
|
79
79
|
response = client.send_request(request)
|
80
80
|
|
@@ -96,8 +96,8 @@ class Dir < Rex::Post::Dir
|
|
96
96
|
|
97
97
|
files <<
|
98
98
|
{
|
99
|
-
'FileName' =>
|
100
|
-
'FilePath' =>
|
99
|
+
'FileName' => client.unicode_filter_encode( file_name.value ),
|
100
|
+
'FilePath' => client.unicode_filter_encode( fpath[idx].value ),
|
101
101
|
'StatBuf' => st,
|
102
102
|
}
|
103
103
|
}
|
@@ -117,7 +117,7 @@ class Dir < Rex::Post::Dir
|
|
117
117
|
def Dir.chdir(path)
|
118
118
|
request = Packet.create_request('stdapi_fs_chdir')
|
119
119
|
|
120
|
-
request.add_tlv(TLV_TYPE_DIRECTORY_PATH,
|
120
|
+
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))
|
121
121
|
|
122
122
|
response = client.send_request(request)
|
123
123
|
|
@@ -130,7 +130,7 @@ class Dir < Rex::Post::Dir
|
|
130
130
|
def Dir.mkdir(path)
|
131
131
|
request = Packet.create_request('stdapi_fs_mkdir')
|
132
132
|
|
133
|
-
request.add_tlv(TLV_TYPE_DIRECTORY_PATH,
|
133
|
+
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))
|
134
134
|
|
135
135
|
response = client.send_request(request)
|
136
136
|
|
@@ -145,7 +145,7 @@ class Dir < Rex::Post::Dir
|
|
145
145
|
|
146
146
|
response = client.send_request(request)
|
147
147
|
|
148
|
-
return
|
148
|
+
return client.unicode_filter_encode( response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value )
|
149
149
|
end
|
150
150
|
|
151
151
|
#
|
@@ -161,7 +161,7 @@ class Dir < Rex::Post::Dir
|
|
161
161
|
def Dir.delete(path)
|
162
162
|
request = Packet.create_request('stdapi_fs_delete_dir')
|
163
163
|
|
164
|
-
request.add_tlv(TLV_TYPE_DIRECTORY_PATH,
|
164
|
+
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode( path ))
|
165
165
|
|
166
166
|
response = client.send_request(request)
|
167
167
|
|
@@ -195,8 +195,8 @@ class Dir < Rex::Post::Dir
|
|
195
195
|
def Dir.download(dst, src, recursive = false, force = true, &stat)
|
196
196
|
|
197
197
|
self.entries(src).each { |src_sub|
|
198
|
-
dst_item = dst + ::File::SEPARATOR +
|
199
|
-
src_item = src +
|
198
|
+
dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
|
199
|
+
src_item = src + client.fs.file.separator + client.unicode_filter_encode( src_sub )
|
200
200
|
|
201
201
|
if (src_sub == '.' or src_sub == '..')
|
202
202
|
next
|
@@ -240,8 +240,8 @@ class Dir < Rex::Post::Dir
|
|
240
240
|
#
|
241
241
|
def Dir.upload(dst, src, recursive = false, &stat)
|
242
242
|
::Dir.entries(src).each { |src_sub|
|
243
|
-
dst_item = dst +
|
244
|
-
src_item = src + ::File::SEPARATOR +
|
243
|
+
dst_item = dst + client.fs.file.separator + client.unicode_filter_encode( src_sub )
|
244
|
+
src_item = src + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
|
245
245
|
|
246
246
|
if (src_sub == '.' or src_sub == '..')
|
247
247
|
next
|
@@ -23,16 +23,38 @@ module Fs
|
|
23
23
|
###
|
24
24
|
class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
25
25
|
|
26
|
+
include Rex::Post::File
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_accessor :client
|
30
|
+
end
|
31
|
+
|
26
32
|
#
|
27
|
-
#
|
33
|
+
# Return the directory separator, i.e.: "/" on unix, "\\" on windows
|
28
34
|
#
|
29
|
-
|
30
|
-
|
35
|
+
def File.separator()
|
36
|
+
# The separator won't change, so cache it to prevent sending
|
37
|
+
# unnecessary requests.
|
38
|
+
return @separator if @separator
|
31
39
|
|
32
|
-
|
40
|
+
request = Packet.create_request('stdapi_fs_separator')
|
41
|
+
|
42
|
+
# Fall back to the old behavior of always assuming windows. This
|
43
|
+
# allows meterpreter executables built before the addition of this
|
44
|
+
# command to continue functioning.
|
45
|
+
begin
|
46
|
+
response = client.send_request(request)
|
47
|
+
@separator = response.get_tlv_value(TLV_TYPE_STRING)
|
48
|
+
rescue RequestError
|
49
|
+
@separator = "\\"
|
50
|
+
end
|
51
|
+
|
52
|
+
return @separator
|
53
|
+
end
|
33
54
|
|
34
55
|
class << self
|
35
|
-
|
56
|
+
alias :Separator :separator
|
57
|
+
alias :SEPARATOR :separator
|
36
58
|
end
|
37
59
|
|
38
60
|
#
|
@@ -44,7 +66,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
44
66
|
|
45
67
|
request = Packet.create_request( 'stdapi_fs_search' )
|
46
68
|
|
47
|
-
root =
|
69
|
+
root = client.unicode_filter_decode(root) if root
|
48
70
|
root = root.chomp( '\\' ) if root
|
49
71
|
|
50
72
|
request.add_tlv( TLV_TYPE_SEARCH_ROOT, root )
|
@@ -57,8 +79,8 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
57
79
|
if( response.result == 0 )
|
58
80
|
response.each( TLV_TYPE_SEARCH_RESULTS ) do | results |
|
59
81
|
files << {
|
60
|
-
'path' =>
|
61
|
-
'name' =>
|
82
|
+
'path' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ) ),
|
83
|
+
'name' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_NAME ) ),
|
62
84
|
'size' => results.get_tlv_value( TLV_TYPE_FILE_SIZE )
|
63
85
|
}
|
64
86
|
end
|
@@ -88,11 +110,11 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
88
110
|
def File.expand_path(path)
|
89
111
|
request = Packet.create_request('stdapi_fs_file_expand_path')
|
90
112
|
|
91
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
113
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( path ))
|
92
114
|
|
93
115
|
response = client.send_request(request)
|
94
116
|
|
95
|
-
return
|
117
|
+
return client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_FILE_PATH) )
|
96
118
|
end
|
97
119
|
|
98
120
|
|
@@ -102,7 +124,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
102
124
|
def File.md5(path)
|
103
125
|
request = Packet.create_request('stdapi_fs_md5')
|
104
126
|
|
105
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
127
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( path ))
|
106
128
|
|
107
129
|
response = client.send_request(request)
|
108
130
|
|
@@ -116,7 +138,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
116
138
|
def File.sha1(path)
|
117
139
|
request = Packet.create_request('stdapi_fs_sha1')
|
118
140
|
|
119
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
141
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( path ))
|
120
142
|
|
121
143
|
response = client.send_request(request)
|
122
144
|
|
@@ -145,7 +167,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
145
167
|
def File.rm(name)
|
146
168
|
request = Packet.create_request('stdapi_fs_delete_file')
|
147
169
|
|
148
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
170
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( name ))
|
149
171
|
|
150
172
|
response = client.send_request(request)
|
151
173
|
|
@@ -168,8 +190,8 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
|
168
190
|
dest = destination
|
169
191
|
|
170
192
|
stat.call('uploading', src, dest) if (stat)
|
171
|
-
if (
|
172
|
-
dest +=
|
193
|
+
if (self.basename(destination) != ::File.basename(src))
|
194
|
+
dest += self.separator + ::File.basename(src)
|
173
195
|
end
|
174
196
|
|
175
197
|
upload_file(dest, src)
|
@@ -88,7 +88,7 @@ protected
|
|
88
88
|
def stat(file)
|
89
89
|
request = Packet.create_request('stdapi_fs_stat')
|
90
90
|
|
91
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
91
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, self.class.client.unicode_filter_decode( file ))
|
92
92
|
|
93
93
|
response = self.class.client.send_request(request)
|
94
94
|
stat_buf = response.get_tlv(TLV_TYPE_STAT_BUF).value
|
@@ -30,7 +30,7 @@ class Config
|
|
30
30
|
def getuid
|
31
31
|
request = Packet.create_request('stdapi_sys_config_getuid')
|
32
32
|
response = client.send_request(request)
|
33
|
-
return
|
33
|
+
return client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_USER_NAME) )
|
34
34
|
end
|
35
35
|
|
36
36
|
#
|
@@ -62,7 +62,7 @@ class Config
|
|
62
62
|
req = Packet.create_request('stdapi_sys_config_steal_token')
|
63
63
|
req.add_tlv(TLV_TYPE_PID, pid.to_i)
|
64
64
|
res = client.send_request(req)
|
65
|
-
return
|
65
|
+
return client.unicode_filter_encode( res.get_tlv_value(TLV_TYPE_USER_NAME) )
|
66
66
|
end
|
67
67
|
|
68
68
|
#
|
@@ -71,7 +71,7 @@ class Config
|
|
71
71
|
def drop_token
|
72
72
|
req = Packet.create_request('stdapi_sys_config_drop_token')
|
73
73
|
res = client.send_request(req)
|
74
|
-
return
|
74
|
+
return client.unicode_filter_encode( res.get_tlv_value(TLV_TYPE_USER_NAME) )
|
75
75
|
end
|
76
76
|
|
77
77
|
#
|
@@ -151,7 +151,7 @@ class Process < Rex::Post::Process
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
request.add_tlv(TLV_TYPE_PROCESS_PATH,
|
154
|
+
request.add_tlv(TLV_TYPE_PROCESS_PATH, client.unicode_filter_decode( path ));
|
155
155
|
|
156
156
|
# If process arguments were supplied
|
157
157
|
if (arguments != nil)
|
@@ -237,10 +237,10 @@ class Process < Rex::Post::Process
|
|
237
237
|
{
|
238
238
|
'pid' => p.get_tlv_value(TLV_TYPE_PID),
|
239
239
|
'parentid' => p.get_tlv_value(TLV_TYPE_PARENT_PID),
|
240
|
-
'name' =>
|
241
|
-
'path' =>
|
240
|
+
'name' => client.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_PROCESS_NAME) ),
|
241
|
+
'path' => client.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_PROCESS_PATH) ),
|
242
242
|
'session' => p.get_tlv_value(TLV_TYPE_PROCESS_SESSION),
|
243
|
-
'user' =>
|
243
|
+
'user' => client.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_USER_NAME) ),
|
244
244
|
'arch' => arch
|
245
245
|
}
|
246
246
|
}
|
@@ -358,8 +358,8 @@ protected
|
|
358
358
|
response = client.send_request(request)
|
359
359
|
|
360
360
|
# Populate the hash
|
361
|
-
info['name'] =
|
362
|
-
info['path'] =
|
361
|
+
info['name'] = client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_PROCESS_NAME) )
|
362
|
+
info['path'] = client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_PROCESS_PATH) )
|
363
363
|
|
364
364
|
return info
|
365
365
|
end
|
@@ -44,7 +44,7 @@ class Registry
|
|
44
44
|
request = Packet.create_request('stdapi_registry_load_key')
|
45
45
|
request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
|
46
46
|
request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
|
47
|
-
request.add_tlv(TLV_TYPE_FILE_PATH,
|
47
|
+
request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( hive_file ))
|
48
48
|
|
49
49
|
response = client.send_request(request)
|
50
50
|
return response.get_tlv(TLV_TYPE_RESULT).value
|
@@ -58,6 +58,8 @@ class Console::CommandDispatcher::Core
|
|
58
58
|
"bgkill" => "Kills a background meterpreter script",
|
59
59
|
"bglist" => "Lists running background scripts",
|
60
60
|
"write" => "Writes data to a channel",
|
61
|
+
"enable_unicode_encoding" => "Enables encoding of unicode strings",
|
62
|
+
"disable_unicode_encoding" => "Disables encoding of unicode strings"
|
61
63
|
}
|
62
64
|
if (msf_loaded?)
|
63
65
|
c["info"] = "Displays information about a Post module"
|
@@ -707,7 +709,15 @@ class Console::CommandDispatcher::Core
|
|
707
709
|
end
|
708
710
|
end
|
709
711
|
|
712
|
+
def cmd_enable_unicode_encoding
|
713
|
+
client.encode_unicode = true
|
714
|
+
print_status("Unicode encoding is enabled")
|
715
|
+
end
|
710
716
|
|
717
|
+
def cmd_disable_unicode_encoding
|
718
|
+
client.encode_unicode = false
|
719
|
+
print_status("Unicode encoding is disabled")
|
720
|
+
end
|
711
721
|
|
712
722
|
@@client_extension_search_paths = [ ::File.join(Rex::Root, "post", "meterpreter", "ui", "console", "command_dispatcher") ]
|
713
723
|
|
@@ -78,8 +78,8 @@ module DispatcherShell
|
|
78
78
|
#
|
79
79
|
# Wraps shell.update_prompt
|
80
80
|
#
|
81
|
-
def update_prompt(prompt=nil)
|
82
|
-
shell.update_prompt(prompt)
|
81
|
+
def update_prompt(prompt=nil, prompt_char = nil, mode = false)
|
82
|
+
shell.update_prompt(prompt, prompt_char, mode)
|
83
83
|
end
|
84
84
|
|
85
85
|
#
|
@@ -204,7 +204,7 @@ module DispatcherShell
|
|
204
204
|
#
|
205
205
|
# Initialize the dispatcher shell.
|
206
206
|
#
|
207
|
-
def initialize(prompt, prompt_char = '>', histfile = nil)
|
207
|
+
def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
|
208
208
|
super
|
209
209
|
|
210
210
|
# Initialze the dispatcher array
|
@@ -18,8 +18,6 @@ begin
|
|
18
18
|
# Initializes the readline-aware Input instance for text.
|
19
19
|
#
|
20
20
|
def initialize(tab_complete_proc = nil)
|
21
|
-
|
22
|
-
|
23
21
|
if(not Object.const_defined?('Readline'))
|
24
22
|
begin
|
25
23
|
require 'readline'
|
@@ -79,13 +77,14 @@ begin
|
|
79
77
|
# down other background threads. This is important when there are many active
|
80
78
|
# background jobs, such as when the user is running Karmetasploit
|
81
79
|
#
|
82
|
-
def pgets
|
80
|
+
def pgets()
|
83
81
|
|
84
82
|
line = nil
|
85
83
|
orig = Thread.current.priority
|
86
84
|
|
87
85
|
begin
|
88
86
|
Thread.current.priority = -20
|
87
|
+
|
89
88
|
output.prompting
|
90
89
|
line = ::Readline.readline(prompt, true)
|
91
90
|
::Readline::HISTORY.pop if (line and line.empty?)
|
data/lib/rex/ui/text/shell.rb
CHANGED
@@ -21,7 +21,8 @@ module Shell
|
|
21
21
|
module InputShell
|
22
22
|
attr_accessor :prompt, :output
|
23
23
|
|
24
|
-
def pgets
|
24
|
+
def pgets()
|
25
|
+
|
25
26
|
output.print(prompt)
|
26
27
|
output.flush
|
27
28
|
|
@@ -36,7 +37,7 @@ module Shell
|
|
36
37
|
#
|
37
38
|
# Initializes a shell that has a prompt and can be interacted with.
|
38
39
|
#
|
39
|
-
def initialize(prompt, prompt_char = '>', histfile = nil)
|
40
|
+
def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
|
40
41
|
# Set the stop flag to false
|
41
42
|
self.stop_flag = false
|
42
43
|
self.disable_output = false
|
@@ -48,6 +49,8 @@ module Shell
|
|
48
49
|
|
49
50
|
self.histfile = histfile
|
50
51
|
self.hist_last_saved = 0
|
52
|
+
|
53
|
+
self.framework = framework
|
51
54
|
end
|
52
55
|
|
53
56
|
def init_tab_complete
|
@@ -124,7 +127,60 @@ module Shell
|
|
124
127
|
break if (self.stop_flag or self.stop_count > 1)
|
125
128
|
|
126
129
|
init_tab_complete
|
127
|
-
|
130
|
+
|
131
|
+
if framework
|
132
|
+
if input.prompt.include?("%T")
|
133
|
+
t = Time.now
|
134
|
+
if framework.datastore['PromptTimeFormat']
|
135
|
+
t = t.strftime(framework.datastore['PromptTimeFormat'])
|
136
|
+
end
|
137
|
+
input.prompt.gsub!(/%T/, t.to_s)
|
138
|
+
end
|
139
|
+
|
140
|
+
if input.prompt.include?("%H")
|
141
|
+
hostname = ENV['HOSTNAME']
|
142
|
+
if hostname.nil?
|
143
|
+
hostname = `hostname`.split('.')[0]
|
144
|
+
end
|
145
|
+
|
146
|
+
# check if hostname is still nil
|
147
|
+
if hostname.nil?
|
148
|
+
hostname = ENV['COMPUTERNAME']
|
149
|
+
end
|
150
|
+
|
151
|
+
if hostname.nil?
|
152
|
+
hostname = 'unknown'
|
153
|
+
end
|
154
|
+
|
155
|
+
input.prompt.gsub!(/%H/, hostname.chomp)
|
156
|
+
end
|
157
|
+
|
158
|
+
if input.prompt.include?("%U")
|
159
|
+
user = ENV['USER']
|
160
|
+
if user.nil?
|
161
|
+
user = `whoami`
|
162
|
+
end
|
163
|
+
|
164
|
+
# check if username is still nil
|
165
|
+
if user.nil?
|
166
|
+
user = ENV['USERNAME']
|
167
|
+
end
|
168
|
+
|
169
|
+
if user.nil?
|
170
|
+
user = 'unknown'
|
171
|
+
end
|
172
|
+
|
173
|
+
input.prompt.gsub!(/%U/, user.chomp)
|
174
|
+
end
|
175
|
+
|
176
|
+
input.prompt.gsub!(/%S/, framework.sessions.length.to_s)
|
177
|
+
input.prompt.gsub!(/%J/, framework.jobs.length.to_s)
|
178
|
+
input.prompt.gsub!(/%L/, Rex::Socket.source_address("50.50.50.50"))
|
179
|
+
input.prompt.gsub!(/%D/, ::Dir.getwd)
|
180
|
+
self.init_prompt = input.prompt
|
181
|
+
end
|
182
|
+
|
183
|
+
line = input.pgets()
|
128
184
|
log_output(input.prompt)
|
129
185
|
|
130
186
|
# If a block was passed in, pass the line to it. If it returns true,
|
@@ -176,14 +232,21 @@ module Shell
|
|
176
232
|
#
|
177
233
|
# Change the input prompt.
|
178
234
|
#
|
179
|
-
|
235
|
+
# prompt - the actual prompt
|
236
|
+
# new_prompt_char the char to append to the prompt
|
237
|
+
# mode - append or not to append - false = append true = make a new prompt
|
238
|
+
def update_prompt(prompt = nil, new_prompt_char = nil, mode = false)
|
180
239
|
if (self.input)
|
181
|
-
if
|
240
|
+
if prompt
|
182
241
|
new_prompt = self.init_prompt + ' ' + prompt + prompt_char + ' '
|
183
242
|
else
|
184
243
|
new_prompt = self.prompt || ''
|
185
244
|
end
|
186
245
|
|
246
|
+
if mode
|
247
|
+
new_prompt = prompt + (new_prompt_char || prompt_char) + ' '
|
248
|
+
end
|
249
|
+
|
187
250
|
# Save the prompt before any substitutions
|
188
251
|
self.prompt = new_prompt
|
189
252
|
|
@@ -263,6 +326,7 @@ module Shell
|
|
263
326
|
|
264
327
|
attr_accessor :on_command_proc
|
265
328
|
attr_accessor :on_print_proc
|
329
|
+
attr_accessor :framework
|
266
330
|
|
267
331
|
protected
|
268
332
|
|
data/lib/rex/ui/text/table.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: librex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.44
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Metasploit Development Team
|
@@ -11,11 +11,11 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-07-
|
14
|
+
date: 2011-07-26 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
18
|
-
description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision
|
18
|
+
description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision 13354
|
19
19
|
email:
|
20
20
|
- hdm@metasploit.com
|
21
21
|
- jacob.hammack@hammackj.com
|