librex 0.0.28 → 0.0.29

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 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: 12292
6
+ SVN Revision: 12371
7
7
 
8
8
  # Credits
9
9
  The Metasploit development team <http://www.metasploit.com>
data/Rakefile CHANGED
@@ -86,7 +86,7 @@ task :update do
86
86
  system "mv README.markdown.1 README.markdown &> /dev/null"
87
87
 
88
88
  system "git commit -a -m \"Updated for Revision #{rev[1]}\" &> /dev/null"
89
- puts "Commiting and Pushing Updates for Revision #{rev[1]}"
89
+ puts "[*] Commiting and Pushing Updates for Revision #{rev[1]}"
90
90
  system "git push &> /dev/null"
91
91
 
92
92
  #Twitter tweet for the update, I am that lazy yes.
@@ -26,6 +26,11 @@ class Arguments
26
26
  #
27
27
  def initialize(fmt)
28
28
  self.fmt = fmt
29
+ # I think reduce is a better name for this method, but it doesn't exist
30
+ # before 1.8.7, so use the stupid inject instead.
31
+ self.longest = fmt.keys.inject(0) { |max, str|
32
+ max = ((max > str.length) ? max : str.length)
33
+ }
29
34
  end
30
35
 
31
36
  #
@@ -77,7 +82,7 @@ class Arguments
77
82
  fmt.sort.each { |entry|
78
83
  fmtspec, val = entry
79
84
 
80
- txt << " #{fmtspec}" + ((val[0] == true) ? " <opt> " : " ")
85
+ txt << " #{fmtspec.ljust(longest)}" + ((val[0] == true) ? " <opt> " : " ")
81
86
  txt << val[1] + "\n"
82
87
  }
83
88
 
@@ -89,7 +94,12 @@ class Arguments
89
94
  return fmt.include?(search)
90
95
  end
91
96
 
92
- attr_accessor :fmt # :nodoc:
97
+ def arg_required?(opt)
98
+ fmt[opt][0] if fmt[opt]
99
+ end
100
+
101
+ attr_accessor :fmt # :nodoc:
102
+ attr_accessor :longest # :nodoc:
93
103
 
94
104
  end
95
105
 
@@ -29,6 +29,7 @@ class NexposeXMLStreamParser
29
29
  @host["os_vendor"] = attributes["vendor"]
30
30
  @host["os_family"] = attributes["family"]
31
31
  @host["os_product"] = attributes["product"]
32
+ @host["os_version"] = attributes["version"]
32
33
  @host["arch"] = attributes["arch"]
33
34
  @host["os_certainty"] = attributes["certainty"]
34
35
  end
@@ -76,7 +77,7 @@ class NexposeXMLStreamParser
76
77
  when "vulnerability"
77
78
  callback.call(:vuln, @vuln) if callback
78
79
  reset_state
79
- when "service","reference"
80
+ when "service","reference","names"
80
81
  @state = :generic_state
81
82
  end
82
83
  end
@@ -70,10 +70,18 @@ class NmapXMLStreamParser
70
70
  @host["addr"] = attributes["addr"]
71
71
  end
72
72
  when "osclass"
73
- @host["os_vendor"] = attributes["vendor"]
74
- @host["os_family"] = attributes["osfamily"]
75
- @host["os_version"] = attributes["osgen"]
76
- @host["os_accuracy"] = attributes["accuracy"]
73
+ # If there is more than one, take the highest accuracy. In case of
74
+ # a tie, this will have the effect of taking the last one in the
75
+ # list. Last is really no better than first but nmap appears to
76
+ # put OSes in chronological order, at least for Windows.
77
+ # Accordingly, this will report XP instead of 2000, 7 instead of
78
+ # Vista, etc, when each has the same accuracy.
79
+ if (@host["os_accuracy"].to_i <= attributes["accuracy"].to_i)
80
+ @host["os_vendor"] = attributes["vendor"]
81
+ @host["os_family"] = attributes["osfamily"]
82
+ @host["os_version"] = attributes["osgen"]
83
+ @host["os_accuracy"] = attributes["accuracy"]
84
+ end
77
85
  when "osmatch"
78
86
  if(attributes["accuracy"].to_i == 100)
79
87
  @host["os_match"] = attributes["name"]
@@ -96,7 +96,15 @@ Separator = "\\"
96
96
  def File.stat(name)
97
97
  return client.fs.filestat.new(name)
