librex 0.0.43 → 0.0.44

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: 13247
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' => Rex::Text.unicode_filter_decode( name )
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, Rex::Text.unicode_filter_decode(name))
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 << Rex::Text.unicode_filter_encode( file_name.value )
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, Rex::Text.unicode_filter_decode(name))
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' => Rex::Text.unicode_filter_encode( file_name.value ),
100
- 'FilePath' => Rex::Text.unicode_filter_encode( fpath[idx].value ),
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, Rex::Text.unicode_filter_decode( 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, Rex::Text.unicode_filter_decode( 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 Rex::Text.unicode_filter_encode( response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value )
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, Rex::Text.unicode_filter_decode( 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 + Rex::Text.unicode_filter_encode( src_sub )
199
- src_item = src + File::SEPARATOR + Rex::Text.unicode_filter_encode( src_sub )
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 + File::SEPARATOR + Rex::Text.unicode_filter_encode( src_sub )
244
- src_item = src + ::File::SEPARATOR + Rex::Text.unicode_filter_encode( src_sub )
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
- # This should be replaced with a platform-specific value.
33
+ # Return the directory separator, i.e.: "/" on unix, "\\" on windows
28
34
  #
29
- SEPARATOR = "\\"
30
- Separator = "\\"
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
- include Rex::Post::File
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
- attr_accessor :client
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 = Rex::Text.unicode_filter_decode(root) if 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' => Rex::Text.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ) ),
61
- 'name' => Rex::Text.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_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, Rex::Text.unicode_filter_decode( 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 Rex::Text.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_FILE_PATH) )
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, Rex::Text.unicode_filter_decode( 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, Rex::Text.unicode_filter_decode( 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, Rex::Text.unicode_filter_decode( name ))
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 (File.basename(destination) != ::File.basename(src))
172
- dest += File::SEPARATOR + ::File.basename(src)
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, Rex::Text.unicode_filter_decode( file ))
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 Rex::Text.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_USER_NAME) )
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 Rex::Text.unicode_filter_encode( res.get_tlv_value(TLV_TYPE_USER_NAME) )
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 Rex::Text.unicode_filter_encode( res.get_tlv_value(TLV_TYPE_USER_NAME) )
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, Rex::Text.unicode_filter_decode( 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' => Rex::Text.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_PROCESS_NAME) ),
241
- 'path' => Rex::Text.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_PROCESS_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' => Rex::Text.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_USER_NAME) ),
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'] = Rex::Text.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_PROCESS_NAME) )
362
- info['path'] = Rex::Text.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_PROCESS_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, Rex::Text.unicode_filter_decode( hive_file ))
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?)
@@ -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
- line = input.pgets
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
- def update_prompt(prompt = nil, new_prompt_char = nil)
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 (prompt)
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
 
@@ -94,7 +94,7 @@ class Table
94
94
  # Converts table contents to a string.
95
95
  #
96
96
  def to_s
97
- str = ''
97
+ str = prefix.dup
98
98
  str << header_to_s || ''
99
99
  str << columns_to_s || ''
100
100
  str << hr_to_s || ''
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: librex
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.43
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-19 00:00:00 -05:00
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 13247
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