CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2024-38077
9.887.07%

MadLicense: When Windows Licensing Decides to Execute You

Alon Barad
Alon Barad
Software Engineer

Jan 31, 2026·6 min read·12 visits

PoC Available

Executive Summary (TL;DR)

Critical RCE (CVSS 9.8) in Windows Remote Desktop Licensing Service via Heap Overflow. Unauthenticated, Zero-Click, SYSTEM privileges. Exploit involves sending malformed Base64 data to RPC Opnum 49.

MadLicense (CVE-2024-38077) is a textbook example of why legacy code in obscure Windows services is a goldmine for attackers. It is a critical Heap-based Buffer Overflow residing in the Windows Remote Desktop Licensing Service, a component often enabled by default on servers handling Terminal Services. With a CVSS score of 9.8, it allows unauthenticated attackers to execute arbitrary code as NT AUTHORITY\SYSTEM simply by sending a malformed RPC packet. No user interaction, no authentication credentials, just pure, unadulterated remote root access. It affects a massive range of Windows Server versions, from 2000-era relics up to Server 2025.

The Hook: The Boring Service That Could Kill You

In the grand theater of Windows exploitation, we usually focus on the stars: SMB, RDP (BlueKeep), or Exchange. But lurking in the background are the stagehands—boring, administrative services that run with the highest privileges imaginable. Enter the Windows Remote Desktop Licensing Service (TermServLicensing).

Its job is mundane: managing Client Access Licenses (CALs) for RDP connections. It’s the bureaucrat of the operating system, counting heads and checking paperwork. Because it needs to manage system-wide licenses, it runs as NT AUTHORITY\SYSTEM. That is the absolute highest privilege level on a Windows machine—higher than Administrator. If you own this service, you own the box, the domain credentials stored in memory, and arguably the entire network segment.

Here’s the kicker: this service exposes an RPC interface over a named pipe (\pipe\TermServLicensing). Historically, this pipe was accessible anonymously. While modern Windows versions have tightened up named pipe permissions, many enterprise configurations (or legacy domains) still leave these pipes exposed to the network. An attacker doesn't need a password; they just need to ask the Licensing Service a question it doesn't know how to answer.

The Flaw: Math is Hard, Especially in C++

The vulnerability (CVE-2024-38077) is a classic Heap-based Buffer Overflow located in a function named CDataCoding::DecodeData(). As the name suggests, this function is responsible for decoding data—specifically, Base64 encoded strings passed via RPC messages. This feels like a vulnerability from the late 90s that somehow survived two decades of code review.

The root cause is an integer handling error during the calculation of the required buffer size. When the service receives a Base64 string, it tries to calculate how much heap memory it needs to allocate to store the decoded binary output. In a proper implementation, you calculate the size, allocate the buffer, and then decode.

However, MadLicense fails to account for specific malformed input lengths correctly. It allocates a buffer that is too small for the resulting decoded data. When the decoding loop runs, it happily writes past the end of the allocated chunk. This isn't a stack overflow where we just smash a return address; this is a heap overflow. We are corrupting the dynamic memory of the application, which makes exploitation slightly more artistic but equally deadly.

The Code: Anatomy of a Heap Smash

Let's look at the logic flow (simplified for clarity) to understand why the heap creates a crater. The vulnerable code path is triggered via the RPC method TLSRpcTelephoneRegisterLKP (Opnum 49).

// Pseudocode of the vulnerable logic
void CDataCoding::DecodeData(char* inputBase64, int inputLen) {
    // 1. Calculate size. 
    // The flaw: This calculation underestimates size for specific
    // malformed Base64 inputs with padding anomalies.
    int allocSize = CalculateDecodedSize(inputLen);
 
    // 2. Allocate Heap Memory
    BYTE* buffer = (BYTE*)HeapAlloc(GetProcessHeap(), 0, allocSize);
 
    // 3. Decode
    // The decoding routine doesn't strictly check bounds against allocSize
    // It trusts the math from step 1.
    Base64Decode(inputBase64, inputLen, buffer);
}

The CalculateDecodedSize function likely assumed standard Base64 padding rules. By providing a string that violates these assumptions (or by leveraging integer overflow in the size calculation itself depending on the specific patch version), the allocSize ends up being smaller than the actual bytes written by Base64Decode.

When Base64Decode writes to buffer, it continues writing past the end of the allocated chunk. In the Windows Heap Manager, the data immediately following your chunk usually contains Heap Metadata (headers that tell Windows where the next free chunk is). By overwriting this metadata, an attacker can trigger a "write-what-where" condition when the heap manager tries to coalesce or free chunks later. This allows the attacker to overwrite function pointers (like Virtual Function Tables) elsewhere in the application memory.

