librex 0.0.28 → 0.0.29

Sign up to get free protection for your applications and to get access to all the features.
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