librex 0.0.29 → 0.0.30
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +1 -1
- data/lib/rex/io/ring_buffer.rb +3 -3
- data/lib/rex/io/stream.rb +12 -8
- data/lib/rex/io/stream_abstraction.rb +10 -7
- data/lib/rex/job_container.rb +12 -0
- data/lib/rex/parser/apple_backup_manifestdb.rb +131 -0
- data/lib/rex/parser/nexpose_xml.rb +4 -0
- data/lib/rex/post/meterpreter/client.rb +26 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +8 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb +175 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +3 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +21 -11
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +15 -1
- data/lib/rex/proto/dhcp/constants.rb +2 -1
- data/lib/rex/proto/dhcp/server.rb +34 -2
- data/lib/rex/proto/http/header.rb +12 -0
- data/lib/rex/proto/proxy/socks4a.rb +1 -2
- data/lib/rex/proto/smb/constants.rb +0 -1
- data/lib/rex/service_manager.rb +13 -1
- data/lib/rex/socket/comm/local.rb +1 -1
- data/lib/rex/socket/ssl_tcp.rb +129 -13
- data/lib/rex/socket/ssl_tcp_server.rb +31 -2
- data/lib/rex/socket/switch_board.rb +6 -0
- metadata +5 -3
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:
|
6
|
+
SVN Revision: 12516
|
7
7
|
|
8
8
|
# Credits
|
9
9
|
The Metasploit development team <http://www.metasploit.com>
|
data/lib/rex/io/ring_buffer.rb
CHANGED
@@ -54,7 +54,7 @@ class RingBuffer
|
|
54
54
|
end
|
55
55
|
|
56
56
|
#
|
57
|
-
# The built-in monitor thread
|
57
|
+
# The built-in monitor thread (normally unused with Metasploit)
|
58
58
|
#
|
59
59
|
def monitor_thread
|
60
60
|
Thread.new do
|
@@ -74,8 +74,8 @@ class RingBuffer
|
|
74
74
|
# Push data back into the associated stream socket. Logging must occur
|
75
75
|
# elsewhere, this function is simply a passthrough.
|
76
76
|
#
|
77
|
-
def put(data)
|
78
|
-
self.fd.put(data)
|
77
|
+
def put(data, opts={})
|
78
|
+
self.fd.put(data, opts={})
|
79
79
|
end
|
80
80
|
|
81
81
|
#
|
data/lib/rex/io/stream.rb
CHANGED
@@ -35,20 +35,20 @@ module Stream
|
|
35
35
|
total_sent = 0
|
36
36
|
total_length = buf.length
|
37
37
|
block_size = 32768
|
38
|
+
|
38
39
|
begin
|
39
40
|
while( total_sent < total_length )
|
40
41
|
s = Rex::ThreadSafe.select( nil, [ fd ], nil, 0.2 )
|
41
42
|
if( s == nil || s[0] == nil )
|
42
43
|
next
|
43
44
|
end
|
44
|
-
data = buf[
|
45
|
+
data = buf[total_sent, block_size]
|
45
46
|
sent = fd.write_nonblock( data )
|
46
47
|
if sent > 0
|
47
48
|
total_sent += sent
|
48
|
-
buf[0, sent] = ""
|
49
49
|
end
|
50
50
|
end
|
51
|
-
rescue ::Errno::EAGAIN
|
51
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
52
52
|
# Sleep for a half a second, or until we can write again
|
53
53
|
Rex::ThreadSafe.select( nil, [ fd ], nil, 0.5 )
|
54
54
|
# Decrement the block size to handle full sendQs better
|
@@ -57,8 +57,8 @@ module Stream
|
|
57
57
|
retry
|
58
58
|
rescue ::IOError, ::Errno::EPIPE
|
59
59
|
return nil if (fd.abortive_close == true)
|
60
|
-
raise $!
|
61
60
|
end
|
61
|
+
|
62
62
|
total_sent
|
63
63
|
end
|
64
64
|
|
@@ -66,12 +66,16 @@ module Stream
|
|
66
66
|
# This method reads data of the supplied length from the stream.
|
67
67
|
#
|
68
68
|
def read(length = nil, opts = {})
|
69
|
-
|
69
|
+
|
70
70
|
begin
|
71
|
-
fd.
|
72
|
-
rescue ::
|
71
|
+
return fd.read_nonblock( length )
|
72
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
73
|
+
# Sleep for a half a second, or until we can read again
|
74
|
+
Rex::ThreadSafe.select( [ fd ], nil, nil, 0.5 )
|
75
|
+
# Decrement the block size to handle full sendQs better
|
76
|
+
retry
|
77
|
+
rescue ::IOError, ::Errno::EPIPE
|
73
78
|
return nil if (fd.abortive_close == true)
|
74
|
-
raise $!
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
@@ -68,19 +68,19 @@ module StreamAbstraction
|
|
68
68
|
end
|
69
69
|
|
70
70
|
#
|
71
|
-
#
|
71
|
+
# Low-level write to the local side.
|
72
72
|
#
|
73
73
|
def syswrite(buffer)
|
74
74
|
lsock.syswrite(buffer)
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
#
|
78
|
-
#
|
78
|
+
# Low-level read from the local side.
|
79
79
|
#
|
80
80
|
def sysread(length)
|
81
81
|
lsock.sysread(length)
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
#
|
85
85
|
# Shuts down the local side of the stream abstraction.
|
86
86
|
#
|
@@ -160,15 +160,18 @@ protected
|
|
160
160
|
total_length = buf.length
|
161
161
|
while( total_sent < total_length )
|
162
162
|
begin
|
163
|
-
data = buf[
|
163
|
+
data = buf[total_sent, buf.length]
|
164
|
+
|
165
|
+
# Note that this must be write() NOT syswrite() or put() or anything like it.
|
166
|
+
# Using syswrite() breaks SSL streams.
|
164
167
|
sent = self.write( data )
|
165
|
-
|
168
|
+
|
169
|
+
# sf: Only remove the data off the queue is write was successfull.
|
166
170
|
# This way we naturally perform a resend if a failure occured.
|
167
171
|
# Catches an edge case with meterpreter TCP channels where remote send
|
168
172
|
# failes gracefully and a resend is required.
|
169
173
|
if( sent > 0 )
|
170
174
|
total_sent += sent
|
171
|
-
buf[0, sent] = ""
|
172
175
|
end
|
173
176
|
rescue ::IOError => e
|
174
177
|
closed = true
|
data/lib/rex/job_container.rb
CHANGED
@@ -177,6 +177,18 @@ class JobContainer < Hash
|
|
177
177
|
self.delete(inst.jid.to_s)
|
178
178
|
end
|
179
179
|
|
180
|
+
#
|
181
|
+
# Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+
|
182
|
+
# "can't add a new key into hash during iteration"
|
183
|
+
#
|
184
|
+
def each(&block)
|
185
|
+
list = []
|
186
|
+
self.keys.sort.each do |sidx|
|
187
|
+
list << [sidx, self[sidx]]
|
188
|
+
end
|
189
|
+
list.each(&block)
|
190
|
+
end
|
191
|
+
|
180
192
|
protected
|
181
193
|
|
182
194
|
attr_accessor :job_id_pool # :nodoc:
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#
|
2
|
+
# This is a Ruby port of the Python manifest parsing code posted to:
|
3
|
+
# http://stackoverflow.com/questions/3085153/how-to-parse-the-manifest-mbdb-file-in-an-ios-4-0-itunes-backup/3130860#3130860
|
4
|
+
#
|
5
|
+
|
6
|
+
module Rex
|
7
|
+
module Parser
|
8
|
+
class AppleBackupManifestDB
|
9
|
+
|
10
|
+
attr_accessor :entry_offsets
|
11
|
+
attr_accessor :entries
|
12
|
+
attr_accessor :mbdb, :mbdx
|
13
|
+
attr_accessor :mbdb_data, :mbdx_data
|
14
|
+
attr_accessor :mbdb_offset, :mbdx_offset
|
15
|
+
|
16
|
+
def initialize(mbdb_data, mbdx_data)
|
17
|
+
self.entries = {}
|
18
|
+
self.entry_offsets = {}
|
19
|
+
self.mbdb_data = mbdb_data
|
20
|
+
self.mbdx_data = mbdx_data
|
21
|
+
parse_mbdb
|
22
|
+
parse_mbdx
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_files(mbdb_file, mbdx_file)
|
26
|
+
mbdb_data = ""
|
27
|
+
::File.open(mbdb_file, "rb") {|fd| mbdb_data = fd.read(fd.stat.size) }
|
28
|
+
mbdx_data = ""
|
29
|
+
::File.open(mbdx_file, "rb") {|fd| mbdx_data = fd.read(fd.stat.size) }
|
30
|
+
|
31
|
+
self.new(mbdb_data, mbdx_data)
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_mbdb
|
35
|
+
raise ArgumentError, "Not valid MBDB data" if self.mbdb_data[0,4] != "mbdb"
|
36
|
+
self.mbdb_offset = 4
|
37
|
+
self.mbdb_offset = self.mbdb_offset + 2 # Maps to \x05 \x00 (unknown)
|
38
|
+
|
39
|
+
while self.mbdb_offset < self.mbdb_data.length
|
40
|
+
info = {}
|
41
|
+
info[:start_offset] = self.mbdb_offset
|
42
|
+
info[:domain] = mbdb_read_string
|
43
|
+
info[:filename] = mbdb_read_string
|
44
|
+
info[:linktarget] = mbdb_read_string
|
45
|
+
info[:datahash] = mbdb_read_string
|
46
|
+
info[:unknown1] = mbdb_read_string
|
47
|
+
info[:mode] = mbdb_read_int(2)
|
48
|
+
info[:unknown2] = mbdb_read_int(4)
|
49
|
+
info[:unknown3] = mbdb_read_int(4)
|
50
|
+
info[:uid] = mbdb_read_int(4)
|
51
|
+
info[:gid] = mbdb_read_int(4)
|
52
|
+
info[:mtime] = Time.at(mbdb_read_int(4))
|
53
|
+
info[:atime] = Time.at(mbdb_read_int(4))
|
54
|
+
info[:ctime] = Time.at(mbdb_read_int(4))
|
55
|
+
info[:length] = mbdb_read_int(8)
|
56
|
+
info[:flag] = mbdb_read_int(1)
|
57
|
+
property_count = mbdb_read_int(1)
|
58
|
+
info[:properties] = {}
|
59
|
+
1.upto(property_count) do |i|
|
60
|
+
k = mbdb_read_string
|
61
|
+
v = mbdb_read_string
|
62
|
+
info[:properties][k] = v
|
63
|
+
end
|
64
|
+
self.entry_offsets[ info[:start_offset] ] = info
|
65
|
+
end
|
66
|
+
self.mbdb_data = ""
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_mbdx
|
70
|
+
raise ArgumentError, "Not a valid MBDX file" if self.mbdx_data[0,4] != "mbdx"
|
71
|
+
|
72
|
+
self.mbdx_offset = 4
|
73
|
+
self.mbdx_offset = self.mbdx_offset + 2 # Maps to \x02 \x00 (unknown)
|
74
|
+
|
75
|
+
file_count = mbdx_read_int(4)
|
76
|
+
|
77
|
+
while self.mbdx_offset < self.mbdx_data.length
|
78
|
+
file_id = self.mbdx_data[self.mbdx_offset, 20].unpack("C*").map{|c| "%02x" % c}.join
|
79
|
+
self.mbdx_offset += 20
|
80
|
+
entry_offset = mbdx_read_int(4) + 6
|
81
|
+
mode = mbdx_read_int(2)
|
82
|
+
entry = entry_offsets[ entry_offset ]
|
83
|
+
# May be corrupted if there is no matching entry, but what to do about it?
|
84
|
+
next if not entry
|
85
|
+
self.entries[file_id] = entry.merge({:mbdx_mode => mode, :file_id => file_id})
|
86
|
+
end
|
87
|
+
self.mbdx_data = ""
|
88
|
+
end
|
89
|
+
|
90
|
+
def mbdb_read_string
|
91
|
+
raise RuntimeError, "Corrupted MBDB file" if self.mbdb_offset > self.mbdb_data.length
|
92
|
+
len = self.mbdb_data[self.mbdb_offset, 2].unpack("n")[0]
|
93
|
+
self.mbdb_offset += 2
|
94
|
+
return '' if len == 65535
|
95
|
+
val = self.mbdb_data[self.mbdb_offset, len]
|
96
|
+
self.mbdb_offset += len
|
97
|
+
return val
|
98
|
+
end
|
99
|
+
|
100
|
+
def mbdb_read_int(size)
|
101
|
+
val = 0
|
102
|
+
size.downto(1) do |i|
|
103
|
+
val = (val << 8) + self.mbdb_data[self.mbdb_offset, 1].unpack("C")[0]
|
104
|
+
self.mbdb_offset += 1
|
105
|
+
end
|
106
|
+
val
|
107
|
+
end
|
108
|
+
|
109
|
+
def mbdx_read_string
|
110
|
+
raise RuntimeError, "Corrupted MBDX file" if self.mbdx_offset > self.mbdx_data.length
|
111
|
+
len = self.mbdx_data[self.mbdx_offset, 2].unpack("n")[0]
|
112
|
+
self.mbdx_offset += 2
|
113
|
+
return '' if len == 65535
|
114
|
+
val = self.mbdx_data[self.mbdx_offset, len]
|
115
|
+
self.mbdx_offset += len
|
116
|
+
return val
|
117
|
+
end
|
118
|
+
|
119
|
+
def mbdx_read_int(size)
|
120
|
+
val = 0
|
121
|
+
size.downto(1) do |i|
|
122
|
+
val = (val << 8) + self.mbdx_data[self.mbdx_offset, 1].unpack("C")[0]
|
123
|
+
self.mbdx_offset += 1
|
124
|
+
end
|
125
|
+
val
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
@@ -51,6 +51,10 @@ class NexposeXMLStreamParser
|
|
51
51
|
when "test"
|
52
52
|
if attributes["status"] == "vulnerable-exploited" or attributes["status"] == "vulnerable-version"
|
53
53
|
@host["vulns"][attributes["id"]] = attributes.dup
|
54
|
+
if attributes["key"]
|
55
|
+
@host["notes"] ||= []
|
56
|
+
@host["notes"] << [attributes["id"], attributes["key"]]
|
57
|
+
end
|
54
58
|
end
|
55
59
|
when "vulnerability"
|
56
60
|
@vuln.merge! attributes
|
@@ -128,7 +128,32 @@ class Client
|
|
128
128
|
ctx = generate_ssl_context()
|
129
129
|
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
130
130
|
|
131
|
-
ssl.
|
131
|
+
if not ssl.respond_to?(:accept_nonblock)
|
132
|
+
ssl.accept
|
133
|
+
else
|
134
|
+
begin
|
135
|
+
ssl.accept_nonblock
|
136
|
+
|
137
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
138
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
139
|
+
IO::select(nil, nil, nil, 0.10)
|
140
|
+
retry
|
141
|
+
|
142
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
143
|
+
rescue ::Exception => e
|
144
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
145
|
+
IO::select( [ ssl ], nil, nil, 0.10 )
|
146
|
+
retry
|
147
|
+
end
|
148
|
+
|
149
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
150
|
+
IO::select( nil, [ ssl ], nil, 0.10 )
|
151
|
+
retry
|
152
|
+
end
|
153
|
+
|
154
|
+
raise e
|
155
|
+
end
|
156
|
+
end
|
132
157
|
|
133
158
|
self.sock.extend(Rex::Socket::SslTcp)
|
134
159
|
self.sock.sslsock = ssl
|
@@ -72,12 +72,14 @@ class Priv < Extension
|
|
72
72
|
if( response.result == 0 and technique != nil )
|
73
73
|
client.core.use( "stdapi" ) if not client.ext.aliases.include?( "stdapi" )
|
74
74
|
client.sys.config.getprivs
|
75
|
-
client.framework.db.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
75
|
+
if client.framework.db and client.framework.db.active
|
76
|
+
client.framework.db.report_note(
|
77
|
+
:host => client.sock.peerhost,
|
78
|
+
:workspace => client.framework.db.workspace,
|
79
|
+
:type => "meterpreter.getsystem",
|
80
|
+
:data => {:technique => technique}
|
81
|
+
) rescue nil
|
82
|
+
end
|
81
83
|
return [ true, technique ]
|
82
84
|
end
|
83
85
|
|
@@ -0,0 +1,175 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib'))
|
4
|
+
|
5
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll'
|
6
|
+
require 'test/unit'
|
7
|
+
|
8
|
+
module Rex
|
9
|
+
module Post
|
10
|
+
module Meterpreter
|
11
|
+
module Extensions
|
12
|
+
module Stdapi
|
13
|
+
module Railgun
|
14
|
+
class DLL::UnitTest < Test::Unit::TestCase
|
15
|
+
|
16
|
+
TLV_TYPE_NAMES = {
|
17
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => "TLV_TYPE_RAILGUN_SIZE_OUT",
|
18
|
+
TLV_TYPE_RAILGUN_STACKBLOB => "TLV_TYPE_RAILGUN_STACKBLOB",
|
19
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "TLV_TYPE_RAILGUN_BUFFERBLOB_IN",
|
20
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT",
|
21
|
+
TLV_TYPE_RAILGUN_DLLNAME => "TLV_TYPE_RAILGUN_DLLNAME",
|
22
|
+
TLV_TYPE_RAILGUN_FUNCNAME => "TLV_TYPE_RAILGUN_FUNCNAME",
|
23
|
+
}
|
24
|
+
|
25
|
+
class MockRailgunClient
|
26
|
+
attr_reader :platform, :check_request, :response_tlvs
|
27
|
+
|
28
|
+
def initialize(platform, response_tlvs, check_request)
|
29
|
+
@check_request = check_request
|
30
|
+
@response_tlvs = response_tlvs
|
31
|
+
@platform = platform
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_request(request)
|
35
|
+
check_request.call(request)
|
36
|
+
|
37
|
+
(Class.new do
|
38
|
+
def initialize(response_tlvs)
|
39
|
+
@response_tlvs = response_tlvs
|
40
|
+
end
|
41
|
+
def get_tlv_value(type)
|
42
|
+
return @response_tlvs[type]
|
43
|
+
end
|
44
|
+
end).new(@response_tlvs)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def make_mock_client(platform = "x86/win32", target_request_tlvs = [], response_tlvs = [])
|
49
|
+
check_request = lambda do |request|
|
50
|
+
target_request_tlvs.each_pair do |type, target_value|
|
51
|
+
assert_equal(target_value, request.get_tlv_value(type),
|
52
|
+
"process_function_call should send to client appropriate #{TLV_TYPE_NAMES[type]}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
return MockRailgunClient.new(platform, response_tlvs, check_request)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_add_function
|
60
|
+
function_descriptions.each do |func|
|
61
|
+
dll = DLL.new(func[:dll_name], make_mock_client(func[:platform]), nil)
|
62
|
+
dll.add_function(func[:name], func[:return_type], func[:params])
|
63
|
+
|
64
|
+
assert(dll.functions.has_key?(func[:name]),
|
65
|
+
"add_function should expand the list of available functions")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_method_missing
|
70
|
+
function_descriptions.each do |func|
|
71
|
+
client = make_mock_client(func[:platform], func[:request_to_client], func[:response_from_client])
|
72
|
+
dll = DLL.new(func[:dll_name], client, nil)
|
73
|
+
|
74
|
+
dll.add_function(func[:name], func[:return_type], func[:params])
|
75
|
+
|
76
|
+
actual_returned_hash = dll.send(:method_missing, func[:name].to_sym, *func[:ruby_args])
|
77
|
+
|
78
|
+
assert(func[:returned_hash].has_key?('GetLastError'),
|
79
|
+
"process_function_call should add the result of GetLastError to the key GetLastError")
|
80
|
+
|
81
|
+
assert_equal(func[:returned_hash], actual_returned_hash,
|
82
|
+
"process_function_call convert function result to a ruby hash")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# These are sample descriptions of functions to use for testing.
|
87
|
+
def function_descriptions
|
88
|
+
[
|
89
|
+
{
|
90
|
+
:platform => "x86/win32",
|
91
|
+
:name => "LookupAccountSidA",
|
92
|
+
:params => [
|
93
|
+
["PCHAR","lpSystemName","in"],
|
94
|
+
["LPVOID","Sid","in"],
|
95
|
+
["PCHAR","Name","out"],
|
96
|
+
["PDWORD","cchName","inout"],
|
97
|
+
["PCHAR","ReferencedDomainName","out"],
|
98
|
+
["PDWORD","cchReferencedDomainName","inout"],
|
99
|
+
["PBLOB","peUse","out"],
|
100
|
+
],
|
101
|
+
:return_type => "BOOL",
|
102
|
+
:dll_name => "advapi32",
|
103
|
+
:ruby_args => [nil, 1371864, 100, 100, 100, 100, 1],
|
104
|
+
:request_to_client => {
|
105
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
106
|
+
TLV_TYPE_RAILGUN_STACKBLOB => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD8\xEE\x14\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00d\x00\x00\x00\x03\x00\x00\x00\b\x00\x00\x00\x02\x00\x00\x00\xC8\x00\x00\x00",
|
107
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
108
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
109
|
+
TLV_TYPE_RAILGUN_DLLNAME => "advapi32",
|
110
|
+
TLV_TYPE_RAILGUN_FUNCNAME => "LookupAccountSidA"
|
111
|
+
},
|
112
|
+
:response_from_client => {
|
113
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
114
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
115
|
+
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
116
|
+
TLV_TYPE_RAILGUN_BACK_ERR => 997
|
117
|
+
},
|
118
|
+
:returned_hash => {
|
119
|
+
"GetLastError" => 997,
|
120
|
+
"return" => true,
|
121
|
+
"Name" => "SYSTEM",
|
122
|
+
"ReferencedDomainName" => "NT AUTHORITY",
|
123
|
+
"peUse" => "\x05",
|
124
|
+
"cchName" => 6,
|
125
|
+
"cchReferencedDomainName" => 12
|
126
|
+
},
|
127
|
+
},
|
128
|
+
{
|
129
|
+
:platform => 'x64/win64',
|
130
|
+
:name => 'LookupAccountSidA',
|
131
|
+
:params => [
|
132
|
+
["PCHAR", "lpSystemName", "in"],
|
133
|
+
["LPVOID", "Sid", "in"],
|
134
|
+
["PCHAR", "Name", "out"],
|
135
|
+
["PDWORD", "cchName", "inout"],
|
136
|
+
["PCHAR", "ReferencedDomainName", "out"],
|
137
|
+
["PDWORD", "cchReferencedDomainName", "inout"],
|
138
|
+
["PBLOB", "peUse", "out"]
|
139
|
+
],
|
140
|
+
:return_type => 'BOOL',
|
141
|
+
:dll_name => 'advapi32',
|
142
|
+
:ruby_args => [nil, 1631552, 100, 100, 100, 100, 1],
|
143
|
+
:request_to_client => {
|
144
|
+
TLV_TYPE_RAILGUN_SIZE_OUT => 201,
|
145
|
+
TLV_TYPE_RAILGUN_STACKBLOB => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xE5\x18\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xC8\x00\x00\x00\x00\x00\x00\x00",
|
146
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_IN => "",
|
147
|
+
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => "d\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00",
|
148
|
+
TLV_TYPE_RAILGUN_DLLNAME => 'advapi32',
|
149
|
+
TLV_TYPE_RAILGUN_FUNCNAME => 'LookupAccountSidA',
|
150
|
+
},
|
151
|
+
:response_from_client => {
|
152
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => "\x06\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00",
|
153
|
+
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => "SYSTEM\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANT AUTHORITY\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x05",
|
154
|
+
TLV_TYPE_RAILGUN_BACK_RET => 1,
|
155
|
+
TLV_TYPE_RAILGUN_BACK_ERR => 0,
|
156
|
+
},
|
157
|
+
:returned_hash => {
|
158
|
+
"GetLastError"=>0,
|
159
|
+
"return"=>true,
|
160
|
+
"Name"=>"SYSTEM",
|
161
|
+
"ReferencedDomainName"=>"NT AUTHORITY",
|
162
|
+
"peUse"=>"\x05",
|
163
|
+
"cchName"=>6,
|
164
|
+
"cchReferencedDomainName"=>12
|
165
|
+
},
|
166
|
+
},
|
167
|
+
]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -555,7 +555,9 @@ class Console::CommandDispatcher::Core
|
|
555
555
|
end
|
556
556
|
|
557
557
|
if (mod)
|
558
|
-
print_line
|
558
|
+
print_line(::Msf::Serializer::ReadableText.dump_module(mod))
|
559
|
+
mod_opt = ::Msf::Serializer::ReadableText.dump_options(mod, ' ')
|
560
|
+
print_line("\nModule options (#{mod.fullname}):\n\n#{mod_opt}") if (mod_opt and mod_opt.length > 0)
|
559
561
|
end
|
560
562
|
end
|
561
563
|
|
@@ -21,11 +21,13 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
21
21
|
# Options for the download command.
|
22
22
|
#
|
23
23
|
@@download_opts = Rex::Parser::Arguments.new(
|
24
|
+
"-h" => [ false, "Help banner." ],
|
24
25
|
"-r" => [ false, "Download recursively." ])
|
25
26
|
#
|
26
27
|
# Options for the upload command.
|
27
28
|
#
|
28
29
|
@@upload_opts = Rex::Parser::Arguments.new(
|
30
|
+
"-h" => [ false, "Help banner." ],
|
29
31
|
"-r" => [ false, "Upload recursively." ])
|
30
32
|
|
31
33
|
#
|
@@ -179,17 +181,21 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
179
181
|
end
|
180
182
|
|
181
183
|
alias :cmd_del :cmd_rm
|
184
|
+
|
185
|
+
def cmd_download_help
|
186
|
+
print_line "Usage: download [options] src1 src2 src3 ... destination"
|
187
|
+
print_line
|
188
|
+
print_line "Downloads remote files and directories to the local machine."
|
189
|
+
print_line @@download_opts.usage
|
190
|
+
end
|
182
191
|
|
183
192
|
#
|
184
193
|
# Downloads a file or directory from the remote machine to the local
|
185
194
|
# machine.
|
186
195
|
#
|
187
196
|
def cmd_download(*args)
|
188
|
-
if (args.empty?)
|
189
|
-
|
190
|
-
"Usage: download [options] src1 src2 src3 ... destination\n\n" +
|
191
|
-
"Downloads remote files and directories to the local machine.\n" +
|
192
|
-
@@download_opts.usage)
|
197
|
+
if (args.empty? or args.include? "-h")
|
198
|
+
cmd_download_help
|
193
199
|
return true
|
194
200
|
end
|
195
201
|
|
@@ -361,7 +367,7 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
361
367
|
# Removes one or more directory if it's empty.
|
362
368
|
#
|
363
369
|
def cmd_rmdir(*args)
|
364
|
-
if (args.length == 0)
|
370
|
+
if (args.length == 0 or args.include?("-h"))
|
365
371
|
print_line("Usage: rmdir dir1 dir2 dir3 ...")
|
366
372
|
return true
|
367
373
|
end
|
@@ -374,16 +380,20 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
374
380
|
return true
|
375
381
|
end
|
376
382
|
|
383
|
+
def cmd_upload_help
|
384
|
+
print_line "Usage: upload [options] src1 src2 src3 ... destination"
|
385
|
+
print_line
|
386
|
+
print_line "Uploads local files and directories to the remote machine."
|
387
|
+
print_line @@upload_opts.usage
|
388
|
+
end
|
389
|
+
|
377
390
|
#
|
378
391
|
# Uploads a file or directory to the remote machine from the local
|
379
392
|
# machine.
|
380
393
|
#
|
381
394
|
def cmd_upload(*args)
|
382
|
-
if (args.empty?)
|
383
|
-
|
384
|
-
"Usage: upload [options] src1 src2 src3 ... destination\n\n" +
|
385
|
-
"Uploads local files and directories to the remote machine.\n" +
|
386
|
-
@@upload_opts.usage)
|
395
|
+
if (args.empty? or args.include?("-h"))
|
396
|
+
cmd_upload_help
|
387
397
|
return true
|
388
398
|
end
|
389
399
|
|
@@ -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" => "
|
54
|
+
"getprivs" => "Attempt to enable 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",
|
@@ -421,10 +421,24 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
421
421
|
client.sys.config.revert_to_self
|
422
422
|
end
|
423
423
|
|
424
|
+
def cmd_getprivs_help
|
425
|
+
print_line "Usage: getprivs"
|
426
|
+
print_line
|
427
|
+
print_line "Attempt to enable all privileges, such as SeDebugPrivilege, available to the"
|
428
|
+
print_line "current process. Note that this only enables existing privs and does not change"
|
429
|
+
print_line "users or tokens."
|
430
|
+
print_line
|
431
|
+
print_line "See also: steal_token, getsystem"
|
432
|
+
print_line
|
433
|
+
end
|
434
|
+
|
424
435
|
#
|
425
436
|
# Obtains as many privileges as possible on the target machine.
|
426
437
|
#
|
427
438
|
def cmd_getprivs(*args)
|
439
|
+
if args.include? "-h"
|
440
|
+
cmd_getprivs_help
|
441
|
+
end
|
428
442
|
print_line("=" * 60)
|
429
443
|
print_line("Enabled Process Privileges")
|
430
444
|
print_line("=" * 60)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: constants.rb
|
1
|
+
# $Id: constants.rb 12375 2011-04-20 14:21:36Z jduck $
|
2
2
|
require 'rex/proto/dhcp'
|
3
3
|
|
4
4
|
module Rex
|
@@ -20,6 +20,7 @@ OpLeaseTime = 0x33
|
|
20
20
|
OpSubnetMask = 1
|
21
21
|
OpRouter = 3
|
22
22
|
OpDns = 6
|
23
|
+
OpHostname = 0x0c
|
23
24
|
OpEnd = 0xff
|
24
25
|
|
25
26
|
PXEMagic = "\xF1\x00\x74\x7E"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: server.rb
|
1
|
+
# $Id: server.rb 12471 2011-04-29 22:58:55Z scriptjunkie $
|
2
2
|
|
3
3
|
require 'rex/socket'
|
4
4
|
require 'rex/proto/dhcp'
|
@@ -12,6 +12,9 @@ module DHCP
|
|
12
12
|
# DHCP Server class
|
13
13
|
# not completely configurable - written specifically for a PXE server
|
14
14
|
# - scriptjunkie
|
15
|
+
#
|
16
|
+
# extended to support testing/exploiting CVE-2011-0997
|
17
|
+
# - apconole@yahoo.com
|
15
18
|
##
|
16
19
|
|
17
20
|
class Server
|
@@ -82,6 +85,17 @@ class Server
|
|
82
85
|
else
|
83
86
|
self.servePXE = false
|
84
87
|
end
|
88
|
+
|
89
|
+
# Always assume we don't give out hostnames ...
|
90
|
+
self.give_hostname = false
|
91
|
+
self.served_over = 0
|
92
|
+
if (hash['HOSTNAME'])
|
93
|
+
self.give_hostname = true
|
94
|
+
self.served_hostname = hash['HOSTNAME']
|
95
|
+
if ( hash['HOSTSTART'] )
|
96
|
+
self.served_over = hash['HOSTSTART'].to_i
|
97
|
+
end
|
98
|
+
end
|
85
99
|
|
86
100
|
self.leasetime = 600
|
87
101
|
self.relayip = "\x00\x00\x00\x00" # relay ip - not currently suported
|
@@ -116,7 +130,8 @@ class Server
|
|
116
130
|
def set_option(opts)
|
117
131
|
allowed_options = [
|
118
132
|
:serveOnce, :servePXE, :relayip, :leasetime, :dnsserv,
|
119
|
-
:pxeconfigfile, :pxepathprefix, :pxereboottime, :router
|
133
|
+
:pxeconfigfile, :pxepathprefix, :pxereboottime, :router,
|
134
|
+
:give_hostname, :served_hostname, :served_over
|
120
135
|
]
|
121
136
|
|
122
137
|
opts.each_pair { |k,v|
|
@@ -144,6 +159,7 @@ class Server
|
|
144
159
|
attr_accessor :sock, :thread, :myfilename, :ipstring, :served, :serveOnce
|
145
160
|
attr_accessor :current_ip, :start_ip, :end_ip, :broadcasta, :netmaskn
|
146
161
|
attr_accessor :servePXE, :pxeconfigfile, :pxepathprefix, :pxereboottime
|
162
|
+
attr_accessor :give_hostname, :served_hostname, :served_over
|
147
163
|
|
148
164
|
protected
|
149
165
|
|
@@ -263,6 +279,12 @@ protected
|
|
263
279
|
pkt << [DHCPAck].pack('C')
|
264
280
|
# now we ignore their discovers (but we'll respond to requests in case a packet was lost)
|
265
281
|
self.served.merge!( buf[28..43] => true )
|
282
|
+
if ( self.served_over != 0 )
|
283
|
+
# NOTE: this is sufficient for low-traffic net
|
284
|
+
# for high-traffic, this will probably lead to
|
285
|
+
# hostname collision
|
286
|
+
self.served_over += 1
|
287
|
+
end
|
266
288
|
else
|
267
289
|
#dlog("ignoring unknown DHCP request - type #{messageType}")
|
268
290
|
return
|
@@ -278,6 +300,16 @@ protected
|
|
278
300
|
pkt << dhcpoption(OpPXEConfigFile, self.pxeconfigfile)
|
279
301
|
pkt << dhcpoption(OpPXEPathPrefix, self.pxepathprefix)
|
280
302
|
pkt << dhcpoption(OpPXERebootTime, [self.pxereboottime].pack('N'))
|
303
|
+
if ( self.give_hostname == true )
|
304
|
+
send_hostname = self.served_hostname
|
305
|
+
if ( self.served_over != 0 )
|
306
|
+
# NOTE : see above comments for the 'uniqueness'
|
307
|
+
# of this value
|
308
|
+
send_hostname += self.served_over.to_s
|
309
|
+
end
|
310
|
+
pkt << dhcpoption(OpHostname, send_hostname)
|
311
|
+
end
|
312
|
+
|
281
313
|
pkt << dhcpoption(OpEnd)
|
282
314
|
|
283
315
|
pkt << ("\x00" * 32) #padding
|
@@ -141,6 +141,18 @@ class Packet::Header < Hash
|
|
141
141
|
self.dcase_hash.clear
|
142
142
|
end
|
143
143
|
|
144
|
+
#
|
145
|
+
# Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+
|
146
|
+
# "can't add a new key into hash during iteration"
|
147
|
+
#
|
148
|
+
def each(&block)
|
149
|
+
list = []
|
150
|
+
self.keys.sort.each do |sidx|
|
151
|
+
list << [sidx, self[sidx]]
|
152
|
+
end
|
153
|
+
list.each(&block)
|
154
|
+
end
|
155
|
+
|
144
156
|
#
|
145
157
|
# The raw command string associated with the header which will vary between
|
146
158
|
# requests and responses.
|
@@ -193,11 +193,10 @@ class Socks4a
|
|
193
193
|
total_length = buf.length
|
194
194
|
while( total_sent < total_length )
|
195
195
|
begin
|
196
|
-
data = buf[
|
196
|
+
data = buf[total_sent, buf.length]
|
197
197
|
sent = self.write( data )
|
198
198
|
if( sent > 0 )
|
199
199
|
total_sent += sent
|
200
|
-
buf[0, sent] = ""
|
201
200
|
end
|
202
201
|
rescue
|
203
202
|
closed = true
|
data/lib/rex/service_manager.rb
CHANGED
@@ -127,6 +127,18 @@ class ServiceManager < Hash
|
|
127
127
|
return false
|
128
128
|
end
|
129
129
|
|
130
|
+
#
|
131
|
+
# Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+
|
132
|
+
# "can't add a new key into hash during iteration"
|
133
|
+
#
|
134
|
+
def each(&block)
|
135
|
+
list = []
|
136
|
+
self.keys.sort.each do |sidx|
|
137
|
+
list << [sidx, self[sidx]]
|
138
|
+
end
|
139
|
+
list.each(&block)
|
140
|
+
end
|
141
|
+
|
130
142
|
protected
|
131
143
|
|
132
144
|
#
|
@@ -138,4 +150,4 @@ protected
|
|
138
150
|
|
139
151
|
end
|
140
152
|
|
141
|
-
end
|
153
|
+
end
|
data/lib/rex/socket/ssl_tcp.rb
CHANGED
@@ -14,9 +14,10 @@ begin
|
|
14
14
|
begin
|
15
15
|
require 'openssl'
|
16
16
|
@@loaded_openssl = true
|
17
|
+
require 'openssl/nonblock'
|
17
18
|
rescue ::Exception
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
|
21
22
|
include Rex::Socket::Tcp
|
22
23
|
|
@@ -55,12 +56,13 @@ begin
|
|
55
56
|
def initsock(params = nil)
|
56
57
|
super
|
57
58
|
|
58
|
-
|
59
59
|
version = :SSLv3
|
60
60
|
if(params)
|
61
61
|
case params.ssl_version
|
62
62
|
when 'SSL2'
|
63
63
|
version = :SSLv2
|
64
|
+
when 'SSL23'
|
65
|
+
version = :SSLv23
|
64
66
|
when 'TLS1'
|
65
67
|
version = :TLSv1
|
66
68
|
end
|
@@ -87,15 +89,40 @@ begin
|
|
87
89
|
|
88
90
|
# Tie the context to a socket
|
89
91
|
self.sslsock = OpenSSL::SSL::SSLSocket.new(self, self.sslctx)
|
90
|
-
|
92
|
+
|
91
93
|
# XXX - enabling this causes infinite recursion, so disable for now
|
92
94
|
# self.sslsock.sync_close = true
|
93
95
|
|
96
|
+
|
94
97
|
# Force a negotiation timeout
|
95
98
|
begin
|
96
99
|
Timeout.timeout(params.timeout) do
|
97
|
-
|
98
|
-
|
100
|
+
if not self.sslsock.respond_to?(:connect_nonblock)
|
101
|
+
self.sslsock.connect
|
102
|
+
else
|
103
|
+
begin
|
104
|
+
self.sslsock.connect_nonblock
|
105
|
+
|
106
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
107
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
108
|
+
IO::select(nil, nil, nil, 0.10)
|
109
|
+
retry
|
110
|
+
|
111
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
112
|
+
rescue ::Exception => e
|
113
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
114
|
+
IO::select( [ self.sslsock ], nil, nil, 0.10 )
|
115
|
+
retry
|
116
|
+
end
|
117
|
+
|
118
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
119
|
+
IO::select( nil, [ self.sslsock ], nil, 0.10 )
|
120
|
+
retry
|
121
|
+
end
|
122
|
+
|
123
|
+
raise e
|
124
|
+
end
|
125
|
+
end
|
99
126
|
end
|
100
127
|
|
101
128
|
rescue ::Timeout::Error
|
@@ -113,22 +140,111 @@ begin
|
|
113
140
|
# Writes data over the SSL socket.
|
114
141
|
#
|
115
142
|
def write(buf, opts = {})
|
116
|
-
return sslsock.write(buf)
|
143
|
+
return sslsock.write(buf) if not self.sslsock.respond_to?(:write_nonblock)
|
144
|
+
|
145
|
+
total_sent = 0
|
146
|
+
total_length = buf.length
|
147
|
+
block_size = 32768
|
148
|
+
|
149
|
+
begin
|
150
|
+
while( total_sent < total_length )
|
151
|
+
s = Rex::ThreadSafe.select( nil, [ self.sslsock ], nil, 0.25 )
|
152
|
+
if( s == nil || s[0] == nil )
|
153
|
+
next
|
154
|
+
end
|
155
|
+
data = buf[total_sent, block_size]
|
156
|
+
sent = sslsock.write_nonblock( data )
|
157
|
+
if sent > 0
|
158
|
+
total_sent += sent
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
rescue ::IOError, ::Errno::EPIPE
|
163
|
+
return nil if (fd.abortive_close == true)
|
164
|
+
|
165
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
166
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
167
|
+
# Sleep for a half a second, or until we can write again
|
168
|
+
Rex::ThreadSafe.select( nil, [ self.sslsock ], nil, 0.5 )
|
169
|
+
# Decrement the block size to handle full sendQs better
|
170
|
+
block_size = 1024
|
171
|
+
# Try to write the data again
|
172
|
+
retry
|
173
|
+
|
174
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
175
|
+
rescue ::Exception => e
|
176
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
177
|
+
IO::select( [ self.sslsock ], nil, nil, 0.5 )
|
178
|
+
retry
|
179
|
+
end
|
180
|
+
|
181
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
182
|
+
IO::select( nil, [ self.sslsock ], nil, 0.5 )
|
183
|
+
retry
|
184
|
+
end
|
185
|
+
|
186
|
+
raise e
|
187
|
+
end
|
188
|
+
|
189
|
+
total_sent
|
117
190
|
end
|
118
191
|
|
119
192
|
#
|
120
193
|
# Reads data from the SSL socket.
|
121
194
|
#
|
122
|
-
def read(length = nil, opts = {})
|
123
|
-
|
195
|
+
def read(length = nil, opts = {})
|
196
|
+
if not self.sslsock.respond_to?(:read_nonblock)
|
197
|
+
length = 16384 unless length
|
198
|
+
begin
|
199
|
+
return sslsock.sysread(length)
|
200
|
+
rescue EOFError, ::Errno::EPIPE
|
201
|
+
raise EOFError
|
202
|
+
end
|
203
|
+
return
|
204
|
+
end
|
205
|
+
|
124
206
|
|
125
207
|
begin
|
126
|
-
|
127
|
-
|
128
|
-
|
208
|
+
while true
|
209
|
+
s = Rex::ThreadSafe.select( [ self.sslsock ], nil, nil, 0.10 )
|
210
|
+
if( s == nil || s[0] == nil )
|
211
|
+
next
|
212
|
+
end
|
213
|
+
buf = sslsock.read_nonblock( length )
|
214
|
+
return buf if buf
|
215
|
+
raise ::EOFError
|
216
|
+
end
|
217
|
+
|
218
|
+
rescue ::IOError, ::Errno::EPIPE
|
219
|
+
return nil if (fd.abortive_close == true)
|
220
|
+
|
221
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
222
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
223
|
+
# Sleep for a tenth a second, or until we can read again
|
224
|
+
Rex::ThreadSafe.select( [ self.sslsock ], nil, nil, 0.10 )
|
225
|
+
# Decrement the block size to handle full sendQs better
|
226
|
+
block_size = 1024
|
227
|
+
# Try to write the data again
|
228
|
+
retry
|
229
|
+
|
230
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
231
|
+
rescue ::Exception => e
|
232
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
233
|
+
IO::select( [ self.sslsock ], nil, nil, 0.5 )
|
234
|
+
retry
|
235
|
+
end
|
236
|
+
|
237
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
238
|
+
IO::select( nil, [ self.sslsock ], nil, 0.5 )
|
239
|
+
retry
|
240
|
+
end
|
241
|
+
|
242
|
+
raise e
|
129
243
|
end
|
244
|
+
|
130
245
|
end
|
131
246
|
|
247
|
+
|
132
248
|
#
|
133
249
|
# Closes the SSL socket.
|
134
250
|
#
|
@@ -166,14 +282,14 @@ begin
|
|
166
282
|
sslsock.cipher if sslsock
|
167
283
|
end
|
168
284
|
|
169
|
-
|
170
|
-
|
171
285
|
attr_reader :peer_verified # :nodoc:
|
172
286
|
attr_accessor :sslsock, :sslctx # :nodoc:
|
287
|
+
|
173
288
|
protected
|
174
289
|
|
175
290
|
attr_writer :peer_verified # :nodoc:
|
176
291
|
|
292
|
+
|
177
293
|
rescue LoadError
|
178
294
|
end
|
179
295
|
|
@@ -15,10 +15,10 @@ module Rex::Socket::SslTcpServer
|
|
15
15
|
begin
|
16
16
|
require 'openssl'
|
17
17
|
@@loaded_openssl = true
|
18
|
+
require 'openssl/nonblock'
|
18
19
|
rescue ::Exception
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
22
|
include Rex::Socket::TcpServer
|
23
23
|
|
24
24
|
##
|
@@ -57,10 +57,39 @@ module Rex::Socket::SslTcpServer
|
|
57
57
|
|
58
58
|
begin
|
59
59
|
ssl = OpenSSL::SSL::SSLSocket.new(sock, self.sslctx)
|
60
|
-
|
60
|
+
|
61
|
+
|
62
|
+
if not ssl.respond_to?(:accept_nonblock)
|
63
|
+
ssl.accept
|
64
|
+
else
|
65
|
+
begin
|
66
|
+
ssl.accept_nonblock
|
67
|
+
|
68
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
69
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
70
|
+
IO::select(nil, nil, nil, 0.10)
|
71
|
+
retry
|
72
|
+
|
73
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
74
|
+
rescue ::Exception => e
|
75
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
76
|
+
IO::select( [ ssl ], nil, nil, 0.10 )
|
77
|
+
retry
|
78
|
+
end
|
79
|
+
|
80
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
81
|
+
IO::select( nil, [ ssl ], nil, 0.10 )
|
82
|
+
retry
|
83
|
+
end
|
84
|
+
|
85
|
+
raise e
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
61
89
|
sock.extend(Rex::Socket::SslTcp)
|
62
90
|
sock.sslsock = ssl
|
63
91
|
sock.sslctx = self.sslctx
|
92
|
+
|
64
93
|
return sock
|
65
94
|
|
66
95
|
rescue ::OpenSSL::SSL::SSLError
|
@@ -190,6 +190,12 @@ class SwitchBoard
|
|
190
190
|
def flush_routes
|
191
191
|
_init
|
192
192
|
|
193
|
+
# Remove each of the individual routes so the comms don't think they're
|
194
|
+
# still routing after a flush.
|
195
|
+
self.routes.each { |r|
|
196
|
+
r.comm.routes.delete("#{r.subnet}/#{r.netmask}")
|
197
|
+
}
|
198
|
+
# Re-initialize to an empty array
|
193
199
|
self.routes = Array.new
|
194
200
|
end
|
195
201
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: librex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.30
|
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-
|
14
|
+
date: 2011-05-02 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
|
18
|
+
description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision 12516
|
19
19
|
email:
|
20
20
|
- hdm@metasploit.com
|
21
21
|
- jacob.hammack@hammackj.com
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- lib/rex/ole/substorage.rb
|
150
150
|
- lib/rex/ole/util.rb
|
151
151
|
- lib/rex/ole.rb
|
152
|
+
- lib/rex/parser/apple_backup_manifestdb.rb
|
152
153
|
- lib/rex/parser/arguments.rb
|
153
154
|
- lib/rex/parser/arguments.rb.ut.rb
|
154
155
|
- lib/rex/parser/ini.rb
|
@@ -236,6 +237,7 @@ files:
|
|
236
237
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb
|
237
238
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb
|
238
239
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb
|
240
|
+
- lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb
|
239
241
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb
|
240
242
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb
|
241
243
|
- lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb
|