
CVE-2021-43229 : procédure pas à pas
Windows NTFS Vulnérabilité d'élévation de privilèges
Distincte de :
Correctif : 14 décembre 2021
Selon @AravGarg3 sur Twitter, CVE-2021-43229 semble être exploitable et lié à un débordement d'entier.
Source : https://twitter.com/AravGarg3/status/1479447843458863104
| Versions mineures de Windows 10 | Dates de publication |
|---|---|
| 1387 | 11/22/2021 |
| 1415 | 12/14/2021 |
En utilisant BinDiff avec IDA Pro, le diffing de correctif donne les modifications suivantes :
Trois candidats se démarquent :
Selon le Guide de mise à jour de sécurité de Microsoft de décembre, quatre CVE sont liées à NTFS :
CVE-2021-43240 semble être lié à NtSetShortNameInfo.
NtfsRenameToPrivateDir, TxfAllocateAndStoreNameForTxLogging et TxAllocateFullFilePathForChangeNotify ont tous les trois la même nouvelle vérification de longueur, et semblent être liés à CVE-2021-43229, CVE-2021-43230 et CVE-2021-43231, pas nécessairement dans cet ordre. Actuellement, il n'est pas possible de savoir lequel est lequel, Microsoft est un peu avare de ces informations.
Dans les trois CVE, un débordement d'entier se produit lors du calcul de la taille d'allocation (longueur du chemin du répertoire + longueur du nom de fichier), conduisant à un débordement de tampon dans le pool avec les deux memmove suivants du chemin du répertoire et du nom de fichier.
NtfsRenameToPrivateDirLe chemin vers NtfsRenameToPrivateDir est présenté ci-dessous :
NtfsCommonSetInformation
|__________________
| |
v v
NtfsSetLinkInfo NtfsSetRenameInfo
|__________________|
|
v
NtfsRemoveSupersededTarget
|
v
NtfsRenameToPrivateDir
Tout d'abord, pour appeler NtfsCommonSetInformation, il suffit d'appeler NtSetInformationFile. Ensuite, pour passer par NtfsSetLinkInfo et NtfsSetRenameInfo, utilisez respectivement FileLinkInformationEx et FileRenameInformationEx comme classe d'informations de fichier dans NtSetInformationFile.
Pour atteindre NtfsRemoveSupersededTarget via NtfsSetRenameInfo, il est nécessaire de définir les indicateurs FILE_RENAME_REPLACE_IF_EXISTS et FILE_RENAME_POSIX_SEMANTICS. Renommez un fichier avec le nom d'un fichier existant pour accéder à NtfsRemoveSupersededTarget. Pour NtfsRenameToPrivateDir, c'est un peu délicat, car le fichier remplacé doit être ouvert par un processus.
Malheureusement, une vérification de longueur est effectuée avant l'appel à NtfsRemoveSupersededTarget.
La méthode avec NtfsSetLinkInfo est similaire à NtfsSetRenameInfo, seuls les noms des indicateurs diffèrent, leurs significations restent les mêmes. Mais tout comme NtfsSetRenameInfo, une autre vérification est effectuée avant l'appel à NtfsRemoveSupersededTarget.
TxfAllocateAndStoreNameForTxLoggingLe chemin vers TxfAllocateAndStoreNameForTxLogging est présenté ci-dessous :
NtfsCommonCreate
|
v
NtfsCreateNewFile
|
v
TxfNewFileCreate
|
v
TxfAllocateAndStoreNameForTxfLogging
Tout d'abord, pour appeler NtfsCommonCreate, il suffit d'appeler CreateFile.
La fonction TxfNewFileCreate est préfixée avec Txf qui signifie "Transactional NTFS" et est appelée lorsqu'un fichier transactionnel est créé. TxfAllocateAndStoreNameForTxfLogging est appelée au cours du processus afin de stocker le chemin du fichier transactionnel.
Seuls deux appels sont nécessaires :
Le code vulnérable de TxfAllocateAndStoreNameForTxLogging est présenté ci-dessous :
...
and di, 2
add di, [rsi+UNICODE_STRING.Length] ; File name
add di, [rsp+68h+RelativeNormalizedDirectoryPath.Length] ; OVERFLOW HERE
cmp [rsp+68h+arg_20], r12b
jnz loc_16592C
movzx edx, di
add rdx, size UNICODE_STRING ; NumberOfBytes
mov ecx, cs:PoolType
or ecx, 10h ; PoolType
mov r8d, 'afxT' ; Tag
call cs:__imp_ExAllocatePooliWthTag
...
Pour déclencher le débordement, il est nécessaire de créer un fichier avec une longueur excessive, plus de 0xFFFF octets (32767 caractères).
Un problème qui apparaît est qu'un nom de fichier ou de répertoire ne peut pas dépasser 256 caractères - y compris le caractère NULL. Pour résoudre ce problème, l'utilisation de sous-dossiers profonds sera nécessaire. Bizarrement, ce n'est pas si facile, même avec des sous-dossiers créés avec succès, le sous-fichier ne peut pas être créé, probablement à cause de certaines vérifications effectuées en amont.
En utilisant la barre d'explorateur, on peut remarquer le format utilisé pour afficher le chemin du répertoire. Ce n'est pas ce que j'attendais, au lieu d'utiliser un chemin "classique", l'explorateur utilise le format désuet de DOS, le format court 8.3.
En conservant la création des sous-dossiers comme avant et en utilisant le nom court pour les sous-répertoires lors de la création du fichier, cela fonctionne.
Il est important de noter que 16 octets seront ajoutés à la taille débordée, ce qui correspond à la taille de la UNICODE_STRING qui représentera le chemin final. C'est parce que la mémoire demandée contiendra la UNICODE_STRING suivie du tampon de cette UNICODE_STRING.
Méthode :
Conditions actuelles :
Un write-up intéressant de Synacktiv au SSTIC 2020 pourrait être une piste à creuser, en ciblant VS Heap.
Le CVE-2020-17087, un cas similaire d'exploitation, a été présenté par PixiePoint Security en utilisant la technique mentionnée ci-dessus.
| Simi | Conf | Fonction | Infos |
|---|
| NOK | 0.98 | 0.99 | NtfsCommonSetInformation$fin$0 | Modifications de sauts |
| 0.97 | 0.99 | NtSetShortNameInfo | ||
| 0.96 | 0.99 | NtfsUpdateSecurity | ||
| NOK | 0.91 | 0.94 | NtfsRenameToPrivateDir$fin$1 | Modifications de sauts |
| 0.89 | 0.98 | NtfsInitializeFileInDirectory | ||
| OK | 0.88 | 0.95 | TxfAllocateAndStoreNameForTxLogging | Vérification de longueur |
| OK | 0.87 | 0.93 | NtfsRenameToPrivateDir | Vérification de longueur |
| OK | 0.81 | 0.95 | TxfAllocateFullFilePathForChangeNotify | Vérification de longueur |
| 0.76 | 0.94 | NtfsCommonSetInformation |