rex 2.0.9 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rex/exploitation/cmdstager/bourne.rb +14 -8
- data/lib/rex/exploitation/cmdstager/echo.rb +3 -3
- data/lib/rex/exploitation/js/memory.rb +1 -1
- data/lib/rex/java/serialization/model/contents.rb +1 -1
- data/lib/rex/mime/message.rb +1 -1
- data/lib/rex/parser/acunetix_nokogiri.rb +2 -0
- data/lib/rex/parser/appscan_nokogiri.rb +1 -1
- data/lib/rex/parser/burp_issue_nokogiri.rb +139 -0
- data/lib/rex/parser/burp_session_nokogiri.rb +1 -1
- data/lib/rex/parser/fs/bitlocker.rb +233 -0
- data/lib/rex/parser/fusionvm_nokogiri.rb +2 -2
- data/lib/rex/parser/ini.rb +1 -8
- data/lib/rex/parser/nokogiri_doc_mixin.rb +5 -0
- data/lib/rex/payloads/meterpreter/config.rb +23 -4
- data/lib/rex/post/meterpreter/channel.rb +8 -3
- data/lib/rex/post/meterpreter/client.rb +1 -0
- data/lib/rex/post/meterpreter/client_core.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/android/android.rb +86 -1
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +29 -0
- data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +75 -89
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +10 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +7 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +10 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +1 -1
- data/lib/rex/post/meterpreter/packet.rb +38 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +101 -108
- data/lib/rex/post/meterpreter/packet_parser.rb +14 -6
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +42 -21
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +54 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +39 -13
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +8 -0
- data/lib/rex/proto/adb.rb +7 -0
- data/lib/rex/proto/adb/client.rb +39 -0
- data/lib/rex/proto/adb/message.rb +164 -0
- data/lib/rex/proto/dcerpc/svcctl/packet.rb +9 -9
- data/lib/rex/proto/http/client_request.rb +2 -1
- data/lib/rex/proto/http/response.rb +1 -1
- data/lib/rex/proto/kademlia/bootstrap_response.rb +2 -2
- data/lib/rex/proto/ntp/modes.rb +17 -0
- data/lib/rex/text.rb +12 -0
- data/lib/rex/zip/blocks.rb +1 -1
- data/lib/rex/zip/entry.rb +1 -1
- data/rex.gemspec +28 -1
- metadata +106 -3
@@ -59,7 +59,7 @@ module Parser
|
|
59
59
|
unless in_tag("JobOrder")
|
60
60
|
case name
|
61
61
|
when "OS"
|
62
|
-
unless @host.nil? or @text.
|
62
|
+
unless @host.nil? or @text.to_s.empty?
|
63
63
|
tnote = {
|
64
64
|
:type => "host.os.fusionvm_fingerprint",
|
65
65
|
:data => { :os => @text.strip },
|
@@ -86,7 +86,7 @@ module Parser
|
|
86
86
|
when "CVE"
|
87
87
|
@vuln[:refs] << "CVE-#{@text.strip}"
|
88
88
|
when "References"
|
89
|
-
unless @text.
|
89
|
+
unless @text.to_s.empty?
|
90
90
|
@text.split(' ').each do |ref|
|
91
91
|
next unless ref.start_with? "http"
|
92
92
|
if ref =~ /MS\d{2}-\d{3}/
|
data/lib/rex/parser/ini.rb
CHANGED
@@ -49,14 +49,7 @@ class Ini < Hash
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
# Enumerates the groups hash keys.
|
54
|
-
#
|
55
|
-
def each_group(&block)
|
56
|
-
self.keys.each { |k|
|
57
|
-
yield
|
58
|
-
}
|
59
|
-
end
|
52
|
+
alias each_group each_key
|
60
53
|
|
61
54
|
#
|
62
55
|
# Adds a group of the supplied name if it doesn't already exist.
|
@@ -200,6 +200,11 @@ module Parser
|
|
200
200
|
return attr_pairs
|
201
201
|
end
|
202
202
|
|
203
|
+
# Removes HTML from a string
|
204
|
+
def strip_html_tags(text)
|
205
|
+
return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "}
|
206
|
+
end
|
207
|
+
|
203
208
|
# This breaks xml-encoded characters, so need to append.
|
204
209
|
# It's on the end_element tag name to turn the appending
|
205
210
|
# off and clear out the data.
|
@@ -120,6 +120,20 @@ private
|
|
120
120
|
extension_data = [ ext.length, ext ].pack('VA*')
|
121
121
|
end
|
122
122
|
|
123
|
+
def extension_init_block(name, value)
|
124
|
+
# for now, we're going to blindly assume that the value is a path to a file
|
125
|
+
# which contains the data that gets passed to the extension
|
126
|
+
content = ::File.read(value)
|
127
|
+
data = [
|
128
|
+
name,
|
129
|
+
"\x00",
|
130
|
+
content.length,
|
131
|
+
content
|
132
|
+
]
|
133
|
+
|
134
|
+
data.pack('A*A*VA*')
|
135
|
+
end
|
136
|
+
|
123
137
|
def config_block
|
124
138
|
# start with the session information
|
125
139
|
config = session_block(@opts)
|
@@ -142,12 +156,17 @@ private
|
|
142
156
|
end
|
143
157
|
|
144
158
|
# terminate the extensions with a 0 size
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
159
|
+
config << [0].pack('V')
|
160
|
+
|
161
|
+
# wire in the extension init data
|
162
|
+
(@opts[:ext_init] || '').split(':').each do |cfg|
|
163
|
+
name, value = cfg.split(',')
|
164
|
+
config << extension_init_block(name, value)
|
149
165
|
end
|
150
166
|
|
167
|
+
# terminate the ext init config with a final null byte
|
168
|
+
config << "\x00"
|
169
|
+
|
151
170
|
# and we're done
|
152
171
|
config
|
153
172
|
end
|
@@ -141,7 +141,9 @@ class Channel
|
|
141
141
|
if (cid and client)
|
142
142
|
client.add_channel(self)
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
|
+
# Ensure the remote object is closed when all references are removed
|
146
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, cid))
|
145
147
|
end
|
146
148
|
|
147
149
|
def self.finalize(client,cid)
|
@@ -288,8 +290,11 @@ class Channel
|
|
288
290
|
end
|
289
291
|
|
290
292
|
def _close(addends = nil)
|
291
|
-
|
292
|
-
|
293
|
+
unless self.cid.nil?
|
294
|
+
ObjectSpace.undefine_finalizer(self)
|
295
|
+
self.class._close(self.client, self.cid, addends)
|
296
|
+
self.cid = nil
|
297
|
+
end
|
293
298
|
end
|
294
299
|
#
|
295
300
|
# Enables or disables interactive mode.
|
@@ -469,7 +469,7 @@ class ClientCore < Extension
|
|
469
469
|
end
|
470
470
|
|
471
471
|
if client.platform =~ /linux/
|
472
|
-
if writable_dir.
|
472
|
+
if writable_dir.to_s.empty?
|
473
473
|
writable_dir = tmp_folder
|
474
474
|
end
|
475
475
|
|
@@ -752,7 +752,7 @@ class ClientCore < Extension
|
|
752
752
|
def tmp_folder
|
753
753
|
tmp = client.sys.config.getenv('TMPDIR')
|
754
754
|
|
755
|
-
if tmp.
|
755
|
+
if tmp.to_s.empty?
|
756
756
|
tmp = '/tmp'
|
757
757
|
end
|
758
758
|
|
@@ -20,6 +20,8 @@ module Android
|
|
20
20
|
class Android < Extension
|
21
21
|
|
22
22
|
COLLECT_TYPE_WIFI = 1
|
23
|
+
COLLECT_TYPE_GEO = 2
|
24
|
+
COLLECT_TYPE_CELL = 3
|
23
25
|
|
24
26
|
COLLECT_ACTION_START = 1
|
25
27
|
COLLECT_ACTION_PAUSE = 2
|
@@ -28,7 +30,9 @@ class Android < Extension
|
|
28
30
|
COLLECT_ACTION_DUMP = 5
|
29
31
|
|
30
32
|
COLLECT_TYPES = {
|
31
|
-
'wifi' => COLLECT_TYPE_WIFI
|
33
|
+
'wifi' => COLLECT_TYPE_WIFI,
|
34
|
+
'geo' => COLLECT_TYPE_GEO,
|
35
|
+
'cell' => COLLECT_TYPE_CELL,
|
32
36
|
}
|
33
37
|
|
34
38
|
COLLECT_ACTIONS = {
|
@@ -68,6 +72,12 @@ class Android < Extension
|
|
68
72
|
response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
|
69
73
|
end
|
70
74
|
|
75
|
+
def set_audio_mode(n)
|
76
|
+
request = Packet.create_request('set_audio_mode')
|
77
|
+
request.add_tlv(TLV_TYPE_AUDIO_MODE, n)
|
78
|
+
response = client.send_request(request)
|
79
|
+
end
|
80
|
+
|
71
81
|
def interval_collect(opts)
|
72
82
|
request = Packet.create_request('interval_collect')
|
73
83
|
request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]])
|
@@ -107,6 +117,64 @@ class Android < Extension
|
|
107
117
|
records.each do |k, v|
|
108
118
|
result[:entries] << v
|
109
119
|
end
|
120
|
+
|
121
|
+
when COLLECT_TYPE_GEO
|
122
|
+
result[:headers] = ['Timestamp', 'Latitude', 'Longitude']
|
123
|
+
result[:entries] = []
|
124
|
+
records = {}
|
125
|
+
|
126
|
+
response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
|
127
|
+
timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
|
128
|
+
timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
129
|
+
|
130
|
+
g.each(TLV_TYPE_COLLECT_RESULT_GEO) do |w|
|
131
|
+
lat = w.get_tlv_value(TLV_TYPE_GEO_LAT)
|
132
|
+
lng = w.get_tlv_value(TLV_TYPE_GEO_LONG)
|
133
|
+
result[:entries] << [timestamp, lat, lng]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
when COLLECT_TYPE_CELL
|
138
|
+
result[:headers] = ['Timestamp', 'Cell Info']
|
139
|
+
result[:entries] = []
|
140
|
+
records = {}
|
141
|
+
|
142
|
+
response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
|
143
|
+
timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
|
144
|
+
timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
145
|
+
|
146
|
+
g.each(TLV_TYPE_COLLECT_RESULT_CELL) do |cell|
|
147
|
+
|
148
|
+
cell.each(TLV_TYPE_CELL_ACTIVE_GSM) do |info|
|
149
|
+
cid = info.get_tlv_value(TLV_TYPE_CELL_CID)
|
150
|
+
lac = info.get_tlv_value(TLV_TYPE_CELL_LAC)
|
151
|
+
psc = info.get_tlv_value(TLV_TYPE_CELL_PSC)
|
152
|
+
info = sprintf("cid=%d lac=%d psc=%d", cid, lac, psc)
|
153
|
+
result[:entries] << [timestamp, "GSM: #{info}"]
|
154
|
+
end
|
155
|
+
|
156
|
+
cell.each(TLV_TYPE_CELL_ACTIVE_CDMA) do |info|
|
157
|
+
bid = info.get_tlv_value(TLV_TYPE_CELL_BASE_ID)
|
158
|
+
lat = info.get_tlv_value(TLV_TYPE_CELL_BASE_LAT)
|
159
|
+
lng = info.get_tlv_value(TLV_TYPE_CELL_BASE_LONG)
|
160
|
+
net = info.get_tlv_value(TLV_TYPE_CELL_NET_ID)
|
161
|
+
sys = info.get_tlv_value(TLV_TYPE_CELL_SYSTEM_ID)
|
162
|
+
info = sprintf("base_id=%d lat=%d lng=%d net_id=%d sys_id=%d", bid, lat, lng, net, sys)
|
163
|
+
result[:entries] << [timestamp, "CDMA: #{info}"]
|
164
|
+
end
|
165
|
+
|
166
|
+
cell.each(TLV_TYPE_CELL_NEIGHBOR) do |w|
|
167
|
+
net = w.get_tlv_value(TLV_TYPE_CELL_NET_TYPE)
|
168
|
+
cid = w.get_tlv_value(TLV_TYPE_CELL_CID)
|
169
|
+
lac = w.get_tlv_value(TLV_TYPE_CELL_LAC)
|
170
|
+
psc = w.get_tlv_value(TLV_TYPE_CELL_PSC)
|
171
|
+
sig = w.get_tlv_value(TLV_TYPE_CELL_RSSI) * -1
|
172
|
+
inf = sprintf("network_type=%d cid=%d lac=%d psc=%d rssi=%d", net, cid, lac, psc, sig)
|
173
|
+
result[:entries] << [timestamp, inf]
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
110
178
|
end
|
111
179
|
|
112
180
|
result
|
@@ -180,6 +248,23 @@ class Android < Extension
|
|
180
248
|
response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value
|
181
249
|
end
|
182
250
|
|
251
|
+
def activity_start(uri)
|
252
|
+
request = Packet.create_request('activity_start')
|
253
|
+
request.add_tlv(TLV_TYPE_URI_STRING, uri)
|
254
|
+
response = client.send_request(request)
|
255
|
+
if response.get_tlv(TLV_TYPE_ACTIVITY_START_RESULT).value
|
256
|
+
return nil
|
257
|
+
else
|
258
|
+
return response.get_tlv(TLV_TYPE_ACTIVITY_START_ERROR).value
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def set_wallpaper(data)
|
263
|
+
request = Packet.create_request('set_wallpaper')
|
264
|
+
request.add_tlv(TLV_TYPE_WALLPAPER_DATA, data)
|
265
|
+
response = client.send_request(request)
|
266
|
+
end
|
267
|
+
|
183
268
|
def send_sms(dest, body, dr)
|
184
269
|
request = Packet.create_request('send_sms')
|
185
270
|
request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest)
|
@@ -54,6 +54,35 @@ TLV_TYPE_COLLECT_RESULT_WIFI_BSSID = TLV_TYPE_WLAN_BSSID
|
|
54
54
|
TLV_TYPE_COLLECT_RESULT_WIFI_SSID = TLV_TYPE_WLAN_SSID
|
55
55
|
TLV_TYPE_COLLECT_RESULT_WIFI_LEVEL = TLV_TYPE_WLAN_LEVEL
|
56
56
|
|
57
|
+
|
58
|
+
TLV_TYPE_COLLECT_RESULT_GEO = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9030)
|
59
|
+
|
60
|
+
TLV_TYPE_COLLECT_RESULT_CELL = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9060)
|
61
|
+
|
62
|
+
TLV_TYPE_CELL_ACTIVE_GSM = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9061)
|
63
|
+
TLV_TYPE_CELL_ACTIVE_CDMA = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9062)
|
64
|
+
TLV_TYPE_CELL_NEIGHBOR = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9063)
|
65
|
+
|
66
|
+
TLV_TYPE_CELL_NET_TYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9065)
|
67
|
+
TLV_TYPE_CELL_CID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9066)
|
68
|
+
TLV_TYPE_CELL_LAC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9067)
|
69
|
+
TLV_TYPE_CELL_PSC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9068)
|
70
|
+
TLV_TYPE_CELL_RSSI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9069)
|
71
|
+
|
72
|
+
|
73
|
+
TLV_TYPE_CELL_BASE_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9070)
|
74
|
+
TLV_TYPE_CELL_BASE_LAT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9071)
|
75
|
+
TLV_TYPE_CELL_BASE_LONG = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9072)
|
76
|
+
TLV_TYPE_CELL_NET_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9073)
|
77
|
+
TLV_TYPE_CELL_SYSTEM_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9074)
|
78
|
+
TLV_TYPE_AUDIO_MODE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9075)
|
79
|
+
|
80
|
+
TLV_TYPE_URI_STRING = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9101)
|
81
|
+
TLV_TYPE_ACTIVITY_START_RESULT = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9102)
|
82
|
+
TLV_TYPE_ACTIVITY_START_ERROR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9103)
|
83
|
+
|
84
|
+
TLV_TYPE_WALLPAPER_DATA = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 9201)
|
85
|
+
|
57
86
|
end
|
58
87
|
end
|
59
88
|
end
|
@@ -31,7 +31,7 @@ class Wmi
|
|
31
31
|
def query(query, root = nil)
|
32
32
|
request = Packet.create_request('extapi_wmi_query')
|
33
33
|
|
34
|
-
request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.
|
34
|
+
request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.to_s.empty?
|
35
35
|
request.add_tlv(TLV_TYPE_EXT_WMI_QUERY, query)
|
36
36
|
|
37
37
|
response = client.send_request(request)
|
@@ -24,73 +24,59 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
24
24
|
#
|
25
25
|
@@server_channels = {}
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
def request_handler( client, packet )
|
38
|
-
|
39
|
-
if( packet.method == "tcp_channel_open" )
|
40
|
-
|
41
|
-
cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
|
42
|
-
pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
|
43
|
-
localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
|
44
|
-
localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
|
45
|
-
peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
|
46
|
-
peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
|
47
|
-
|
48
|
-
if( cid == nil or pid == nil )
|
49
|
-
return false
|
50
|
-
end
|
51
|
-
|
52
|
-
server_channel = client.find_channel( pid )
|
53
|
-
if( server_channel == nil )
|
54
|
-
return false
|
55
|
-
end
|
56
|
-
|
57
|
-
params = Rex::Socket::Parameters.from_hash(
|
58
|
-
{
|
59
|
-
'Proto' => 'tcp',
|
60
|
-
'LocalHost' => localhost,
|
61
|
-
'LocalPort' => localport,
|
62
|
-
'PeerHost' => peerhost,
|
63
|
-
'PeerPort' => peerport,
|
64
|
-
'Comm' => server_channel.client
|
65
|
-
}
|
66
|
-
)
|
67
|
-
|
68
|
-
client_channel = TcpClientChannel.new( client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS )
|
69
|
-
|
70
|
-
client_channel.params = params
|
71
|
-
|
72
|
-
if( @@server_channels[server_channel] == nil )
|
73
|
-
@@server_channels[server_channel] = []
|
74
|
-
end
|
75
|
-
|
76
|
-
@@server_channels[server_channel] << client_channel
|
77
|
-
|
78
|
-
return true
|
79
|
-
end
|
80
|
-
|
81
|
-
return false
|
82
|
-
end
|
27
|
+
#
|
28
|
+
# This is the request handler which is registered to the respective meterpreter instance via
|
29
|
+
# Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket. All incoming requests from the meterpreter
|
30
|
+
# for a 'tcp_channel_open' will be processed here. We create a new TcpClientChannel for each request
|
31
|
+
# received and store it in the respective tcp server channels list of new pending client channels.
|
32
|
+
# These new tcp client channels are passed off via a call the the tcp server channels accept() method.
|
33
|
+
#
|
34
|
+
def self.request_handler(client, packet)
|
35
|
+
return false unless packet.method == "tcp_channel_open"
|
83
36
|
|
84
|
-
|
85
|
-
|
86
|
-
|
37
|
+
cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
|
38
|
+
pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
|
39
|
+
localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
|
40
|
+
localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
|
41
|
+
peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
|
42
|
+
peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
|
43
|
+
|
44
|
+
return false if cid.nil? || pid.nil?
|
45
|
+
|
46
|
+
server_channel = client.find_channel(pid)
|
47
|
+
|
48
|
+
return false if server_channel.nil?
|
87
49
|
|
50
|
+
params = Rex::Socket::Parameters.from_hash(
|
51
|
+
{
|
52
|
+
'Proto' => 'tcp',
|
53
|
+
'LocalHost' => localhost,
|
54
|
+
'LocalPort' => localport,
|
55
|
+
'PeerHost' => peerhost,
|
56
|
+
'PeerPort' => peerport,
|
57
|
+
'Comm' => server_channel.client
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS)
|
62
|
+
|
63
|
+
client_channel.params = params
|
64
|
+
|
65
|
+
@@server_channels[server_channel] ||= ::Queue.new
|
66
|
+
@@server_channels[server_channel].enq(client_channel)
|
67
|
+
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.cls
|
72
|
+
CHANNEL_CLASS_STREAM
|
88
73
|
end
|
89
74
|
|
90
75
|
#
|
91
76
|
# Open a new tcp server channel on the remote end.
|
92
77
|
#
|
93
|
-
|
78
|
+
# @return [Channel]
|
79
|
+
def self.open(client, params)
|
94
80
|
c = Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
|
95
81
|
[
|
96
82
|
{
|
@@ -112,7 +98,7 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
112
98
|
def initialize(client, cid, type, flags)
|
113
99
|
super(client, cid, type, flags)
|
114
100
|
# add this instance to the class variables dictionary of tcp server channels
|
115
|
-
@@server_channels[self]
|
101
|
+
@@server_channels[self] ||= ::Queue.new
|
116
102
|
end
|
117
103
|
|
118
104
|
#
|
@@ -120,46 +106,46 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
120
106
|
# and returns nil if no new client connection is available.
|
121
107
|
#
|
122
108
|
def accept_nonblock
|
123
|
-
|
124
|
-
if( @@server_channels[self].length > 0 )
|
125
|
-
channel = @@server_channels[self].shift
|
126
|
-
result = channel.lsock
|
127
|
-
end
|
128
|
-
return result
|
109
|
+
_accept(true)
|
129
110
|
end
|
130
111
|
|
131
112
|
#
|
132
113
|
# Accept a new tcp client connection form this tcp server channel. This method will block indefinatly
|
133
114
|
# if no timeout is specified.
|
134
115
|
#
|
135
|
-
def accept(
|
136
|
-
timeout = opts['Timeout']
|
137
|
-
if( timeout
|
138
|
-
|
139
|
-
else
|
140
|
-
begin
|
141
|
-
::Timeout.timeout( timeout ) {
|
142
|
-
result = _accept
|
143
|
-
}
|
144
|
-
rescue Timeout::Error
|
145
|
-
result = nil
|
146
|
-
end
|
116
|
+
def accept(opts = {})
|
117
|
+
timeout = opts['Timeout']
|
118
|
+
if (timeout.nil? || timeout <= 0)
|
119
|
+
timeout = 0
|
147
120
|
end
|
148
|
-
|
121
|
+
|
122
|
+
result = nil
|
123
|
+
begin
|
124
|
+
::Timeout.timeout(timeout) {
|
125
|
+
result = _accept
|
126
|
+
}
|
127
|
+
rescue Timeout::Error
|
128
|
+
end
|
129
|
+
|
130
|
+
result
|
149
131
|
end
|
150
132
|
|
151
133
|
protected
|
152
134
|
|
153
|
-
def _accept
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
result =
|
160
|
-
break if result != nil
|
135
|
+
def _accept(nonblock = false)
|
136
|
+
result = nil
|
137
|
+
|
138
|
+
channel = @@server_channels[self].deq(nonblock)
|
139
|
+
|
140
|
+
if channel
|
141
|
+
result = channel.lsock
|
161
142
|
end
|
162
|
-
|
143
|
+
|
144
|
+
if result != nil && !result.kind_of?(Rex::Socket::Tcp)
|
145
|
+
result.extend(Rex::Socket::Tcp)
|
146
|
+
end
|
147
|
+
|
148
|
+
result
|
163
149
|
end
|
164
150
|
|
165
151
|
end
|