98
98
  end
99
-
99
+
100
+ #
101
+ # Determines if a file exists and returns true/false
102
+ #
103
+ def File.exists?(name)
104
+ r = client.fs.filestat.new(name) rescue nil
105
+ r ? true : false
106
+ end
107
+
100
108
  #
101
109
  # Performs a delete on the specified file.
102
110
  #
@@ -1,4 +1,9 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__)))
2
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..','..','..','..','..', 'lib'))
3
+
4
+ require 'test/unit'
5
+ require 'rex'
6
+
2
7
  require 'railgun/api_constants.rb.ut'
3
8
  require 'railgun/buffer_item.rb.ut'
4
9
  require 'railgun/dll_function.rb.ut'
@@ -25,6 +25,8 @@
25
25
  require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_helper'
26
26
  require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_function'
27
27
  require 'rex/post/meterpreter/extensions/stdapi/railgun/buffer_item'
28
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
29
+ require 'rex/post/meterpreter/packet'
28
30
 
29
31
  module Rex
30
32
  module Post
@@ -299,8 +301,36 @@ class DLL
299
301
  end
300
302
  end
301
303
  #puts return_hash
302
- #puts "finished"
303
304
 
305
+ #puts "finished"
306
+ # puts("
307
+ #=== START of proccess_function_call snapshot ===
308
+ # {
309
+ # :platform => '#{@native == 'Q' ? 'x64/win64' : 'x86/win32'}',
310
+ # :name => '#{function.windows_name}',
311
+ # :params => #{function.params},
312
+ # :return_type => '#{function.return_type}',
313
+ # :dll_name => '#{@dll_path}',
314
+ # :ruby_args => #{args.inspect},
315
+ # :request_to_client => {
316
+ # TLV_TYPE_RAILGUN_SIZE_OUT => #{out_only_size_bytes},
317
+ # TLV_TYPE_RAILGUN_STACKBLOB => #{literal_pairs_blob.inspect},
318
+ # TLV_TYPE_RAILGUN_BUFFERBLOB_IN => #{in_only_buffer.inspect},
319
+ # TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => #{inout_buffer.inspect},
320
+ # TLV_TYPE_RAILGUN_DLLNAME => '#{@dll_path}',
321
+ # TLV_TYPE_RAILGUN_FUNCNAME => '#{function.windows_name}',
322
+ # },
323
+ # :response_from_client => {
324
+ # TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => #{rec_inout_buffers.inspect},
325
+ # TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => #{rec_out_only_buffers.inspect},
326
+ # TLV_TYPE_RAILGUN_BACK_RET => #{rec_return_value.inspect},
327
+ # TLV_TYPE_RAILGUN_BACK_ERR => #{rec_last_error},
328
+ # },
329
+ # :returned_hash => #{return_hash.inspect},
330
+ # },
331
+ #=== END of proccess_function_call snapshot ===
332
+ # ")
333
+ #
304
334
  return return_hash
305
335
  end
306
336
 
@@ -22,6 +22,8 @@
22
22
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
23
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
24
 
25
+ require 'rex/post/meterpreter/packet'
26
+
25
27
  module Rex
26
28
  module Post
27
29
  module Meterpreter
@@ -219,6 +219,38 @@ class UI < Rex::Post::UI
219
219
  return response.get_tlv_value(TLV_TYPE_KEYS_DUMP);
220
220
  end
221
221
 
222
+ #
223
+ # Extract the keystroke from the buffer data
224
+ #
225
+ def keyscan_extract(buffer_data)
226
+ outp = ""
227
+ buffer_data.unpack("n*").each do |inp|
228
+ fl = (inp & 0xff00) >> 8
229
+ vk = (inp & 0xff)
230
+ kc = VirtualKeyCodes[vk]
231
+
232
+ f_shift = fl & (1<<1)
233
+ f_ctrl = fl & (1<<2)
234
+ f_alt = fl & (1<<3)
235
+
236
+ if(kc)
237
+ name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
238
+ case name
239
+ when /^.$/
240
+ outp << name
241
+ when /shift|click/i
242
+ when 'Space'
243
+ outp << " "
244
+ else
245
+ outp << " <#{name}> "
246
+ end
247
+ else
248
+ outp << " <0x%.2x> " % vk
249
+ end
250
+ end
251
+ return outp
252
+ end
253
+
222
254
  protected
223
255
  attr_accessor :client # :nodoc:
