Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-24990_POC — Preuve de concept CVE-2025-24990 (pilote d'Agere Systems) | Kitploit
Outils/GitHubGitHub/moiz-2x/cve-2025-24990_poc
Escalade de PrivilègesFrameworks d'ExploitationAnalyse des VulnérabilitésExploitationExploitation de Binaires
GitHubmoiz-2x/cve-2025-24990_poc

CVE-2025-24990_POC

Preuve de concept CVE-2025-24990 (pilote d'Agere Systems)

Voir le dépôt
5913il y a 9 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Pilote du modem Agere Windows (ltmdm64.sys). Ce pilote est très ancien et n'est pas chargé par défaut sur ma machine de test, je vais donc l'exploiter dans un scénario BYOVD. Fait intéressant, selon mes recherches, ce pilote existe depuis Windows 7 et possède au moins un bug. ici

À cette époque, le MSRC n'a pris aucune mesure 🤡

Vulnérabilités

Certains IOCTL de ce pilote utilisent METHOD_NEITHER mais ne vérifient pas si le tampon d'adresse fourni par l'appelant provient du mode utilisateur ou du mode noyau. Voici un exemple de code IOCTL que j'ai décodé avec OSR :

Cela signifie que vous pouvez fournir une adresse noyau à l'API DeviceIoControl et le pilote la traitera normalement.

Notez que vous devez d'abord contourner kASLR pour divulguer l'adresse noyau. J'utiliserai EnumDeviceDrivers (sur Windows 24h2, vous avez besoin de SeDebugPriv pour cela).

Déréférencement nul

Le problème se trouve dans l'IOCTL 0x802b200f (ud_response). Encore une fois, ce dispatch d'IOCTL ne valide pas l'adresse que je fournis depuis le mode utilisateur, mais je l'exploiterai plus tard.

Le ud_response appelle ll_load_diagnostics, et j'atteindrai le code suivant :

Au début, la variable globale eeprom n'est pas initialisée, elle contiendra donc NULL. Voici un code simple qui déclenchera cela.

Je l'exploiterai plus tard.

Point d'entrée de l'exploit 0x802b2003

Cet IOCTL convertit simplement la chaîne de version du pilote "8.36" en nombre 0x836 (un DWORD) et l'écrit à l'adresse fournie par l'appelant (grâce à METHOD_NEITHER). Techniquement, je peux écrire ces quatre octets (36 08 00 00) à une adresse noyau arbitraire. J'exploiterai cela pour écraser les variables globales du pilote et modifier le flux d'exécution.

J'appellerai cet IOCTL 0x802b2003 IOCTL_GET_VERSION.

Exploit

Octet nul arbitraire :

En revenant au cas du déréférencement nul, j'utilise l'API VirtualAlloc pour allouer une adresse fixe (0x083600000000). J'utilise ensuite IOCTL_GET_VERSION pour écrire dans *(eeprom + 4) les quatre octets décrits ci-dessus. Lorsque le pilote déréférence ensuite eeprom, il lira depuis l'adresse que j'ai allouée.

Après avoir corrigé le déréférencement nul, l'IOCTL écrit une chaîne à l'adresse que je fournis depuis le mode utilisateur, en fonction de la taille du tampon.

Ce code démontre simplement ce que j'ai décrit ci-dessus : allouer un tampon et le remplir avec 0xAA, corriger le déréférencement nul, puis appeler le pilote. Notez que j'alloue 11 octets mais ne fournis qu'une taille de tampon de 10 au pilote pour observer son comportement.

Il écrit une séquence fixe d'octets dans mon tampon puis met à zéro le dernier octet (le 11ᵉ), même si je ne fournis qu'une taille de 10. Il remplace le dernier 0xAA de mon tampon par 0x00. Cela indique que si je fournis une taille de 0, le pilote écrit quand même un seul octet 0x00 à l'adresse cible.

Décrémentation arbitraire

Maintenant que j'ai l'octet nul et l'écriture arbitraire avec 4 octets fixes, construisons une autre primitive.

Cet IOCTL définira la variable globale LtMsgEvent sur mon tampon utilisateur, puis vérifiera si WDM est nul et le remettra à zéro.

Ensuite, dans 0x802b2207, il appellera l'API ObfReferenceObject.

À l'état initial, WDM est nul, mais avec l'aide de IOCTL_GET_VERSION, je peux définir WDM sur 0x36 (sa taille n'est que d'un octet) et LtMsgEvent reste mon tampon. Ensuite, je mets WDM à zéro et j'appelle 0x802b2207. Enfin, j'atteins ObfReferenceObject. J'appellerai ces deux IOCTL IOCTL_SET_LtMsgEvent et IOCTL_DEREF_LtMsgEvent.

La technique d'exploitation utilisant ObfReferenceObject modifie le PreviousMode de notre KTHREAD de UserMode à KernelMode ; vous pouvez en lire plus ici. Cependant, Windows a corrigé cet exploit, nous ne pouvons donc pas l'utiliser.

Mais la primitive dans ObfReferenceObject existe toujours. L'API soustrait 0x30 de l'adresse que nous fournissons, convertit le résultat en entier de 8 octets, puis soustrait 1.

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

Mais le problème est qu'elle vérifie si la valeur suivante est 0 ou si la valeur actuelle est < 1 (interprétée comme un entier signé de 8 octets). Si l'une ou l'autre condition est vraie, elle saute vers KeBugCheckEx et fait planter le système.

Écriture arbitraire

Avec la décrémentation arbitraire en main, je dois trouver un autre endroit pour écrire l'octet 0xFF, puis le décrémenter jusqu'à l'octet souhaité, et j'ai trouvé cet IOCTL 0x802b2243 :

Nous nous concentrerons sur la branche flip. pbVar5 est l'adresse que je fournis depuis le mode utilisateur et peut être n'importe quelle adresse cible de mon choix. J'écris l'octet 0x0C dans DAT_TARGET_EX (avec l'aide de IOCTL_GET_VERSION et de la primitive de décrémentation arbitraire), et je mets également à zéro 1 octet à l'adresse cible. Le premier appel à cet IOCTL définit 0xC0 à l'adresse cible, qui est ensuite décrémenté à 0xBF. Un deuxième appel définit 0xFF à l'adresse cible (0xBF | 0xC0 = 0xFF). Une fois que la cible contient 0xFF, je la décrémente simplement jusqu'à la valeur souhaitée.

J'écrirai un octet à la fois et je ferai attention au KeBugCheckEx dans ObfReferenceObject.

Lecture arbitraire

Pour la primitive de lecture, j'utilise la technique décrite ici (@carrot_c4k3). J'écrase simplement l'objet UNICODE_STRING dans le noyau (ExpManufacturingInformation) puis j'appelle NtQuerySystemInformation. Parce que ObfReferenceObject appelle KeBugCheckEx, je mettrai à zéro 8 octets adjacents à ExpManufacturingInformation.

Voilà, nous avons maintenant une lecture/écriture arbitraire ; nous pouvons utiliser ces primitives pour faire beaucoup de choses. Le pilote n'est pas chargé par défaut, je vais donc l'exploiter dans un scénario BYOVD et définir le PPL d'un processus.

Exploit sur Windows 11 22H2+ :

L'exploit que j'ai décrit ci-dessus fonctionne sur toutes les versions de Windows mais est instable en raison du KeBugCheckEx. Mais sur Windows 11 22h2+, il existe une technique appelée ioring. Cette technique consiste simplement à écraser ioring->Buffer avec une adresse contrôlable. Concrètement, nous pouvons écraser ioring->Buffer et sa taille avec 0x083600000000 et 0x836 respectivement (en utilisant IOCTL_GET_VERSION). Avec cette technique, je n'effectue que 2 écritures puis j'utilise la primitive R/W de manière très stable. Notez que cette approche nécessite de divulguer l'adresse noyau.

Exécution de l'exploit

Windows ne charge pas le pilote par défaut. Vous devez donc le charger manuellement. Le fichier ltmdm64.sys se trouve dans C:\Windows\System32\DriverStore\...\ltmdm64.sys ; exécutez cette commande en tant qu'administrateur puis exécutez l'exploit :

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

L'exploit utilisera la technique ioring pour désactiver le PPL de lsass.exe et utilisera ma technique data-only pour définir le PPL sur notepad.exe (sur win 11 24h2, SeDebugPriv doit être activé).

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

Auteurs du CVE

J'ai signalé ce bug à ZDI. Mais il semble qu'il soit en double avec la soumission de Fabian Mosch et Jordan Jay au MSRC, donc ce PoC montre simplement le bug et apprécie leur travail. Presque mon premier CVE 😍

Télécharger l’outil