The Exploit: Weaponizing Bureaucracy

To exploit this, we don't need a complex phishing campaign. We just need network access to the RPC port (usually 135) or SMB (445). The attack chain is embarrassingly straightforward for a vulnerability this critical.

First, we establish a DCE/RPC connection to the TermServLicensing pipe. We send a Bind request to the interface UUID. Once bound, we call TLSRpcConnect (Opnum 1) to get a context handle. This basically tells the server, "Hi, I'm a client, please allocate some memory for our session."

Next, we invoke TLSRpcTelephoneRegisterLKP (Opnum 49). This function expects a "telephone number" or license key pack identifier, but it accepts a variable-length character array. We pass a massive, malformed Base64 string designed to trigger the miscalculation described above.

> [!NOTE] > Heap Grooming is Key: In a real-world exploit, we wouldn't just send the overflow packet immediately. We would first spray the heap with other RPC calls to arrange memory chunks in a predictable pattern. We want our vulnerable chunk to sit right next to a C++ object with a Virtual Table (vtable).

When the overflow occurs, we overwrite the vtable pointer of the adjacent object. The next time the application tries to call a method on that object (e.g., Object->Destructor()), it instead jumps to an address we control—typically a ROP (Return-Oriented Programming) chain that disables Data Execution Prevention (DEP) and executes our shellcode.

The Impact: Game Over

The impact cannot be overstated. We are talking about Remote Code Execution as SYSTEM. This is the "God Mode" of Windows. If an attacker lands this on a Domain Controller (where this service is often running), they can dump the NTDS.dit file, extract every password hash in the domain, and create a Golden Ticket.

Even on a standalone server, the attacker has total control. They can install ransomware, install persistent backdoors, or use the machine as a pivot point to attack the rest of the internal network. Because the exploit happens in memory and creates no files on disk (initially), it can bypass traditional antivirus signatures.

With an EPSS score hovering around 87%, the automated bots are already sniffing for this. The only thing stopping widespread wormable chaos is that many firewalls block RPC ports from the internet. However, inside a corporate network, those ports are almost always open between servers.

The Fix: Patch or Perish

Microsoft released patches in July 2024. If you haven't applied them, stop reading this and go do it. The patch modifies CDataCoding::DecodeData to correctly validate the buffer size against the maximum possible decoded length and adds strict bounds checking during the copy operation.

Immediate Mitigation Strategy:

  1. Patch: Apply the relevant KB for your OS (e.g., KB5040437 for Server 2022).
  2. Disable the Service: If the server is not actually acting as a Remote Desktop Licensing Server (many admins install the role "just in case" or by accident via the RDSH role), disable the TermServLicensing service immediately.
  3. Firewalling: Ensure TCP ports 135 and 445 are not exposed to the internet. Internally, restrict RPC access to only administrative subnets.

This vulnerability is a stark reminder: unused services are unmanaged risks. Turn them off.

Official Patches

MicrosoftOfficial Microsoft Security Update Guide for CVE-2024-38077

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
87.07%
Top 1% most exploited
170,000
Estimated exposed hosts via Shadowserver / Shodan

Affected Systems

Windows Server 2025Windows Server 2022Windows Server 2019Windows Server 2016Windows Server 2012 R2Windows Server 2012Windows Server 2008 R2 SP1

Affected Versions Detail

Product
Affected Versions
Fixed Version
Windows Server 2022
Microsoft
< 10.0.20348.258210.0.20348.2582
Windows Server 2019
Microsoft
< 10.0.17763.605410.0.17763.6054
Windows Server 2016
Microsoft
< 10.0.14393.715910.0.14393.7159
AttributeDetail
Vulnerability IDCVE-2024-38077
TypeHeap-based Buffer Overflow
CVSS v3.19.8 (Critical)
EPSS Score87.07% (99.42nd Percentile)
Attack VectorNetwork (RPC over SMB/TCP)
Privileges RequiredNone
ImpactRCE as SYSTEM

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1210Exploitation of Remote Services
Lateral Movement
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-122
Heap-based Buffer Overflow

A heap-based buffer overflow occurs when a product calculates a buffer size incorrectly, allocating a heap chunk that is smaller than the data written to it.

Known Exploits & Detection

GitHubPoC implementation for MadLicense triggering the heap overflow via Opnum 49.
GitHubScanner to verify vulnerability by triggering a controlled crash (Access Violation).

Vulnerability Timeline

Vulnerability published and patched by Microsoft
2024-07-09
Technical details regarding 'MadLicense' and DecodeData emerge
2024-07-20
Public PoC exploits and scanners appear on GitHub
2024-08-01

References & Sources

  • [1]Microsoft MSRC Advisory
  • [2]CWE-122: Heap-based Buffer Overflow

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.