224
256
 
@@ -80,6 +80,8 @@ class Console
80
80
  #
81
81
  def interact_with_channel(channel)
82
82
  channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
83
+ channel.on_command_proc = self.on_command_proc if self.on_command_proc
84
+ channel.on_print_proc = self.on_print_proc if self.on_print_proc
83
85
 
84
86
  channel.interact(input, output)
85
87
  channel.reset_ui
@@ -36,6 +36,11 @@ module Console::CommandDispatcher
36
36
  @@file_hash[name] = klass
37
37
  end
38
38
 
39
+ def initialize(shell)
40
+ @msf_loaded = nil
41
+ super
42
+ end
43
+
39
44
  #
40
45
  # Returns the meterpreter client context.
41
46
  #
@@ -43,6 +48,24 @@ module Console::CommandDispatcher
43
48
  shell.client
44
49
  end
45
50
 
51
+ #
52
+ # Returns true if the client has a framework object.
53
+ #
54
+ # Used for firing framework session events
55
+ #
56
+ def msf_loaded?
57
+ return @msf_loaded unless @msf_loaded.nil?
58
+ # if we get here we must not have initialized yet
59
+
60
+ if client.framework
61
+ # We have a framework instance so the msf libraries should be
62
+ # available. Load up the ones we're going to use
63
+ require 'msf/base/serializer/readable_text'
64
+ end
65
+ @msf_loaded = !!(client.framework)
66
+ @msf_loaded
67
+ end
68
+
46
69
  #
47
70
  # Log that an error occurred.
48
71
  #
@@ -59,4 +82,4 @@ end
59
82
  end
60
83
  end
61
84
  end
62
- end
85
+ end
@@ -27,23 +27,9 @@ class Console::CommandDispatcher::Core
27
27
  self.bgjobs = []
28
28
  self.bgjob_id = 0
29
29
 
30
- @msf_loaded = nil
31
30
  end
32
31
 
33
- def msf_loaded?
34
- return @msf_loaded unless @msf_loaded.nil?
35
- # if we get here we must not have initialized yet
36
-
37
- if client.framework
38
- # We have a framework instance so the msf libraries should be
39
- # available. Load up the ones we're going to use
40
- require 'msf/base/serializer/readable_text'
41
- end
42
- @msf_loaded = !!(client.framework)
43
- @msf_loaded
44
- end
45
-
46
- @@use_opts = Rex::Parser::Arguments.new(
32
+ @@load_opts = Rex::Parser::Arguments.new(
47
33
  "-l" => [ false, "List all available extensions" ],
48
34
  "-h" => [ false, "Help menu." ])
49
35
 
@@ -61,7 +47,8 @@ class Console::CommandDispatcher::Core
61
47
  "interact" => "Interacts with a channel",
62
48
  "irb" => "Drop into irb scripting mode",
63
49
  "migrate" => "Migrate the server to another process",
64
- "use" => "Load a one or more meterpreter extensions",
50
+ "use" => "Deprecated alias for 'load'",
51
+ "load" => "Load one or more meterpreter extensions",
65
52
  "quit" => "Terminate the meterpreter session",
66
53
  "resource" => "Run the commands stored in a file",
67
54
  "read" => "Reads data from a channel",
@@ -85,6 +72,13 @@ class Console::CommandDispatcher::Core
85
72
  "Core"
86
73
  end
87
74
 
75
+ def cmd_background_help
76
+ print_line "Usage: background"
77
+ print_line
78
+ print_line "Stop interacting with this session and return to the parent prompt"
79
+ print_line
80
+ end
81
+
88
82
  def cmd_background
89
83
  client.interacting = false
90
84
  end
@@ -93,37 +87,61 @@ class Console::CommandDispatcher::Core
93
87
  # Displays information about active channels
94
88
  #
95
89
  @@channel_opts = Rex::Parser::Arguments.new(
90
+ "-c" => [ true, "Close the given channel." ],
91
+ "-i" => [ true, "Interact with the given channel." ],
96
92
  "-l" => [ false, "List active channels." ],
97
- "-h" => [ false, "Help menu." ])
93
+ "-r" => [ true, "Read from the given channel." ],
94
+ "-w" => [ true, "Write to the given channel." ],
95
+ "-h" => [ false, "Help menu." ])
96
+
97
+ def cmd_channel_help
98
+ print_line "Usage: channel [options]"
99
+ print_line
100
+ print_line "Displays information about active channels."
101
+ print_line @@channel_opts.usage
102
+ end
98
103
 
