Talos Vulnerability Report

TALOS-2024-1969

Microsoft Windows CLIPSP.SYS License Update Field Type 0x20 out-of-bounds read vulnerability

August 13, 2024
CVE Number

CVE-2024-38187

SUMMARY

An out-of-bounds read vulnerability exists in the License Update Field Type 0x20 functionality of Microsoft Windows CLIPSP.SYS 10.0.22621 Build 22621, 10.0.26080.1 and 10.0.26085.1. A specially crafted license blob can lead to denial of service. An attacker can use the NtQuerySystemInformation function call to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Microsoft CLIPSP.SYS 10.0.22621 Build 22621
Microsoft CLIPSP.SYS 10.0.26080.1
Microsoft CLIPSP.SYS 10.0.26085.1
Microsoft Windows 11 Pro 23H2 22631.3296
Microsoft Windows 11 Pro 24H2 Insider Preview 26085.1

PRODUCT URLS

CLIPSP.SYS - https://www.microsoft.com/en-us/windows/windows-11 Windows - https://www.microsoft.com/en-us/windows/

CVSSv3 SCORE

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

CWE

CWE-125 - Out-of-bounds Read

DETAILS

CLIPSP.SYS is a driver used to implement Client License System Policy on Windows 10 and 11. It provides the functions used when handling most of the requests involving licensing, notably the implementation of many use cases involved with the SystemPolicyInformation class used in conjunction with NtQuerySystemInformation.

Context

When calling NtQuerySystemInformation with the SystemPolicyInformation class, ntoskrnl will call ExHandleSPCall2 that will process the data provided. The format is mostly undocumented and encrypted using Microsoft’s Warbird. Upon decryption of the data provided, a call handler is invoked based on the command_id provided and dispatches the payload to the relevant function (e.g. SPCallServerHandleClepKdf, SPCallServerHandleUpdateLicense, etc.). A substential amount of these functions are wrapers around clipsp functions that are stored as function pointers in the nt!g_kernelCallbacks globlal array.

The SPCallServerHandleUpdateLicense (command_id:100) will accept a License blob whose format is also undocumented. Once installed, these license files are stored in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\{7746D80F-97E0-4E26-9543-26B41FC22F79}\{A25AE4F2-1B96-4CED-8007-AA30E9B1A218} key, only accessible to the SYSTEM user. The format of this license file is TLV (Tag-length-value) following this format:

struct __unaligned __declspec(align(1)) LicenseParsing_entry
{
  __int16 type;
  __int16 reserved;
  int entry_size;
  char value[ANYSIZE_ARRAY]; //expected to be of size entry_size
};

The code snippets below are decompiled output and variables names were assumed from context or retrieved from public symbol servers, sdk, etc. The addresses provided are for the canary build 26085.1.amd64fre.ge_release.240315-1352

There exists multiple out-of-bound reads vulnerabilities when handling various license field types. This vulnerability can be triggered by feeding to the SPCallServerHandleUpdateLicense function a license filed that has been tampered with.

When calling SPCallServerHandleUpdateLicense the data will eventually be past to an obfuscated function inside clipsp and stored in an array (see 0x0001C00E8BA3):

 License->field_0[v13].entry_size = v10->entry_size;
 License->field_0[v13].entry_field2 = v10->field_2;
 License->field_0[v13].entry_ptr = (__int64)&v10->first_byte;

Where v13 is the internal type associated with an entry type in the license file. In most of the case below, the root cause of the problem is reading data in entry_ptr without verifying first that entry_size accomodates for the extent of the data read (e.g. read 2 bytes of data at offset 8 without verifying that entry_size >= 8+2)

Vulnerability

When installing a new device bound license, an out-of-bound read can occur if a truncated blob of type 0x20 is appended at the end of the license such as {0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xAA }. The likely consequence is an access violation leading to a blue screen that coud become recurring if the license file successfuly installs. The following function gets invoked during the installation of a device bound license:

// 0000001C00E7790 
__int64 __fastcall __spoils<rax,rdx> LicenseStruct_get_dref0_for_type3(LicenseStruct *License)
{
  unsigned int *entry_ptr; // rdx
  __int64 result; // rax

  entry_ptr = (unsigned int *)License->field_0[3].entry_ptr;
  result = 0i64;
  if ( entry_ptr )
    return *entry_ptr;
  return result;
}
TIMELINE

2024-04-11 - Vendor Disclosure
2024-08-13 - Vendor Patch Release
2024-08-13 - Public Release

Credit

Discovered by Philippe Laulheret of Cisco Talos.