Skip to content

Commit c1826cd

Browse files
committed
Land rapid7#18829, Allow multiple HttpServers in module
Adding multiple HttpServer services in a module is sometimes complex since they share the same methods. This usually this causes issues where on_request_uri needs to be overridden to handle requests coming from each service. This updates the cmdstager and the Java HTTP ClassLoader mixins, since these are commonly used in the same module. This also updates the manageengine_servicedesk_plus_saml_rce_cve_2022_47966 module to make use of these new changes
2 parents 223c6fe + 8fc6e20 commit c1826cd

13 files changed

+30
-35
lines changed

lib/msf/core/exploit/cmd_stager.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def generate_cmdstager(opts = {}, pl = nil)
152152
if stager_instance.respond_to?(:http?) && stager_instance.http?
153153
opts[:ssl] = datastore['CMDSTAGER::SSL'] unless opts.key?(:ssl)
154154
opts['Path'] = datastore['CMDSTAGER::URIPATH'] unless datastore['CMDSTAGER::URIPATH'].blank?
155-
opts[:payload_uri] = start_service(opts)
155+
opts[:payload_uri] = cmdstager_start_service(opts)
156156
end
157157

158158
cmd_list = stager_instance.generate(opts_with_decoder(opts))

lib/msf/core/exploit/cmd_stager/http.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@ def initialize(info = {})
1111
))
1212
end
1313

14-
def start_service(opts = {})
14+
def cmdstager_start_service(opts = {})
1515
# XXX: This is a workaround until we can take SSL in opts
1616
datastore_ssl = datastore['SSL']
1717
datastore['SSL'] = !!opts[:ssl]
1818

19-
super
19+
opts['Uri'] = {
20+
'Proc' => Proc.new { |cli, req| cmdstager_on_request_uri(cli, req) },
21+
'Path' => opts['Path'] || resource_uri
22+
}.update(opts['Uri'] || {})
23+
start_service(opts)
2024

2125
payload_uri = get_uri
2226
datastore['SSL'] = datastore_ssl
2327

2428
payload_uri
2529
end
2630

27-
def on_request_uri(cli, request)
31+
def cmdstager_on_request_uri(cli, request)
2832
client = cli.peerhost
2933

3034
if (user_agent = request.headers['User-Agent'])

lib/msf/core/exploit/remote/java/http/class_loader.rb

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,38 @@ def initialize(info = {})
1515
))
1616
end
1717

18-
def start_service(opts = {})
18+
def java_class_loader_start_service(opts = {})
1919
# XXX: This is a workaround until we can take SSL in opts
2020
ssl = datastore['SSL']
2121
datastore['SSL'] = false
2222

23-
super
23+
opts['Uri'] = {
24+
'Proc' => Proc.new { |cli, req| java_class_loader_on_request_uri(cli, req) },
25+
'Path' => opts['Path'] || java_class_loader_resource_uri
26+
}.update(opts['Uri'] || {})
27+
start_service(opts)
2428

2529
datastore['SSL'] = ssl
2630
get_uri
2731
end
2832

29-
def resource_uri
30-
return @resource_uri if @resource_uri
33+
def java_class_loader_resource_uri
34+
return @java_class_loader_resource_uri if @java_class_loader_resource_uri
3135
# the resource URI must end in / for the class loading to work
32-
path = super
36+
path = resource_uri
3337
path += '/' unless path.end_with?('/')
34-
@resource_uri = path
38+
@java_class_loader_resource_uri = path
3539
end
3640

37-
def on_request_uri(cli, request)
41+
def java_class_loader_on_request_uri(cli, request)
3842
vprint_status("#{request.method} #{request.uri} requested")
3943

4044
unless %w[HEAD GET].include?(request.method)
4145
vprint_error("Ignoring #{request.method} request")
4246
return
4347
end
4448

45-
resource = request.raw_uri.delete_prefix(resource_uri)
49+
resource = request.raw_uri.delete_prefix(java_class_loader_resource_uri)
4650

4751
if request.method == 'HEAD'
4852
whitelist = %W[

modules/exploits/linux/http/suitecrm_log_file_rce.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def on_request_uri(cli, _request)
316316
end
317317

318318
def start_http_server
319-
start_service(
319+
cmdstager_start_service(
320320
{
321321
'Uri' => {
322322
'Proc' => proc do |cli, req|

modules/exploits/linux/http/vmware_vrli_rce.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def exploit
256256
pak_name = "#{file_name}.pak"
257257
register_files_for_cleanup("/tmp/#{pak_name}")
258258
print_status('Starting Payload Server')
259-
start_service('Path' => "/#{file_name}.tar")
259+
cmdstager_start_service('Path' => "/#{file_name}.tar")
260260

261261
# Connect to the Apache Thrift service
262262
thrift_client = Rex::Proto::Thrift::Client.new(

modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def yeet_runner(root_key)
193193
)
194194
when :unix_cmd
195195
# HTTPS doesn't appear to be supported by the server :(
196-
print_status("Serving intermediate stager over HTTP: #{start_service}")
196+
print_status("Serving intermediate stager over HTTP: #{cmdstager_start_service}")
197197

198198
vprint_status("Executing Unix command: #{payload.encoded}")
199199

modules/exploits/multi/http/apache_commons_text4shell.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def exploit
129129
case target['Type']
130130
when :java
131131
# Start the HTTP server to serve the payload
132-
start_service
132+
java_class_loader_start_service
133133
# Trigger a loadClass request via java.net.URLClassLoader
134134
trigger_urlclassloader
135135
# Handle the payload

modules/exploits/multi/http/liferay_java_unmarshalling.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def check
108108

109109
def exploit
110110
# Start our HTTP server to provide remote classloading
111-
@classloader_uri = start_service
111+
@classloader_uri = java_class_loader_start_service
112112

113113
unless @classloader_uri
114114
fail_with(Failure::BadConfig, 'Could not start remote classloader server')

modules/exploits/multi/http/manageengine_servicedesk_plus_saml_rce_cve_2022_47966.rb

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def exploit
150150
case target['Type']
151151
when :java
152152
# Start the HTTP server to serve the payload
153-
start_service
153+
java_class_loader_start_service
154154
# Trigger a loadClass request via java.net.URLClassLoader
155155
trigger_urlclassloader
156156
# Handle the payload
@@ -285,17 +285,4 @@ def send_transform(transform)
285285
res
286286
end
287287

288-
# handle http requests from java stagers and cmd stagers differently
289-
def on_request_uri(cli, request)
290-
case target['Type']
291-
when :java
292-
super(cli, request)
293-
else
294-
client = cli.peerhost
295-
print_status("Client #{client} requested #{request.uri}")
296-
print_status("Sending payload to #{client}")
297-
send_response(cli, exe)
298-
end
299-
end
300-
301288
end

modules/exploits/multi/http/microfocus_obm_auth_rce.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def check
7979

8080
def exploit
8181
# Start our HTTP server to provide remote classloading
82-
@classloader_uri = start_service
82+
@classloader_uri = java_class_loader_start_service
8383

8484
unless @classloader_uri
8585
fail_with(Failure::BadConfig, 'Could not start remote classloader server')

0 commit comments

Comments
 (0)