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-2025-24990_POC — Proof of Concept CVE-2025-24990 (driver Agere Systems) | Kitploit
Strumenti/GitHubGitHub/moiz-2x/cve-2025-24990_poc
Escalation di PrivilegiFramework di ExploitAnalisi delle VulnerabilitàExploitBinary Exploitation
GitHubmoiz-2x/cve-2025-24990_poc

CVE-2025-24990_POC

Proof of Concept CVE-2025-24990 (driver Agere Systems)

Vedi Repository
59139 mesi faRevisionato da Kitploit

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

Windows Agere Modem Driver (ltmdm64.sys). Questo driver è molto vecchio e non viene caricato di default sulla mia macchina di test, quindi lo sfrutterò in uno scenario BYOVD. Curiosamente, secondo le mie ricerche questo driver esisteva su Windows 7 e ha almeno un bug. qui

A quel tempo, MSRC non ha intrapreso alcuna azione 🤡

Vulnerabilità

Alcuni IOCTL all'interno di questo driver utilizzano METHOD_NEITHER ma non verificano se l'indirizzo del buffer fornito dal chiamante proviene dalla modalità utente o dalla modalità kernel. Ecco un esempio di codice IOCTL che ho decodificato con OSR:

Ciò significa che puoi fornire un indirizzo kernel all'API DeviceIoControl e il driver lo gestirà normalmente.

Nota che devi prima bypassare kASLR per divulgare l'indirizzo kernel, userò EnumDeviceDrivers (Su Windows 24h2 hai bisogno di SeDebugPriv per farlo).

Null Dereference

Il problema è nell'IOCTL 0x802b200f (ud_response). Ancora una volta, questo dispatch IOCTL non valida l'indirizzo che fornisco dalla modalità utente, ma lo sfrutterò più avanti.

ud_response chiama ll_load_diagnostics, e raggiungerò il seguente codice:

All'inizio la variabile globale eeprom non è inizializzata, quindi conterrà NULL. Ecco un semplice codice che attiverà questo.

Lo sfrutterò più avanti.

Punto di ingresso dell'exploit 0x802b2003

Questo IOCTL converte semplicemente la stringa della versione del driver "8.36" nel numero 0x836 (un DWORD) e lo scrive all'indirizzo fornito dal chiamante (grazie a METHOD_NEITHER). Tecnicamente, posso scrivere questi quattro byte (36 08 00 00) a un indirizzo kernel arbitrario. Sfrutterò questo per sovrascrivere le variabili globali del driver e cambiare il flusso di esecuzione.

Chiamerò questo 0x802b2003 IOCTL_GET_VERSION

Exploit

Null arbitrario di 1 byte:

Tornando al caso di null dereference, uso l'API VirtualAlloc per allocare un indirizzo fisso (0x083600000000). Poi uso IOCTL_GET_VERSION per scrivere a *(eeprom + 4) i quattro byte descritti sopra. Quando il driver successivamente dereferenzia eeprom, leggerà dall'indirizzo che ho allocato.

Dopo aver corretto la null dereference, l'IOCTL scrive una stringa all'indirizzo che fornisco dalla modalità utente, in base alla dimensione del buffer.

Questo codice dimostra semplicemente ciò che ho descritto sopra: alloca un buffer e lo riempie con 0xAA, corregge la null dereference, poi chiama il driver. Nota che alloco 11 byte ma fornisco solo una dimensione del buffer di 10 al driver per vedere come si comporta.

