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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/badaccess11/cve-2019-8601
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebAprendizaje y EducaciónDesarrollo de PayloadsExplotación de Binarios
GitHubbadaccess11/cve-2019-8601

CVE-2019-8601

Explotando una vulnerabilidad parcheada en JavaScriptCore

Ver Repositorio
1734hace 6 añosAún no revisado

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

Explotando CVE-2019-8601

Este es un exploit para una vulnerabilidad de WebKit que fue descubierta originalmente por Fluoroacetate durante la competencia pwn2own en Vancouver. Aunque no descubrí este error, escribí este exploit para practicar mis habilidades de desarrollo de exploits. El artículo original sobre este exploit está aquí de Zero Day Initiative. Si bien este artículo es muy bueno y fue fundamental para ayudarme a entender la vulnerabilidad, está desde el punto de vista de alguien que verifica la vulnerabilidad. Encontré que algunos detalles clave faltan al intentar diseñar este exploit desde cero y espero llenar algunos de los vacíos que el artículo de ZDI omitió y adquirir habilidades prácticas sobre cómo diseñar un exploit complicado desde cero.

Pasos para la Explotación

Estos pasos sirven como un esquema para lograr ejecución de código arbitrario dentro de JavaScriptCore (JSC), el motor JavaScript de WebKit

  • Identificar la vulnerabilidad
  • Disparar la vulnerabilidad y provocar un crash con ASAN habilitado
  • Obtener primitivas leakAddr y fakeObj
  • Corromper el butterfly del array para lograr primitivas de lectura y escritura
  • Usar las primitivas de lectura y escritura para lograr ejecución de código arbitrario dentro de JSC

Identificando la Vulnerabilidad

La vulnerabilidad que será explotada es un desbordamiento de enteros que ocurre en el código producido por el compilador DFG justo a tiempo (JIT) para WebKit. Esto ocurre específicamente en la función compileNewArrayWithSpread. Esta función será llamada cuando el código que usa sintaxis de propagación de JavaScript para crear un nuevo array sea compilado JIT por DFG.

compileNewArrayWithSpread

Dentro del código JIT, primero se calculará el tamaño del array. Lo hace sumando la longitud de cada argumento pasado al constructor del array. Mientras calcula el tamaño para cada suma, verifica si hay un desbordamiento del tamaño. Después de esto, llamará a la función compileAllocateNewArray pasando la longitud que se computó en esta función.

compileAllocateNewArrayWithSize

La función compileAllocateNewArray pasará entonces la longitud que se calculó antes a emitAllocateButterfly.

emitAllocateButterfly

emitAllocateButterfly desplazará entonces a la izquierda el tamaño 3 bits, lo que equivale a multiplicarlo por 8. Sin embargo, no hay verificación de desbordamiento, por lo que un número como 0x20000001 puede desbordarse a 0x8

Este programa en C ilustra esta vulnerabilidad:

overflow-example2

overflow-example

Podemos usar esta vulnerabilidad para engañar al motor JavaScript haciéndole creer que hemos asignado un array con tamaño 0x20000001 pero en realidad solo hemos asignado suficiente espacio para 1 JSValue (8 bytes). Esto resultará en una primitiva de lectura y escritura fuera de los límites (OOB) que luego puede ser aprovechada para lograr lectura/escritura arbitraria y eventualmente ejecución remota de código (RCE).

  • Identificar la vulnerabilidad

    Disparando la Vulnerabilidad con ASAN

Para confirmar que tenemos una lectura OOB, intentaremos disparar esta vulnerabilidad en una compilación de JSC con address sanitizer (ASAN).

Para hacer esto desde el directorio de WebKit podemos ejecutar los comandos:```bash Tools/Scripts/set-webkit-configuration --asan Tools/Scripts/build-jsc --jsc--only --debug

Esto construirá una compilación de depuración de JSC con ASAN habilitado, lo que nos permitirá verificar si hemos desencadenado exitosamente la vulnerabilidad o no.

Aquí está la primera iteración de exploit.js```javascript
function jitMe(array){
  return [...array]
}

let dummy = [1.1]
for(let i = 0; i < 200; i++){
  jitMe(dummy);
}

let a = []

let len = 0x20000001                                                                     

for(let i = 0; i < len; i++){
  a[i] = 1.1 
}

jitMe(a)

Cuando ejecuto esto, obtengo el siguiente error:

Program terminated with signal SIGKILL, Killed. The program no longer exists.

Mi suposición era que se estaba consumiendo demasiada memoria al intentar asignar un array tan grande. Para confirmarlo, agregué un punto de interrupción al código JITed añadiendo una llamada a m_jit.breakpoint() dentro de compileNewArrayWithSpread, lo que agrega una instrucción int3 al código JITed.

Después de agregar el punto de interrupción, descubrí que no se disparaba y entonces decidí probar con una longitud de 0x20001. Me di cuenta de que el código ni siquiera se estaba compilando, así que agregué más iteraciones para activar el compilador DFG.```javascript function jitMe(array){ for(let i = 0; i < 0x4000; i++){ let x = 1 + 1 } return [...array] }

let dummy = [1.1] for(let i = 0; i < 60; i++){ print(i) jitMe(dummy); }

let a = []

let len = 0x20000001

for(let i = 0; i < len; i++){ a[i] = 1.1 }

jitMe(a)

Probar el programa tal como está aún lleva a SIGKILL, sin embargo, al probar con una longitud más pequeña, el punto de interrupción se activa. En este punto, todavía me parece que JSC se está quedando sin memoria al intentar procesar ese enorme array.

Para lidiar con esto, decidí asignar un array `a` más pequeño y luego usar la sintaxis de propagación para usarlo varias veces al crear el array corrupto resultando en el siguiente exploit.js```
function jitMe(array){
  for(let i = 0; i < 0x4000; i++){
    let x = 1 + 1
  }
  return [...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array, ...array]
}

let dummy = [1.1]
for(let i = 0; i < 100; i++){
  print(i)
  jitMe(dummy);
}

let a = []

let len = 0x20000010 / 0x10

for(let i = 0; i < len; i++){
  a[i] = 1.1
}

jitMe(a)

Usando este código pudimos alcanzar el punto de interrupción sin un SIGKILL. Como suele ocurrir, solucionar un problema revela otro y obtuvimos un SIGABORT en su lugar... Usando el comando bt de gdb podemos ver que se llamó a operationNewArrayWithSize, que a su vez llamó a create.backtrace1

Parece extraño que nuestro código JIT esté llamando a operationNewArrayWithSize y debe ser que el código JIT tuvo que tomar una ruta lenta hacia el motor de JavaScript por alguna razón.

slowcases

Podemos ver en compileAllocateNewArrayWithSize que efectivamente hay una salida hacia operationNewArrayWithSize. Entonces necesitamos descubrir por qué exactamente estamos saliendo al caso lento.

Podemos ver que en compileNewArrayWithSpread, shouldConvertLargeSizeToArrayStorage está establecido en falso y esa ruta lenta no estará en el código compilado.compileNewArrayWithSpread2

Descargar herramienta