Metasploit Module: ManageEngine ADAudit Plus Authenticated File Write RCE
Type: exploit
Path: modules/exploits/windows/http/manageengine_adaudit_plus_authenticated_rce.rb
Platform: win
Disclosure date: 2021-10-01
References: CVE-2021-42847, URL-https://pitstop.manageengine.com/portal/en/community/topic/fix-released-for-a-vulnerability-in-manageengine-adaudit-plus, URL-https://www.manageengine.com/products/active-directory-audit/adaudit-plus-release-notes.html
Targets: Windows Command

Description:
This module exploits security issues in ManageEngine ADAudit Plus
          prior to 7006 that allow authenticated users to execute arbitrary
          code by creating a custom alert profile and leveraging its custom
          alert script component.

          The module first runs a few checks to test the provided
          credentials, retrieve the configured domain(s) and obtain the
          build number of the target ADAudit Plus server.

          If the credentials are valid and the target is
          vulnerable, the module creates an alert profile that will be
          triggered for any failed login attempt to the configured domain.

          For versions prior to build 7004, the payload is directly inserted
          in the custom alert script component of the alert profile.

          For versions 7004 and 7005, the module leverages an arbitrary file
          write vulnerability (CVE-2021-42847) to create a Powershell script
          in the alert_scripts directory that contains the payload. The name
          of this script is then provided as the value for the custom alert
          script component of the alert profile.

          This module requires valid credentials for an account with the
          privileges to create alert scripts. It has been successfully tested
          against ManageEngine ADAudit Plus builds 7003 and 7005 running on
          Windows Server 2012 R2.

          Successful exploitation will result in RCE as the user running
          ManageEngine ADAudit Plus, which will typically be the local
          administrator.

Check method (fingerprinting):
target_check_results = adaudit_plus_target_check
    target_check_msg = target_check_results['message']
    case target_check_results['status']
    when adaudit_plus_status::CONNECTION_FAILED
      return CheckCode::Unknown(target_check_msg)
    when adaudit_plus_status::UNEXPECTED_REPLY
      return CheckCode::Safe(target_check_msg)
    when adaudit_plus_status::SUCCESS
      vprint_status(target_check_msg)
    else
      # this covers cases that may be added in the future
      return CheckCode::Unknown(target_check_msg)
    end

    target_check_res = target_check_results['server_response']

    # In order to trigger the final payload in the exploit method, we will need to send an authentication request to
    # ADAudit Plus with incorrect Active Directory credentials if the user didn't provide an Active Directory domain,
    # we can try to extract the FQDN for a configured domain from the server response
    domain_alias_results = adaudit_plus_grab_domain_aliases(target_check_res)
    domain_alias_msg = domain_alias_results['message']
    if domain_alias_results['status'] == adaudit_plus_status::NO_DOMAINS
      return CheckCode::Safe(domain_alias_msg)
    end

    domain_aliases = domain_alias_results['domain_aliases']
    # check if we actually have any configured domain aliases now, otherwise the target isn't exploitable
    if domain_aliases.blank?
      return CheckCode::Safe('Failed to verify if any Active Directory domains are configured on the target.')
    end