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.
@@ -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