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-2023-6702 — Chrome Renderer 1day RCE mediante Type Confusion en Async Stack Trace (v8ctf submission) | Kitploit
Herramientas/GitHubGitHub/kaist-hacking/cve-2023-6702
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebCTFAprendizaje y EducaciónExplotación de Binarios
GitHubkaist-hacking/cve-2023-6702

CVE-2023-6702

Chrome Renderer 1day RCE mediante Type Confusion en Async Stack Trace (v8ctf submission)

Ver Repositorio
8697hace 2 añosRevisado por Kitploit

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

Chrome Renderer 1day RCE via Type Confusion in Async Stack Trace (CVE-2023-6702)

Resumen

Esta vulnerabilidad permitía a un atacante remoto ejecutar código arbitrario dentro del proceso renderizador de Chrome.

Había una comprobación de tipo insuficiente en el código de manejo de trazas de pila asíncronas. Conduce a una confusión de tipos entre FunctionContext y NativeContext, causando un acceso ilegal al valor JSGlobalProxy->hash. Mediante heap spraying, el atacante pudo inyectar un marco de pila asíncrono falso y construir la primitiva fakeobj. Usando la primitiva fakeobj, el atacante pudo lograr la ejecución de código arbitrario en el proceso renderizador de Chrome.

Puedes consultar nuestras diapositivas de TyphoonCon 2024.

Proveedor / Producto / Versión

  • Google Chrome
  • Versiones afectadas: anteriores a 120.0.6099.109
  • Versión corregida: 120.0.6099.109

Cronología

  • 2020-05-13: Bug introducido - [Promise.any] Implementar trazas de pila asíncronas para Promise.any
  • 2023-11-10: Reporte del bug - Seguridad: V8 Debug check failed: LAST_TYPE >= value
  • 2023-11-15: Parche - [promises, async stack traces] Corregir el caso cuando el closure se ha ejecutado
  • 2023-12-12: Advisory - https://chromereleases.googleblog.com/2023/12/stable-channel-update-for-desktop_12.html
  • 2024-01-12: Envío a v8CTF <-- El momento en que trabajamos en esta vulnerabilidad
  • 2024-02-23: Reporte del bug divulgado

Contexto

Traza de pila asíncrona

La asincronía es una de las características más importantes de JavaScript. En el pasado, era difícil depurar código asíncrono con la pila de errores porque las funciones asíncronas no se capturaban en la pila de errores. Las funciones asíncronas suspendidas se almacenan en la cola de callbacks del bucle de eventos, no en la pila de llamadas, por lo que la pila de errores no contenía la función asíncrona. Para resolver este problema, V8 ofrece la funcionalidad de "traza de pila asíncrona" (por defecto desde V8 v7.3) para capturar funciones asíncronas en la pila de errores. ([v8 blog], [v8 docs])

Closure de resolución de elementos de Promise.all

El "Closure de resolución de elementos de Promise.all" es una función auxiliar para resolver las promesas de entrada en la función Promise.all. La función Promise.all toma un array de promesas y devuelve una promesa que se resuelve cuando todas las promesas de entrada se han resuelto. El "Closure de resolución de elementos de Promise.all" es un manejador de resolución de cada promesa de entrada en la función Promise.all. Su función es resolver la promesa de entrada y almacenar el valor de cumplimiento en el array de resultados.

Hay 2 puntos a tener en cuenta sobre la función:

  1. Es una función intrínseca integrada y no es directamente accesible desde el código JavaScript.
  2. El contexto de la función se utiliza como un marcador para comprobar si la función ha sido ejecutada o no. Tiene FunctionContext hasta que se llama, y luego tiene NativeContext después de ser llamada. (código v8)

La vulnerabilidad

Clase de bug: Confusión de tipos entre FunctionContext y NativeContext

Detalles de la vulnerabilidad:

La vulnerabilidad se puede desencadenar capturando una traza de pila asíncrona con la función "Closure de resolución de elementos de Promise.all" ya ejecutada o funciones integradas intrínsecas similares. En este exploit, utilicé la función "Closure de resolución de elementos de Promise.all" como ejemplo.

Cuando se lanza un error en el código JavaScript, V8 captura la pila de errores de la pila y añade los marcos de pila asíncronos de la microtarea actual [1].

CallSiteBuilder builder(isolate, mode, limit, caller);
VisitStack(isolate, &builder);

// Si --async-stack-traces está habilitado y la "microtarea actual" es un
// PromiseReactionJobTask, intentamos enriquecer la traza de pila con marcos
// asíncronos.
if (v8_flags.async_stack_traces) {
    CaptureAsyncStackTrace(isolate, &builder);
}

La función CaptureAsyncStackTrace [[2]] recorre la cadena de promesas y añade el marco de pila asíncrono según el tipo de llamada asíncrona (p. ej., await, Promise.all, Promise.any).

A continuación se muestra el fragmento de la función CaptureAsyncStackTrace que maneja el caso de Promise.all:

} else if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
                                Builtin::kPromiseAllResolveElementClosure)) {
    Handle<JSFunction> function(JSFunction::cast(reaction->fulfill_handler()),
                                isolate);
    Handle<Context> context(function->context(), isolate);
    Handle<JSFunction> combinator(context->native_context()->promise_all(),
                                isolate);
    builder->AppendPromiseCombinatorFrame(function, combinator);

    // Ahora inspeccionamos el contexto del elemento de resolución de Promise.all()
    // para encontrar la capacidad de promesa que se está resolviendo cuando todas
    // las promesas concurrentes se resuelven.
    int const index =
        PromiseBuiltins::kPromiseAllResolveElementCapabilitySlot;
    Handle<PromiseCapability> capability(
        PromiseCapability::cast(context->get(index)), isolate);
    if (!IsJSPromise(capability->promise())) return;
    promise = handle(JSPromise::cast(capability->promise()), isolate);
} else if (

Mientras recorre la cadena de promesas, si reaction->fulfill_handler es la función integrada "Closure de resolución de elementos de Promise.all", añade el marco de combinador de promesas asíncrono a la pila de errores. Luego, pasa a la siguiente promesa accediendo a function->context->capability->promise.

El problema es que la función asume que la función "Closure de resolución de elementos de Promise.all" no se ha ejecutado todavía. Si la función "Closure de resolución de elementos de Promise.all" ya se ha ejecutado, el contexto cambia de FunctionContext a NativeContext. Esto lleva a una confusión de tipos entre FunctionContext y NativeContext en la función CaptureAsyncStackTrace.

Creación del PoC:

La estrategia para desencadenar la vulnerabilidad es la siguiente:

  1. Obtener la función "Closure de resolución de elementos de Promise.all", que es una función intrínseca integrada.
  2. Llamar explícitamente a la función "Closure de resolución de elementos de Promise.all" para cambiar el contexto de FunctionContext a NativeContext.
  3. Establecer la función "Closure de resolución de elementos de Promise.all" como manejador de cumplimiento de una promesa con una nueva cadena de promesas.
  4. Lanzar un error en la cadena de promesas y capturar la traza de pila asíncrona.

Usé el patrón de resolución de promesas síncrono para Promise.all con el fin de obtener la función "Closure de resolución de elementos de Promise.all" a nivel de script JS. Tomé prestado el patrón de los casos de prueba de test262.

Después de llamar explícitamente a la función, para desencadenar la vulnerabilidad, usé el código de ejemplo del [documento de traza de pila asíncrona de costo cero][v8 docs] para preparar una nueva cadena de promesas y establecer la función intrínseca integrada como manejador de cumplimiento de una de las promesas.

Descargar herramienta