librex 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/README +4 -0
  2. data/lib/rex/exploitation/cmdstager.rb +9 -133
  3. data/lib/rex/exploitation/cmdstager/base.rb +170 -0
  4. data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
  5. data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
  6. data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
  7. data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
  8. data/lib/rex/io/stream.rb +2 -2
  9. data/lib/rex/io/stream_server.rb +1 -1
  10. data/lib/rex/job_container.rb +7 -6
  11. data/lib/rex/mime/header.rb +12 -10
  12. data/lib/rex/mime/message.rb +57 -26
  13. data/lib/rex/ole/directory.rb +5 -4
  14. data/lib/rex/ole/samples/create_ole.rb +0 -0
  15. data/lib/rex/ole/samples/dir.rb +0 -0
  16. data/lib/rex/ole/samples/dump_stream.rb +1 -1
  17. data/lib/rex/ole/samples/ole_info.rb +0 -0
  18. data/lib/rex/parser/nexpose_xml.rb +131 -0
  19. data/lib/rex/parser/nmap_xml.rb +1 -0
  20. data/lib/rex/peparsey/pe.rb +21 -3
  21. data/lib/rex/post/meterpreter/client.rb +6 -1
  22. data/lib/rex/post/meterpreter/client_core.rb +2 -2
  23. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +19 -18
  24. data/lib/rex/post/meterpreter/packet.rb +68 -0
  25. data/lib/rex/post/meterpreter/packet_dispatcher.rb +2 -2
  26. data/lib/rex/post/meterpreter/packet_response_waiter.rb +5 -5
  27. data/lib/rex/post/meterpreter/ui/console.rb +2 -0
  28. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +5 -2
  29. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +2 -2
  30. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -0
  31. data/lib/rex/proto/http/client.rb +8 -3
  32. data/lib/rex/proto/http/packet.rb +11 -1
  33. data/lib/rex/proto/smb/client.rb +1 -1
  34. data/lib/rex/proto/smb/utils.rb +72 -24
  35. data/lib/rex/proto/tftp.rb +3 -0
  36. data/lib/rex/proto/tftp/constants.rb +37 -0
  37. data/lib/rex/proto/tftp/server.rb +249 -0
  38. data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
  39. data/lib/rex/script/meterpreter.rb +6 -0
  40. data/lib/rex/services/local_relay.rb +2 -2
  41. data/lib/rex/socket/ip.rb +9 -8
  42. data/lib/rex/socket/range_walker.rb +43 -5
  43. data/lib/rex/socket/udp.rb +11 -4
  44. data/lib/rex/text.rb +42 -19
  45. data/lib/rex/ui/interactive.rb +24 -22
  46. data/lib/rex/ui/text/irb_shell.rb +4 -2
  47. data/lib/rex/ui/text/output/file.rb +6 -0
  48. data/lib/rex/ui/text/shell.rb +14 -18
  49. data/lib/rex/zip/samples/comment.rb +0 -0
  50. data/lib/rex/zip/samples/mkwar.rb +0 -0
  51. data/lib/rex/zip/samples/mkzip.rb +0 -0
  52. data/lib/rex/zip/samples/recursive.rb +0 -0
  53. metadata +20 -5
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # $Revision: 9333 $
4
+ #
5
+ # $Id: server.rb.ut.rb 9333 2010-05-21 00:03:04Z jduck $
6
+ #
7
+
8
+ require 'rex/compat'
9
+ require 'rex/proto/tftp'
10
+
11
+ content = nil
12
+
13
+ fn = ARGV.shift
14
+ if (fn and fn.length > 0)
15
+ File.open(fn, "rb") do |fd|
16
+ content = fd.read(fd.stat.size)
17
+ end
18
+ end
19
+
20
+ content ||= "A" * (1024*1024)
21
+
22
+
23
+ tftp = Rex::Proto::TFTP::Server.new
24
+ tftp.register_file("poo", content)
25
+ tftp.start
26
+
27
+ #loop { break if not tftp.thread.alive? }
28
+ tftp.thread.join
@@ -3,6 +3,12 @@ module Rex
3
3
  module Script
4
4
  class Meterpreter < Base
5
5
 
6
+ begin
7
+ require 'msf/scripts/meterpreter'
8
+ include Msf::Scripts::Meterpreter::Common
9
+ rescue ::LoadError
10
+ end
11
+
6
12
  end
7
13
  end
8
14
  end
@@ -370,7 +370,7 @@ protected
370
370
 
371
371
  # Poll all the streams...
372
372
  begin
373
- socks = select(rfds, nil, nil, 0.25)
373
+ socks = Rex::ThreadSafe.select(rfds, nil, nil, 0.25)
374
374
  rescue StreamClosedError => e