99
104
  #
100
105
  # Performs operations on the supplied channel.
101
106
  #
102
107
  def cmd_channel(*args)
103
- if (args.length == 0)
104
- args.unshift("-h")
108
+ if args.include?("-h") or args.include?("--help")
109
+ cmd_channel_help
110
+ return
105
111
  end
106
112
 
107
113
  mode = nil
114
+ chan = nil
115
+ data = []
108
116
 
109
117
  # Parse options
110
118
  @@channel_opts.parse(args) { |opt, idx, val|
111
119
  case opt
112
- when "-h"
113
- print(
114
- "Usage: channel [options]\n\n" +
115
- "Displays information about active channels.\n" +
116
- @@channel_opts.usage)
117
- return true
118
- when "-l"
119
- mode = 'list'
120
+ when "-l"
121
+ mode = :list
122
+ when "-c"
123
+ mode = :close
124
+ chan = val
125
+ when "-i"
126
+ mode = :interact
127
+ chan = val
128
+ when "-r"
129
+ mode = :read
130
+ chan = val
131
+ when "-w"
132
+ mode = :write
133
+ chan = val
134
+ end
135
+ if @@channel_opts.arg_required?(opt)
136
+ unless chan
137
+ print_error("Channel ID required")
138
+ return
139
+ end
120
140
  end
121
141
  }
122
142
 