Scrive una sequenza fissa di byte nel mio buffer e poi azzera il byte finale (l'11°), anche se fornisco solo una dimensione di 10. Sostituisce l'ultimo 0xAA nel mio buffer con 0x00. Questo indica che se fornisco una dimensione di 0, il driver scrive comunque un singolo byte 0x00 all'indirizzo di destinazione.

Decremento arbitrario

Ora ho il null e l'arbitrario con 4 byte fissi, creiamo altre primitive.

Questo IOCTL imposterà il globale LtMsgEvent al mio buffer utente, poi verificherà che WDM sia null e lo imposterà di nuovo a zero.

Poi in 0x802b2207 chiamerà l'API ObfReferenceObject.

Nello stato iniziale WDM è null, ma con l'aiuto di IOCTL_GET_VERSION posso impostare WDM a 0x36 (la sua dimensione è solo 1 byte) e LtMsgEvent è ancora il mio buffer. Poi azzererò WDM e chiamerò 0x802b2207. Infine raggiungo ObfReferenceObject. Chiamerò questi due ioctl IOCTL_SET_LtMsgEvent e IOCTL_DEREF_LtMsgEvent.

La tecnica di exploit che usa ObfReferenceObject cambia il PreviousMode del nostro KTHREAD da UserMode a KernelMode, puoi leggerne qui. Tuttavia, Windows ha corretto questo exploit, quindi non possiamo usarlo.

Ma la primitiva in ObfReferenceObject esiste ancora. L'API sottrae 0x30 dall'indirizzo che forniamo, converte il risultato in un intero a 8 byte, e poi sottrae 1.

    *(signed long long)(LtMsgEvent-0x30) -= 1

Ma il problema è che verifica se il valore successivo è 0 o se il valore corrente è < 1 (interpretato come un intero con segno a 8 byte). Se una delle due condizioni è vera, salta a KeBugCheckEx e manda in crash il sistema.

Scrittura arbitraria

Con il decremento arbitrario in mano, devo trovare un altro posto dove scrivere il byte 0xFF e poi decrementarlo al byte che voglio, e ho trovato questo ioctl 0x802b2243:

Ci concentreremo sul ramo flip. pbVar5 è l'indirizzo che fornisco dalla modalità utente e può essere qualsiasi indirizzo di destinazione che scelgo. Scrivo il byte 0x0C a DAT_TARGET_EX (con l'aiuto di IOCTL_GET_VERSION e della primitiva di decremento arbitrario), e azzero anche 1 byte all'indirizzo di destinazione. La prima chiamata a questo IOCTL imposta 0xC0 all'indirizzo di destinazione, che viene poi decrementato a 0xBF. Una seconda chiamata imposta 0xFF all'indirizzo di destinazione (0xBF | 0xC0 = 0xFF). Una volta che la destinazione contiene 0xFF, lo decremento semplicemente al valore desiderato.

Scriverò un byte alla volta e starò attento al KeBugCheckEx in ObfReferenceObject.

Lettura arbitraria

Per la primitiva di lettura uso la tecnica descritta qui (@carrot_c4k3). Semplicemente sovrascrivo l'oggetto UNICODE_STRING nel kernel (ExpManufacturingInformation) e poi chiamo NtQuerySystemInformation. A causa di ObfReferenceObject che chiama KeBugCheckEx, azzererò 8 byte adiacenti a ExpManufacturingInformation.

Questo è tutto, ora abbiamo R/W arbitrario, possiamo usare queste primitive per fare molte cose. Il driver non è caricato di default, quindi lo sfrutterò in uno scenario BYOVD e imposterò il PPL di un processo.

Exploit su Windows 11 22H2+:

L'exploit che ho descritto sopra funziona su tutte le versioni di Windows ma è instabile a causa del KeBugCheckEx. Ma su Windows 11 22h2+ c'è una tecnica chiamata ioring. Questa tecnica sovrascrive semplicemente ioring->Buffer con un indirizzo controllabile. Concretamente, possiamo sovrascrivere ioring->Buffer e la sua dimensione rispettivamente con 0x083600000000 e 0x836 (usando IOCTL_GET_VERSION). Usando questa tecnica eseguo solo 2 scritture e poi uso la primitiva R/W in modo molto stabile. Nota che questo approccio richiede la divulgazione dell'indirizzo kernel.

Esecuzione dell'Exploit

Windows non carica il driver nello stato predefinito. Quindi devi caricarlo manualmente. Il file ltmdm64.sys si trova in C:\Windows\System32\DriverStore\...\ltmdm64.sys, esegui questo comando come amministratore ed esegui l'exploit:

sc create ltmdm64_srv binPath="C:\Windows\System32\DriverStore...\ltmdm64.sys" type=kernel && sc start ltmdm64_srv

L'exploit userà la tecnica ioring per disattivare il PPL di lsass.exe e userà la mia tecnica solo-dati per impostare il PPL a notepad.exe (su win 11 24h2 è necessario che SeDebugPriv sia abilitato)

https://github.com/user-attachments/assets/05a35b38-d26c-484f-9fb7-137f8fe8c079

Autori CVE

Ho segnalato questo bug a ZDI. Ma sembra che sia un duplicato della segnalazione di Fabian Mosch e Jordan Jay a MSRC, quindi questo PoC mostra solo il bug e apprezza il loro lavoro. Quasi il mio primo CVE 😍

Scarica lo strumento