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-2023-36424 — Élévation de privilèges par corruption du pool du noyau Windows (clfs.sys) | Kitploit
Outils/GitHubGitHub/zerozenxlabs/cve-2023-36424
Escalade de PrivilègesCriminalistique MémoireAnalyse des VulnérabilitésExploitationExploitation de Binaires
GitHubzerozenxlabs/cve-2023-36424

CVE-2023-36424

Élévation de privilèges par corruption du pool du noyau Windows (clfs.sys)

Voir le dépôt
12923il y a 2 ansVé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

Informations

==============

Corruption du pool du noyau Windows (clfs.sys) Élévation de privilèges. (CVE-2023-36424)

Ce dépôt contient l'analyse technique et un exploit fonctionnel.

Auteur : Nassim Asrir (@p1k4l4) || https://www.linkedin.com/in/nassim-asrir-b73a57122/

Vulnérabilité

================

Il y a un débordement de pool dans le pilote de mini-filtre clfs.sys. Des informations à ce sujet peuvent être lues sur :

1 - https://googleprojectzero.blogspot.com/2021/01/hunting-for-bugs-in-windows-mini-filter.html

2 - https://www.zerodayinitiative.com/blog/2021/7/19/cve-2021-31969-underflowing-in-the-clouds

La raison est que le pilote ne vérifie pas suffisamment les données provenant d'un point de réanalyse NTFS.

Nous considérons la version 10.0.22621.2134 de clfs.sys (Windows 11 22H2 22621.2215)

La fonction HsmFltProcessHSMControl est responsable du traitement des FSCTLs du filtre cloud. Pour une opération avec le code 0xC0000003, elle appellera finalement HsmFltProcessUpdatePlaceholder .

Après quelques traitements, le flux d'exécution atteindra HsmiOpUpdatePlaceholderDirectory et enfin HsmpRpCommitNoLock :

root@kitploit:~
__int64 __fastcall HsmpRpCommitNoLock(__int64 a1, __int64 a2, struct _FILE_OBJECT *a3, char a4, char a5)

{ .....

v26 = FileObject; LODWORD(v9) = HsmpRpReadBuffer(*(PFLT_INSTANCE *)(v164 + 32), FileObject, (unsigned __int16 **)&P); // [1*]

HsmDbgBreakOnStatus((unsigned int)v9);

if ( (_DWORD)v9 == -1073741195 ) .....

goto LABEL_55; }

if ( (v9 & 0x80000000) != 0i64 )

goto LABEL_9;}
 

if ( (*(_DWORD *)P & 0xFFFF0FFF) != dword_1C0027650 )// Is
Cloud Reparse Tag?
{
LODWORD(v9) = 0xC000CF0B;
.....
goto LABEL_54;
}
v32 = *((unsigned __int16 *)P + 2);
v9 = (unsigned int)HsmpRpValidateBuffer((__int64)P + 8, v32); [2*]
.....
Pool2 = ExAllocatePool2(0x100i64, 0x4000i64, 'pRsH'); // [3*]
v146 = (_DWORD *)Pool2;
v13 = (void *)Pool2;
if ( Pool2 )
{
v64 = v159_10;
v65 = Pool2 + 4;
if ( v8 && *((_WORD *)v8 + 7) > 0xAu )
v64 = *((_WORD *)v8 + 7);
v9 = Pool2 + 20;
v66 = (unsigned int *)(Pool2 + 12);
*(_OWORD *)v65 = 0i64;
*(_WORD *)(Pool2 + 16) = 0;
*(_WORD *)(Pool2 + 18) = v64;
*(_DWORD *)(Pool2 + 12) = 8 * v64 + 16;
*(_DWORD *)v65 = 'pReF';
memset((void *)(Pool2 + 20), 0, 8i64 * v64);
.....
if ( v8 )
{
v127 = 10;
if ( *((_WORD *)v8 + 7) > 0xAu ) // [4*]
{
if ( WPP_GLOBAL_Control !=
(PDEVICE_OBJECT)&WPP_GLOBAL_Control
&& (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) != 0

&& BYTE1(WPP_GLOBAL_Control->Timer) >= 4u )
{
WPP_SF_qiq(WPP_GLOBAL_Control->AttachedDevice, v86,
v87, a2, *(_QWORD *)(v156 + 32), FileObject);
}
while ( v127 < *((_WORD *)v8 + 7) )
{
*(_QWORD *)(v65 + 8i64 * v127 + 16) = *(_QWORD
*)&v8[8 * v127 + 16];
memmove(
(void *)(v65 + *v66),
&v8[*(unsigned int *)&v8[8 * v127 + 20]],
*(unsigned __int16 *)&v8[8 * v127 + 18]); //
[5*]
*(_DWORD *)(v65 + 8i64 * v127 + 20) = *v66;
*v66 += *(unsigned __int16 *)(v65 + 8i64 * v127++ +
18);
}
}
}
.....
}