375
375
  dlog("monitor_relays: closing stream #{e.stream}", 'rex', LEV_3)
376
376
 
@@ -384,7 +384,7 @@ protected
384
384
 
385
385
  next
386
386
  rescue
387
- elog("Error in #{self} monitor_relays select: #{$!}", 'rex')
387
+ elog("Error in #{self} monitor_relays select: #{$!.class} #{$!}", 'rex')
388
388
  return
389
389
  end
390
390
 
data/lib/rex/socket/ip.rb CHANGED
@@ -19,7 +19,7 @@ module Rex::Socket::Ip
19
19
  # Creates the client using the supplied hash.
20
20
  #
21
21
  def self.create(hash = {})
22
- hash['Proto'] = 'ip'
22
+ hash['Proto'] = 'ip'
23
23
  self.create_param(Rex::Socket::Parameters.from_hash(hash))
24
24
  end
25
25
 
@@ -65,7 +65,7 @@ module Rex::Socket::Ip
65
65
  #
66
66
  def sendto(gram, peerhost, flags = 0)
67
67
  dest = ::Socket.pack_sockaddr_in(0, peerhost)
68
-
68
+
69
69
  # Some BSDs require byteswap for len and offset
70
70
  if(
71
71
  Rex::Compat.is_freebsd or
@@ -82,8 +82,8 @@ module Rex::Socket::Ip
82
82
  send(gram, flags, dest)
83
83
  rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
84
84
  return nil
85
- end
86
-
85
+ end
86
+
87
87
  end
88
88
 
89
89
  #
@@ -92,7 +92,7 @@ module Rex::Socket::Ip
92
92
  #
93
93
  def recvfrom(length = 65535, timeout=def_read_timeout)
94
94
  begin
95
- if ((rv = Kernel.select([ fd ], nil, nil, timeout)) and
95
+ if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
96
96
  (rv[0]) and (rv[0][0] == fd)
97
97
  )
98
98
  data, saddr = super(length)
@@ -106,7 +106,7 @@ module Rex::Socket::Ip
106
106
  return [ '', nil ]
107
107
  end
108
108
  end
109
-
109
+
110
110
  #
111
111
  # Calls recvfrom and only returns the data
112
112
  #
@@ -114,16 +114,17 @@ module Rex::Socket::Ip
114
114
  data, saddr = recvfrom(65535, timeout)
115
115
  return data
116
116
  end
117
-
117
+
118
118
  #
119
119
  # The default number of seconds to wait for a read operation to timeout.
120
120
  #
121
121
  def def_read_timeout
122
122
  10
123
- end
123
+ end
124
124
 
125
125
  def type?
126
126
  return 'ip'
127
127
  end
128
128
 
129
129
  end
130
+
@@ -27,20 +27,46 @@ class RangeWalker
27
27
  reset
28
28
  end
29
29
 
30
+ #
31
+ # Calls the instance method
32
+ #
33
+ # This is basically only useful for determining if a range can be parsed
34
+ #
30
35
  def self.parse(parseme)
31
36
  self.new.parse(parseme)
32
37
  end
33
38
 
39
+ #
40
+ # Turn a human-readable range string into ranges we can step through one address at a time.
41
+ #
42
+ # Allow the following formats:
43
+ # "a.b.c.d e.f.g.h"
44
+ # "a.b.c.d, e.f.g.h"
45
+ # where each chunk is CIDR notation, (e.g. '10.1.1.0/24') or a range in nmap format (see expand_nmap)
46
+ #
47
+ # OR this format
48
+ # "a.b.c.d-e.f.g.h"
49
+ # where a.b.c.d and e.f.g.h are single IPs and the second must be
50
+ # bigger than the first.
51
+ #
34
52
  def parse(parseme)
35
53
  return nil if not parseme
36
54
  ranges = []
37
- parseme.split(' ').each { |arg|
55
+ parseme.split(', ').map{ |a| a.split(' ') }.flatten.each { |arg|
38
56
  if arg.include?("/")
39
57
  # Then it's CIDR notation and needs special case
40
- if arg =~ /[,-]/
41
- # Improper CIDR notation (can't mix with 1,3 or 1-3 style IP ranges)
42
- return false
58
+ return false if arg =~ /[,-]/ # Improper CIDR notation (can't mix with 1,3 or 1-3 style IP ranges)
59
+ return false if arg.scan("/").size > 1 # ..but there are too many slashes
60
+ ip_part,mask_part = arg.split("/")
61
+ return false if ip_part.nil? or ip_part.empty? or mask_part.nil? or mask_part.empty?
62
+ return false if mask_part !~ /^[0-9]{1,2}$/ # Illegal mask -- numerals only
63
+ return false if mask_part.to_i > 32 # This too -- between 0 and 32.
64
+ begin
65
+ Rex::Socket.addr_atoi(ip_part) # This allows for "www.metasploit.com/24" which is fun.
66
+ rescue Resolv::ResolvError
67
+ return false # Can't resolve the ip_part, so bail.
43
68
  end
69
+
44
70
  expanded = expand_cidr(arg)
45
71
  if expanded
46
72
  ranges += expanded
@@ -58,6 +84,16 @@ class RangeWalker
58
84
  # unmolested to force a DNS lookup.
59
85
  addr = Rex::Socket.addr_atoi(arg)
60
86
  ranges.push [addr, addr]
87
+ elsif arg =~ /^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)-([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$/
88
+ # Then it's in the format of 1.2.3.4-5.6.7.8
89
+ # Note, this will /not/ deal with DNS names, or the fancy/obscure 10...1-10...2
90
+ begin
91
+ addrs = [Rex::Socket.addr_atoi($1), Rex::Socket.addr_atoi($2)]
92
+ return false if addrs[0] > addrs[1] # The end is greater than the beginning.
93
+ ranges.push [addrs[0], addrs[1]]
94
+ rescue Resolv::ResolvError # Something's broken, forget it.
95
+ return false
96
+ end
61
97
  else
62
98
  expanded = expand_nmap(arg)
63
99
  if expanded
@@ -274,14 +310,16 @@ class RangeWalker
274
310
  #
275
311
  # The total number of IPs within the range
276
312
  #
277
- attr_reader :ranges
278
313
  attr_reader :length
279
314
 
280
315
  # for backwards compatibility
281
316
  alias :num_ips :length
282
317
 
318
+ attr_reader :ranges
319
+
283
320
  end
284
321
 
322
+ # :nodoc:
285
323
  class Range < Array
286
324
  def start; self[0]; end
287
325
  def stop; self[1]; end
@@ -72,7 +72,7 @@ module Rex::Socket::Udp
72
72
  #
73
73
  def timed_read(length = 65535, timeout=def_read_timeout)
74
74
  begin
75
- if ((rv = Kernel.select([ fd ], nil, nil, timeout)) and
75
+ if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
76
76
  (rv[0]) and (rv[0][0] == fd)
77
77
  )
78
78
  return read(length)
@@ -101,7 +101,10 @@ module Rex::Socket::Udp
101
101
  # Catch unconnected IPv6 sockets talking to IPv4 addresses
102
102
  peer = Rex::Socket.resolv_nbo(peerhost)
103
103
  if (peer.length == 4 and self.ipv == 6)
104
- peerhost = '::ffff:' + Rex::Socket.getaddress(peerhost)
104
+ peerhost = Rex::Socket.getaddress(peerhost)
105
+ if peerhost[0,7].downcase != '::ffff:'
106
+ peerhost = '::ffff:' + peerhost
107
+ end
105
108
  end
106
109
 
107
110
  begin
@@ -119,7 +122,7 @@ module Rex::Socket::Udp
119
122
  def recvfrom(length = 65535, timeout=def_read_timeout)
120
123
 
121
124
  begin
122
- if ((rv = Kernel.select([ fd ], nil, nil, timeout)) and
125
+ if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
123
126
  (rv[0]) and (rv[0][0] == fd)
124
127
  )
125
128
  data, saddr = recvfrom_nonblock(length)
@@ -129,7 +132,11 @@ module Rex::Socket::Udp
129
132
  else
130
133
  return [ '', nil, nil ]
131
134
  end
132
- rescue Exception
135
+ rescue ::Timeout::Error
136
+ return [ '', nil, nil ]
137
+ rescue ::Interrupt
138
+ raise $!
139
+ rescue ::Exception
133
140
  return [ '', nil, nil ]
134
141
  end
135
142
  end
data/lib/rex/text.rb CHANGED
@@ -39,6 +39,10 @@ module Text
39
39
  AllChars = [*(0x00 .. 0xff)].pack("C*")
40
40
 
41
41
  DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
42
+
43
+ # In case Iconv isn't loaded
44
+ Iconv_EBCDIC = ["\x00", "\x01", "\x02", "\x03", "7", "-", ".", "/", "\x16", "\x05", "%", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13", "<", "=", "2", "&", "\x18", "\x19", "?", "'", "\x1C", "\x1D", "\x1E", "\x1F", "@", "Z", "\x7F", "{", "[", "l", "P", "}", "M", "]", "\\", "N", "k", "`", "K", "a", "\xF0", "\xF1", "\xF2", "\xF3", "\xF4", "\xF5", "\xF6", "\xF7", "\xF8", "\xF9", "z", "^", "L", "~", "n", "o", "|", "\xC1", "\xC2", "\xC3", "\xC4", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xD1", "\xD2", "\xD3", "\xD4", "\xD5", "\xD6", "\xD7", "\xD8", "\xD9", "\xE2", "\xE3", "\xE4", "\xE5", "\xE6", "\xE7", "\xE8", "\xE9", nil, "\xE0", nil, nil, "m", "y", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87", "\x88", "\x89", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97", "\x98", "\x99", "\xA2", "\xA3", "\xA4", "\xA5", "\xA6", "\xA7", "\xA8", "\xA9", "\xC0", "O", "\xD0", "\xA1", "\a", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
45
+ Iconv_ASCII = ["\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\a", "\b", "\t", "\n", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1A", "\e", "\x1C", "\x1D", "\x1E", "\x1F", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", nil, "\\", nil, nil, "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\x7F", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
42
46
 
43
47
  ##
44
48
  #
@@ -139,13 +143,43 @@ module Text
139
143
  #
140
144
  # Converts ASCII to EBCDIC
141
145
  #
146
+ class IllegalSequence < ArgumentError; end
147
+
148
+ # A native implementation of the ASCII->EBCDIC table, used to fall back from using
149
+ # Iconv
150
+ def self.to_ebcdic_rex(str)
151
+ new_str = []
152
+ str.each_byte do |x|
153
+ if Iconv_ASCII.index(x.chr)
154
+ new_str << Iconv_EBCDIC[Iconv_ASCII.index(x.chr)]
155
+ else
156
+ raise Rex::Text::IllegalSequence, ("\\x%x" % x)
157
+ end
158
+ end
159
+ new_str.join
160
+ end
161
+
162
+ # A native implementation of the EBCDIC->ASCII table, used to fall back from using
163
+ # Iconv
164
+ def self.from_ebcdic_rex(str)
165
+ new_str = []
166
+ str.each_byte do |x|
167
+ if Iconv_EBCDIC.index(x.chr)
168
+ new_str << Iconv_ASCII[Iconv_EBCDIC.index(x.chr)]
169
+ else
170
+ raise Rex::Text::IllegalSequence, ("\\x%x" % x)
171
+ end
172
+ end
173
+ new_str.join
174
+ end
175
+
142
176
  def self.to_ebcdic(str)
143
177
  begin
144
178
  Iconv.iconv("EBCDIC-US", "ASCII", str).first
145
179
  rescue ::Iconv::IllegalSequence => e
146
180
  raise e
147
181
  rescue
148
- raise ::RuntimeError, "Your installation does not support iconv (needed for EBCDIC conversion)"
182
+ self.to_ebcdic_rex(str)
149
183
  end
150
184
  end
151
185
 
@@ -158,7 +192,7 @@ module Text
158
192
  rescue ::Iconv::IllegalSequence => e
159
193
  raise e
160
194
  rescue
161
- raise ::RuntimeError, "Your installation does not support iconv (needed for EBCDIC conversion)"
195
+ self.from_ebcdic_rex(str)
162
196
  end
163
197
  end
164
198
 
@@ -463,7 +497,7 @@ module Text
463
497
  coords = []
464
498
  (1 << str.size).times { |i| coords << ("%0#{str.size}b" % i) }
465
499
  mixed = []
466
- coords.each do |coord|
500
+ coords.each do |coord|
467
501
  c = coord.scan(/./).map {|x| x.to_i}
468
502
  this_str = ""
469
503
  c.each_with_index { |d,i| this_str << letters[i][d] }
@@ -626,22 +660,11 @@ module Text
626
660
 
627
661
  # Base text generator method
628
662
  def self.rand_base(len, bad, *foo)
629
- # Remove restricted characters
630
- (bad || '').split('').each { |c| foo.delete(c) }
631
-
632
- # Return nil if all bytes are restricted
633
- return nil if foo.length == 0
634
-
635
- buff = ""
636
-
637
- # Generate a buffer from the remaining bytes
638
- if foo.length >= 256
639
- len.times { buff << Kernel.rand(256) }
640
- else
641
- len.times { buff << foo[ rand(foo.length) ] }
642
- end
643
-
644
- return buff
663
+ cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq
664
+ return if cset.length == 0
665
+ outp = []
666
+ len.times { outp << cset[rand(cset.length)] }
667
+ outp.pack("C*")
645
668
  end
646
669
 
647
670
  # Generate random bytes of data
@@ -16,12 +16,12 @@ module Interactive
16
16
  include Rex::Ui::Subscriber
17
17
 
18
18
  #
19
- # Starts interacting with the session at the most raw level, simply
19
+ # Starts interacting with the session at the most raw level, simply
20
20
  # forwarding input from user_input to rstream and forwarding input from
21
21
  # rstream to user_output.
22
22
  #
23
23
  def interact(user_input, user_output)
24
-
24
+
25
25
  # Detach from any existing console
26
26
  if(self.interacting)
27
27
  detach()
@@ -34,13 +34,13 @@ module Interactive
34
34
 
35
35
  eof = false
36
36
 
37
- # Start the readline stdin monitor
37
+ # Start the readline stdin monitor
38
38
  # XXX disabled
39
39
  # user_input.readline_start() if user_input.supports_readline
40
-
40
+
41
41
  # Handle suspend notifications
42
42
  handle_suspend
43
-
43
+
44
44
  # As long as we're interacting...
45
45
  while (self.interacting == true)
46
46
 
@@ -52,18 +52,18 @@ module Interactive
52
52
  # abort the interaction. If they do, then we return out of
53
53
  # the interact function and call it a day.
54
54
  eof = true if (_interrupt)
55
-
55
+
56
56
  rescue EOFError, Errno::ECONNRESET, IOError
57
57
  # If we reach EOF or the connection is reset...
58
58
  eof = true
59
-
59
+
60
60
  end
61
61
 
62
62
  break if eof
63
63
  end
64
64
 
65
65
  begin
66
-
66
+
67
67
  # Restore the suspend handler
68
68
  restore_suspend
69
69
 
@@ -73,10 +73,10 @@ module Interactive
73
73
  # Shutdown the readline thread
74
74
  # XXX disabled
75
75
  # user_input.readline_stop() if user_input.supports_readline
76
-
76
+
77
77
  # Detach from the input/output handles
78
78
  reset_ui()
79
-
79
+
80
80
  ensure
81
81
  # Mark this as completed
82
82
  self.completed = true
@@ -93,7 +93,7 @@ module Interactive
93
93
  if (self.interacting)
94
94
  self.interacting = false
95
95
  while(not self.completed)
96
- select(nil, nil, nil, 0.25)
96
+ ::IO.select(nil, nil, nil, 0.25)
97
97
  end
98
98
  end
99
99
  end
@@ -102,14 +102,14 @@ module Interactive
102
102
  # Whether or not the session is currently being interacted with
103
103
  #
104
104
  attr_accessor :interacting
105
-
105
+
106
106
  #
107
107
  # Whether or not the session has completed interaction
108
108
  #
109
109
  attr_accessor :completed
110
110
 
111
111
  protected
112
-
112
+
113
113
  #
114
114
  # The original suspend proc.
115
115
  #
@@ -156,7 +156,7 @@ protected
156
156
  #
157
157
  def _stream_read_local_write_remote(stream)
158
158
  data = user_input.gets
159
-
159
+
160
160
  stream.put(data)
161
161
  end
162
162
 
@@ -180,10 +180,10 @@ protected
180
180
  #
181
181
  def interact_stream(stream)
182
182
  while self.interacting
183
-
183
+
184
184
  # Select input and rstream
185
185
  sd = Rex::ThreadSafe.select([ _local_fd, _remote_fd(stream) ], nil, nil, 0.25)
186
-
186
+
187
187
  # Cycle through the items that have data
188
188
  # From the stream? Write to user_output.
189
189
  sd[0].each { |s|
@@ -194,7 +194,7 @@ protected
194
194
  _stream_read_local_write_remote(stream)
195
195
  end
196
196
  } if (sd)
197
-
197
+
198
198
  Thread.pass
199
199
  end
200
200
  end
@@ -218,13 +218,14 @@ protected
218
218
  # notifications.
219
219
  #
220
220
  def restore_suspend
221
- if (orig_suspend)
222
- begin
221
+ begin
222
+ if (orig_suspend)
223
223
  Signal.trap("TSTP", orig_suspend)
224
- rescue
224
+ else
225
+ Signal.trap("TSTP", "DEFAULT")
225
226
  end
226
-
227
227
  self.orig_suspend = nil
228
+ rescue
228
229
  end
229
230
  end
230
231
 
@@ -238,7 +239,7 @@ protected
238
239
  user_input.sysread(2)
239
240
  end
240
241
  end
241
-
242
+
242
243
  #
243
244
  # Check the return value of a yes/no prompt
244
245
  #
@@ -250,3 +251,4 @@ end
250
251
 
251
252
  end
252
253
  end
254
+