Skip to content

Commit

Permalink
Land #18829, Allow multiple HttpServers in module
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jheysel-r7 committed Jun 18, 2024
2 parents 223c6fe + 8fc6e20 commit c1826cd
Show file tree
Hide file tree
Showing 13 changed files with 30 additions and 35 deletions.
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/cmd_stager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def generate_cmdstager(opts = {}, pl = nil)
if stager_instance.respond_to?(:http?) && stager_instance.http?
opts[:ssl] = datastore['CMDSTAGER::SSL'] unless opts.key?(:ssl)
opts['Path'] = datastore['CMDSTAGER::URIPATH'] unless datastore['CMDSTAGER::URIPATH'].blank?
opts[:payload_uri] = start_service(opts)
opts[:payload_uri] = cmdstager_start_service(opts)
end

cmd_list = stager_instance.generate(opts_with_decoder(opts))
Expand Down
10 changes: 7 additions & 3 deletions lib/msf/core/exploit/cmd_stager/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ def initialize(info = {})
))
end

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

super
opts['Uri'] = {
'Proc' => Proc.new { |cli, req| cmdstager_on_request_uri(cli, req) },
'Path' => opts['Path'] || resource_uri
}.update(opts['Uri'] || {})
start_service(opts)

payload_uri = get_uri
datastore['SSL'] = datastore_ssl

payload_uri
end

def on_request_uri(cli, request)
def cmdstager_on_request_uri(cli, request)
client = cli.peerhost

if (user_agent = request.headers['User-Agent'])
Expand Down
20 changes: 12 additions & 8 deletions lib/msf/core/exploit/remote/java/http/class_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,38 @@ def initialize(info = {})
))
end

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

super
opts['Uri'] = {
'Proc' => Proc.new { |cli, req| java_class_loader_on_request_uri(cli, req) },
'Path' => opts['Path'] || java_class_loader_resource_uri
}.update(opts['Uri'] || {})
start_service(opts)

datastore['SSL'] = ssl
get_uri
end

def resource_uri
return @resource_uri if @resource_uri
def java_class_loader_resource_uri
return @java_class_loader_resource_uri if @java_class_loader_resource_uri
# the resource URI must end in / for the class loading to work
path = super
path = resource_uri
path += '/' unless path.end_with?('/')
@resource_uri = path
@java_class_loader_resource_uri = path
end

def on_request_uri(cli, request)
def java_class_loader_on_request_uri(cli, request)
vprint_status("#{request.method} #{request.uri} requested")

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

resource = request.raw_uri.delete_prefix(resource_uri)
resource = request.raw_uri.delete_prefix(java_class_loader_resource_uri)

if request.method == 'HEAD'
whitelist = %W[
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/linux/http/suitecrm_log_file_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ def on_request_uri(cli, _request)
end

def start_http_server
start_service(
cmdstager_start_service(
{
'Uri' => {
'Proc' => proc do |cli, req|
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/linux/http/vmware_vrli_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def exploit
pak_name = "#{file_name}.pak"
register_files_for_cleanup("/tmp/#{pak_name}")
print_status('Starting Payload Server')
start_service('Path' => "/#{file_name}.tar")
cmdstager_start_service('Path' => "/#{file_name}.tar")

# Connect to the Apache Thrift service
thrift_client = Rex::Proto::Thrift::Client.new(
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/linux/misc/saltstack_salt_unauth_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def yeet_runner(root_key)
)
when :unix_cmd
# HTTPS doesn't appear to be supported by the server :(
print_status("Serving intermediate stager over HTTP: #{start_service}")
print_status("Serving intermediate stager over HTTP: #{cmdstager_start_service}")

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

Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/multi/http/apache_commons_text4shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def exploit
case target['Type']
when :java
# Start the HTTP server to serve the payload
start_service
java_class_loader_start_service
# Trigger a loadClass request via java.net.URLClassLoader
trigger_urlclassloader
# Handle the payload
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/multi/http/liferay_java_unmarshalling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def check

def exploit
# Start our HTTP server to provide remote classloading
@classloader_uri = start_service
@classloader_uri = java_class_loader_start_service

unless @classloader_uri
fail_with(Failure::BadConfig, 'Could not start remote classloader server')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def exploit
case target['Type']
when :java
# Start the HTTP server to serve the payload
start_service
java_class_loader_start_service
# Trigger a loadClass request via java.net.URLClassLoader
trigger_urlclassloader
# Handle the payload
Expand Down Expand Up @@ -285,17 +285,4 @@ def send_transform(transform)
res
end

# handle http requests from java stagers and cmd stagers differently
def on_request_uri(cli, request)
case target['Type']
when :java
super(cli, request)
else
client = cli.peerhost
print_status("Client #{client} requested #{request.uri}")
print_status("Sending payload to #{client}")
send_response(cli, exe)
end
end

end
2 changes: 1 addition & 1 deletion modules/exploits/multi/http/microfocus_obm_auth_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def check

def exploit
# Start our HTTP server to provide remote classloading
@classloader_uri = start_service
@classloader_uri = java_class_loader_start_service

unless @classloader_uri
fail_with(Failure::BadConfig, 'Could not start remote classloader server')
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/multi/http/solr_velocity_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def exploit

case target.name
when /Java/
@classloader_uri = start_service
@classloader_uri = java_class_loader_start_service
execute_java('core_name' => @vuln_core[0], 'auth_string' => @auth_string)
return
end
Expand Down
2 changes: 1 addition & 1 deletion modules/exploits/multi/http/torchserver_cve_2023_43654.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def generate_mar
end

def exploit
start_service
java_class_loader_start_service

@model_name = rand_text_alphanumeric(8..15)
print_status('Registering the model archive...')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def exploit
case target['Type']
when :java
# Start the HTTP server to serve the payload
start_service
java_class_loader_start_service
# Trigger a loadClass request via java.net.URLClassLoader
trigger_urlclassloader
# Handle the payload
Expand Down

0 comments on commit c1826cd

Please sign in to comment.