123
- # No mode, no service.
124
- if (mode == nil)
125
- return true
126
- elsif (mode == 'list')
143
+ case mode
144
+ when :list
127
145
  tbl = Rex::Ui::Text::Table.new(
128
146
  'Indent' => 4,
129
147
  'Columns' =>
@@ -144,6 +162,17 @@ class Console::CommandDispatcher::Core
144
162
  else
145
163
  print("\n" + tbl.to_s + "\n")
146
164
  end
165
+ when :close
166
+ cmd_close(chan)
167
+ when :interact
168
+ cmd_interact(chan)
169
+ when :read
170
+ cmd_read(chan)
171
+ when :write
172
+ cmd_write(chan)
173
+ else
174
+ # No mode, no service.
175
+ return true
147
176
  end
148
177
  end
149
178
 
@@ -239,17 +268,24 @@ class Console::CommandDispatcher::Core
239
268
  print_status("Migration completed successfully.")
240
269
  end
241
270
 
271
+ def cmd_load_help
272
+ print_line("Usage: load ext1 ext2 ext3 ...")
273
+ print_line
274
+ print_line "Loads a meterpreter extension module or modules."
275
+ print_line @@load_opts.usage
276
+ end
277
+
242
278
  #
243
279
  # Loads one or more meterpreter extensions.
244
280
  #
245
- def cmd_use(*args)
281
+ def cmd_load(*args)
246
282
  if (args.length == 0)
247
283
  args.unshift("-h")
248
284
  end
249
285
 
250
286
  modules = nil
251
287
 
252
- @@use_opts.parse(args) { |opt, idx, val|
288
+ @@load_opts.parse(args) { |opt, idx, val|
253
289
  case opt
254
290
  when "-l"
255
291
  exts = []
@@ -263,10 +299,7 @@ class Console::CommandDispatcher::Core
263
299
 
264
300
  return true
265
301
  when "-h"
266
- print(
267
- "Usage: use ext1 ext2 ext3 ...\n\n" +
268
- "Loads a meterpreter extension module or modules.\n" +
269
- @@use_opts.usage)
302
+ cmd_load_help
270
303
  return true
271
304
  end
272
305
  }
@@ -299,7 +332,7 @@ class Console::CommandDispatcher::Core
299
332
  return true
300
333
  end
301
334
 
302
- def cmd_use_tabs(str, words)
335
+ def cmd_load_tabs(str, words)
303
336
  tabs = []
304
337
  path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
305
338
  ::Dir.entries(path).each { |f|
@@ -312,6 +345,13 @@ class Console::CommandDispatcher::Core
312
345
  return tabs
313
346
  end
314
347
 
348
+ def cmd_use(*args)
349
+ #print_error("Warning: The 'use' command is deprecated in favor of 'load'")
350
+ cmd_load(*args)
351
+ end
352
+ alias cmd_use_help cmd_load_help
353
+ alias cmd_use_tabs cmd_load_tabs
354
+
315
355
  #
316
356
  # Reads data from a channel.
317
357
  #
@@ -487,6 +527,13 @@ class Console::CommandDispatcher::Core
487
527
  end
488
528
  end
489
529
 
530
+ def cmd_info_help
531
+ print_line 'Usage: info <module>'
532
+ print_line
533
+ print_line 'Prints information about a post-exploitation module'
534
+ print_line
535
+ end
536
+
490
537
  #
491
538
  # Show info for a given Post module.
492
539
  #
@@ -495,8 +542,8 @@ class Console::CommandDispatcher::Core
495
542
  def cmd_info(*args)
496
543
  return unless msf_loaded?
497
544
 
498
- if args.length != 1
499
- print_error 'Usage: info <module>'
545
+ if args.length != 1 or args.include?("-h")
546
+ cmd_info_help
500
547
  return
501
548
  end
502
549
 
@@ -524,9 +571,17 @@ class Console::CommandDispatcher::Core
524
571
  "-f" => [ true, "Write the contents of a file on disk" ],
525
572
  "-h" => [ false, "Help menu." ])
526
573
 
574
+ def cmd_write_help
575
+ print_line "Usage: write [options] channel_id"
576
+ print_line
577
+ print_line "Writes data to the supplied channel."
578
+ print_line @@write_opts.usage
579
+ end
580
+
527
581
  def cmd_write(*args)
528
- if (args.length == 0)
529
- args.unshift("-h")
582
+ if (args.length == 0 or args.include?("-h"))
583
+ cmd_write_help
584
+ return
530
585
  end
531
586
 
532
587
  src_file = nil
@@ -534,12 +589,6 @@ class Console::CommandDispatcher::Core
534
589
 
535
590
  @@write_opts.parse(args) { |opt, idx, val|
536
591
  case opt
537
- when "-h"
538
- print(
539
- "Usage: write [options] channel_id\n\n" +
540
- "Writes data to the supplied channel.\n" +
541
- @@write_opts.usage)
542
- return true
543
592
  when "-f"
544
593
  src_file = val
545
594
  else
@@ -225,10 +225,12 @@ class Console::CommandDispatcher::Stdapi::Fs
225
225
  if (stat.directory?)
226
226
  client.fs.dir.download(dest, src, recursive, true) { |step, src, dst|
227
227
  print_status("#{step.ljust(11)}: #{src} -> #{dst}")
228
+ client.framework.events.on_session_download(client, src, dest) if msf_loaded?
228
229
  }
229
230
  elsif (stat.file?)
230
231
  client.fs.file.download(dest, src) { |step, src, dst|
231
232
  print_status("#{step.ljust(11)}: #{src} -> #{dst}")
233
+ client.framework.events.on_session_download(client, src, dest) if msf_loaded?
232
234
  }
233
235
  end
234
236
  }
@@ -417,10 +419,12 @@ class Console::CommandDispatcher::Stdapi::Fs
417
419
  if (stat.directory?)
418
420
  client.fs.dir.upload(dest, src, recursive) { |step, src, dst|
419
421
  print_status("#{step.ljust(11)}: #{src} -> #{dst}")
422
+ client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
420
423
  }
421
424
  elsif (stat.file?)
422
425
  client.fs.file.upload(dest, src) { |step, src, dst|
423
426
  print_status("#{step.ljust(11)}: #{src} -> #{dst}")
427
+ client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
424
428
  }
425
429
  end
426
430
  }
@@ -51,7 +51,7 @@ class Console::CommandDispatcher::Stdapi::Sys
51
51
  "execute" => "Execute a command",
52
52
  "getpid" => "Get the current process identifier",
53
53
  "getuid" => "Get the user that the server is running as",
54
- "getprivs" => "Get as many privileges as possible",
54
+ "getprivs" => "List all privileges available to the current process",
55
55
  "kill" => "Terminate a process",
56
56
  "ps" => "List running processes",
57
57
  "reboot" => "Reboots the remote computer",
@@ -277,32 +277,7 @@ class Console::CommandDispatcher::Stdapi::Ui
277
277
  def cmd_keyscan_dump(*args)
278
278
  print_line("Dumping captured keystrokes...")
279
279
  data = client.ui.keyscan_dump
280
- outp = ""
281
- data.unpack("n*").each do |inp|
282
- fl = (inp & 0xff00) >> 8
283
- vk = (inp & 0xff)
284
- kc = VirtualKeyCodes[vk]
285
-
286
- f_shift = fl & (1<<1)
287
- f_ctrl = fl & (1<<2)
288
- f_alt = fl & (1<<3)
289
-
290
- if(kc)
291
- name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
292
- case name
293
- when /^.$/
294
- outp << name
295
- when /shift|click/i
296
- when 'Space'
297
- outp << " "
298
- else
299
- outp << " <#{name}> "
300
- end
301
- else
302
- outp << " <0x%.2x> " % vk
303
- end
304
- end
305
- print_line(outp)
280
+ print_line(client.ui.keyscan_extract(data))
306
281
 
307
282
  return true
308
283
  end
@@ -68,6 +68,8 @@ module Console::InteractiveChannel
68
68
  def _stream_read_local_write_remote(channel)
69
69
  data = user_input.gets
70
70
  return if not data
71
+
72
+ self.on_command_proc.call(data.strip) if self.on_command_proc
71
73
  self.write(data)
72
74
  end
73
75
 
@@ -77,6 +79,7 @@ module Console::InteractiveChannel
77
79
  def _stream_read_remote_write_local(channel)
78
80
  data = self.lsock.sysread(16384)
79
81
 
82
+ self.on_print_proc.call(data.strip) if self.on_print_proc
80
83
  user_output.print(data)
81
84
  end
82
85
 
@@ -226,7 +226,6 @@ class Socks4a
226
226
  @rsock = nil
227
227
  @client_thread = nil
228
228
  @mutex = ::Mutex.new
229
- @closed = false
230
229
  end
231
230
 
232
231
  #
@@ -248,8 +247,9 @@ class Socks4a
248
247
  params = {
249
248
  'PeerHost' => request.dest_ip,
250
249
  'PeerPort' => request.dest_port,
251
- 'Comm' => @server.opts['Comm']
252
250
  }
251
+ params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
252
+
253
253
  @rsock = Rex::Socket::Tcp.create( params )
254
254
  # and send back success to the client
255
255
  response = Packet.new
@@ -262,8 +262,8 @@ class Socks4a
262
262
  params = {
263
263
  'LocalHost' => '0.0.0.0',
264
264
  'LocalPort' => 0,
265
- 'Comm' => @server.opts['Comm']
266
265
  }
266
+ params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
267
267
  bsock = Rex::Socket::TcpServer.create( params )
268
268
  # send back the bind success to the client
269
269
  response = Packet.new
@@ -353,7 +353,7 @@ class Socks4a
353
353
  # Create a new Socks4a server.
354
354
  #
355
355
  def initialize( opts={} )
356
- @opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080, 'Comm' => nil }
356
+ @opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080 }
357
357
  @opts = @opts.merge( opts )
