librex 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/lib/rex/exploitation/cmdstager.rb +9 -133
- data/lib/rex/exploitation/cmdstager/base.rb +170 -0
- data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
- data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
- data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
- data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
- data/lib/rex/io/stream.rb +2 -2
- data/lib/rex/io/stream_server.rb +1 -1
- data/lib/rex/job_container.rb +7 -6
- data/lib/rex/mime/header.rb +12 -10
- data/lib/rex/mime/message.rb +57 -26
- data/lib/rex/ole/directory.rb +5 -4
- data/lib/rex/ole/samples/create_ole.rb +0 -0
- data/lib/rex/ole/samples/dir.rb +0 -0
- data/lib/rex/ole/samples/dump_stream.rb +1 -1
- data/lib/rex/ole/samples/ole_info.rb +0 -0
- data/lib/rex/parser/nexpose_xml.rb +131 -0
- data/lib/rex/parser/nmap_xml.rb +1 -0
- data/lib/rex/peparsey/pe.rb +21 -3
- data/lib/rex/post/meterpreter/client.rb +6 -1
- data/lib/rex/post/meterpreter/client_core.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +19 -18
- data/lib/rex/post/meterpreter/packet.rb +68 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +2 -2
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +5 -5
- data/lib/rex/post/meterpreter/ui/console.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +5 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +2 -2
- data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -0
- data/lib/rex/proto/http/client.rb +8 -3
- data/lib/rex/proto/http/packet.rb +11 -1
- data/lib/rex/proto/smb/client.rb +1 -1
- data/lib/rex/proto/smb/utils.rb +72 -24
- data/lib/rex/proto/tftp.rb +3 -0
- data/lib/rex/proto/tftp/constants.rb +37 -0
- data/lib/rex/proto/tftp/server.rb +249 -0
- data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
- data/lib/rex/script/meterpreter.rb +6 -0
- data/lib/rex/services/local_relay.rb +2 -2
- data/lib/rex/socket/ip.rb +9 -8
- data/lib/rex/socket/range_walker.rb +43 -5
- data/lib/rex/socket/udp.rb +11 -4
- data/lib/rex/text.rb +42 -19
- data/lib/rex/ui/interactive.rb +24 -22
- data/lib/rex/ui/text/irb_shell.rb +4 -2
- data/lib/rex/ui/text/output/file.rb +6 -0
- data/lib/rex/ui/text/shell.rb +14 -18
- data/lib/rex/zip/samples/comment.rb +0 -0
- data/lib/rex/zip/samples/mkwar.rb +0 -0
- data/lib/rex/zip/samples/mkzip.rb +0 -0
- data/lib/rex/zip/samples/recursive.rb +0 -0
- 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
|
@@ -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 =
|
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
|
-
|
42
|
-
|
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
|
data/lib/rex/socket/udp.rb
CHANGED
@@ -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 =
|
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 =
|
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 =
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
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
|
data/lib/rex/ui/interactive.rb
CHANGED
@@ -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
|
-
|
222
|
-
|
221
|
+
begin
|
222
|
+
if (orig_suspend)
|
223
223
|
Signal.trap("TSTP", orig_suspend)
|
224
|
-
|
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
|
+
|