HsmpRpReadBuffer [1*] récupère les données du point de réanalyse. Ces données contiennent une valeur de taille WORD *((_WORD *)v8 + 7), spécifiant un nombre d'éléments structurés. Chaque élément a un champ Type, Taille et Offset vers les champs de données.

Quel type d'élément à quel endroit est strictement prédéterminé. Mais seulement pour les 10 premiers. Par exemple, le champ type du premier élément doit avoir une valeur égale à 0x7.

Le pilote exécutera HsmpRpValidateBuffer [2*] pour vérifier les données acquises. Ensuite, [3*] allouera un pool paginé d'une taille fixe de 0x4000 octets. Et si les données du point de réanalyse ont une valeur Count supérieure à 10, alors les données des éléments après le dixième seront copiées dans ce pool de taille fixe [4*] sans aucune vérification supplémentaire.

La validation dans HsmpRpValidateBuffer est insuffisante, car elle ne vérifie que les 10 premiers enregistrements.

root@kitploit:~
__int64 __fastcall HsmpRpValidateBuffer(__int64 pBuf, unsigned int a2)
{
.....
v2 = a2 - 4;
pBuf2 = pBuf + 4;
LOBYTE(v5) = 0;
v6 = 0i64;
if ( a2 <= 4 )
v2 = 0;
v7 = 0;
v8 = *(_DWORD *)pBuf & 0xF;
if ( !v8 )
{
.....
return IsReparseBufferSupported;
}
if ( v8 > 1 )
{
....
}
v9 = 0;
v66 = 0;
if ( v2 < 0x18 )
goto ERROR_EXIT;
v9 = 1;
if ( *(_DWORD *)pBuf2 != 'pReF' )
goto ERROR_EXIT;
v9 = 2;
v10 = (unsigned int *)(pBuf + 0xC);
if ( (*(_BYTE *)(pBuf + 16) & 2) != 0 && *(_DWORD *)(pBuf +
8) != RtlComputeCrc32(0, (PUCHAR)(pBuf + 0xC), v2 - 8) )
goto ERROR_EXIT;
v11 = *v10;
v9 = 3;
if ( v2 < (unsigned int)v11 )
goto ERROR_EXIT;
v12 = *(unsigned __int16 *)(pBuf2 + 0xE);
v9 = 4;
if ( !(_WORD)v12 )
goto ERROR_EXIT;
v13 = 8 * v12 + 16;

v9 = 5;
if ( v13 >= v11 )
goto ERROR_EXIT;
v9 = 0x10000;
for ( i = 0; ; ++i )
{
v15 = *(unsigned __int16 *)(pBuf2 + 0xE);
if ( (unsigned int)v12 >= 0xA ) // [1*]
v15 = 10;
if ( i >= v15 )
break;
}

Comme nous pouvons le voir, [1*] le code ne vérifie que les 10 premiers éléments et ignore le cas où il y a plus d'enregistrements.

Exploitation

=================

La taille du pool vulnérable est de 0x4000. La taille est un multiple de page, donc l'allocation de segment sera utilisée [3].

L'exploitation a utilisé la technique décrite ici [4]. L'appel à NtAlpcCreateResourceReserve créera un grand nombre de handles et l'écrasement de l'un d'eux avec le pointeur vers un objet _KALPC_RESERVE factice construit nous donnera la capacité d'écrire à une adresse noyau arbitraire.

Pour préparer la mémoire, nous allouons séquentiellement des pools de taille 0x4000, en utilisant des pipes[5]. Ensuite, nous libérerons un pool sur deux, fournissant un espace pour le buffer vulnérable.

Texte alternatif

Pour lire une adresse noyau arbitraire, l'exploit a utilisé des pipes. À cette fin, nous écraserons le pointeur AttributeValue de la structure PipeAttribute.

Texte alternatif

Et ensuite, nous pouvons voler le token système pour écraser le token dans le processus cible.

Merci de votre lecture.

Télécharger l’outil