
Un PoC pour CVE-2018-7249
Une vulnérabilité a été découverte dans secdrv.sys tel que fourni dans Microsoft Windows Vista, Windows 7, Windows 8 et Windows 8.1 avant KB3086255, et tel que fourni dans Macrovision SafeDisc. Deux appels minutieusement synchronisés à IOCTL 0xCA002813 peuvent provoquer une condition de concurrence menant à une use-after-free. Lorsqu'elle est exploitée, un attaquant non privilégié peut exécuter du code arbitraire dans le noyau.
La vulnérabilité a été signalée à Microsoft, et comme elle n'affecte pas une machine Windows à jour (uniquement les versions antérieures à KB3086255), ils ne prendront aucune mesure. A été testée et exploitée avec succès sur Windows 7 x86.
Également lié à CVE-2018-7250.

Ceci documente ma petite recherche sur le pilote secdrv.sys. Tous les comportements décrits du pilote ont été rétroconçus et peuvent être incorrects/inexacts.
Le décalage 0x4 du tampon d'entrée vers l'IOCTL (0x0CA002813) contient un nombre que j'appellerai le TYPE. La fonction de gestion principale de cet IOCTL (0x0CA002813), sub_11A88 reçoit 3 types différents : 0x96, 0x97 et 0x98.
Après que l'IOCTL de type 0x96 a alloué un nouveau bloc et l'a initialisé, mais pas complètement, il copie le bloc en mode utilisateur. 16 bits dans le bloc nouvellement alloué n'ont pas été initialisés et contiennent des données d'allocations PagedPool précédentes. Les bits non initialisés sont ensuite copiés en mode utilisateur à .text:00011BE9 par l'instruction REP MOVSD. Code PoC ici.
Lorsque l'IOCTL de type 0x97 est appelé, il trouve le bloc nécessaire, précédemment alloué avec le type 0x96, par son tag. Si l'allocation a déjà été libérée par l'IOCTL de type 0x97, DeviceIoControl renvoie une erreur. La vulnérabilité ici est que l'allocation utilisée par le type 0x97 peut être libérée PENDANT son opération (car aucun mécanisme de synchronisation n'est utilisé), devenant ainsi une use-after-free si la condition de concurrence est gagnée. Si un attaquant parvient à libérer le bloc pendant l'opération de l'IOCTL de type 0x97 (en utilisant le type 0x98) et allouer un nouveau bloc, contrôlé par lui, exactement au même emplacement mémoire, il peut remplacer un pointeur vers une autre structure, qui contient un pointeur de fonction pouvant être utilisé pour finalement détourner le flux d'exécution du pilote et exécuter du code arbitraire en ring 0. Étant donné que la routine de chiffrement est effectuée sur un tampon fourni par l'utilisateur, qui peut être énorme en taille, le chiffrement peut prendre beaucoup de temps à s'exécuter, offrant ainsi une fenêtre de temps parfaite pour que l'IOCTL de type 0x98 libère le bloc pendant qu'il est encore utilisé. Les fenêtres de temps peuvent être si longues (plus d'une seconde !) que la condition de concurrence peut être gagnée de manière fiable dès la première tentative. La use-after-free commence à .text:00011B68, et l'appel réel, qui sera détourné pour sauter vers le shellcode, a lieu à .text:00011B86.
Les étapes suivies pour exploiter avec succès cette vulnérabilité sont les suivantes :
Système d'exploitation : Windows 7 Kernel Version 7600 MP (1 procs) Free x86 compatible Built by: 7600.16385.x86fre.win7_rtm.090713-1255 Machine virtuelle : 4 Go de RAM, 1 processeur Matériel : Windows 10 Pro 64 bits, carte mère Gigabyte Z370 HD3, 16 Go de RAM, Intel i5-8400 2.80 GHz (6 processeurs)