358
358
  @server = nil
359
359
  @clients = ::Array.new
@@ -373,7 +373,7 @@ class Socks4a
373
373
  #
374
374
  def start
375
375
  begin
376
- # create the servers main socket
376
+ # create the servers main socket (ignore the context here because we don't want a remote bind)
377
377
  @server = Rex::Socket::TcpServer.create( 'LocalHost' => @opts['ServerHost'], 'LocalPort' => @opts['ServerPort'] )
378
378
  # signal we are now running
379
379
  @running = true
@@ -108,6 +108,9 @@ module Interactive
108
108
  #
109
109
  attr_accessor :completed
110
110
 
111
+ attr_accessor :on_print_proc
112
+ attr_accessor :on_command_proc
113
+
111
114
  protected
112
115
 
113
116
  #
@@ -148,6 +151,7 @@ protected
148
151
  def _stream_read_remote_write_local(stream)
149
152
  data = stream.get
150
153
 
154
+ self.on_print_proc.call(data) if self.on_print_proc
151
155
  user_output.print(data)
152
156
  end
153
157
 
@@ -157,6 +161,7 @@ protected
157
161
  def _stream_read_local_write_remote(stream)
158
162
  data = user_input.gets
159
163
 
164
+ self.on_command_proc.call(data) if self.on_command_proc
160
165
  stream.put(data)
161
166
  end
162
167
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: librex
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.28
5
+ version: 0.0.29
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-04-11 00:00:00 -05:00
14
+ date: 2011-04-19 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 12292
18
+ description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision 12371
19
19
  email:
20
20
  - hdm@metasploit.com
21
21
  - jacob.hammack@hammackj.com