Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2019-8601 — Explorando uma vulnerabilidade corrigida no JavaScriptCore | Kitploit
Ferramentas/GitHubGitHub/badaccess11/cve-2019-8601
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebAprendizado e EducaçãoDesenvolvimento de PayloadsExploração de Binários
GitHubbadaccess11/cve-2019-8601

CVE-2019-8601

Explorando uma vulnerabilidade corrigida no JavaScriptCore

Ver Repositório
17312há 6 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Explorando CVE-2019-8601

Este é um exploit para uma vulnerabilidade do WebKit que foi originalmente descoberta por Fluoroacetate durante a competição pwn2own em Vancouver. Embora eu não tenha descoberto este bug, escrevi este exploit para praticar minhas habilidades de desenvolvimento de exploits. O artigo original sobre este exploit está aqui, da Zero Day Initiative. Embora este artigo seja muito bom e tenha sido fundamental para me ajudar a entender a vulnerabilidade, ele é do ponto de vista de alguém que está verificando a vulnerabilidade. Descobri que alguns detalhes importantes estão faltando ao tentar construir este exploit do zero e espero preencher algumas das lacunas que o artigo da ZDI deixou passar e adquirir habilidades práticas sobre como construir um exploit complicado do zero.

Passos para a Exploração

Estes passos servem como um esboço para obter execução de código arbitrária dentro do JavaScriptCore (JSC), o motor JavaScript do WebKit

  • Identificar a vulnerabilidade
  • Desencadear a vulnerabilidade e causar um crash com ASAN ativado
  • Obter primitivas leakAddr e fakeObj
  • Corromper o butterfly do array para obter primitivas de leitura e escrita
  • Usar primitivas de leitura e escrita para obter execução de código arbitrária dentro do JSC

Identificando a Vulnerabilidade

A vulnerabilidade que será explorada é um estouro de inteiro que ocorre no código produzido pelo compilador just-in-time (JIT) DFG para o WebKit. Isso ocorre especificamente na função compileNewArrayWithSpread. Esta função será chamada quando o código que usa sintaxe de espalhamento do JavaScript para criar um novo array for compilado JIT pelo DFG.

compileNewArrayWithSpread

Dentro do código compilado JIT, primeiro ele calculará o tamanho do array. Ele faz isso somando o comprimento de cada argumento passado para o construtor do array. Ao calcular o tamanho para cada adição, ele verifica se há um estouro do tamanho. Depois disso, ele chamará a função compileAllocateNewArray passando o comprimento que foi calculado nesta função.

compileAllocateNewArrayWithSize

A função compileAllocateNewArray então passará o comprimento calculado anteriormente para emitAllocateButterfly.

emitAllocateButterfly

A função emitAllocateButterfly então deslocará à esquerda o tamanho em 3 bits, o que equivale a multiplicá-lo por 8. No entanto, não há verificação de estouro e, portanto, um número como 0x20000001 pode transbordar para 0x8

Este programa em C ilustra esta vulnerabilidade:

overflow-example2

overflow-example

Podemos usar esta vulnerabilidade para enganar o motor JavaScript, fazendo-o acreditar que alocamos um array com tamanho 0x20000001, mas na verdade alocamos apenas espaço suficiente para 1 JSValue (8 bytes). Isso resultará em uma primitiva de leitura e escrita fora dos limites (OOB) que pode então ser aproveitada para alcançar leitura/escrita arbitrária e, eventualmente, execução remota de código (RCE).

  • Identificar a vulnerabilidade

    Desencadeando a Vulnerabilidade com ASAN

Para confirmar que temos uma leitura OOB, tentaremos desencadear esta vulnerabilidade em uma compilação com address sanitizer (ASAN) do JSC.

Para fazer isso a partir do diretório do WebKit, podemos executar os comandos:```bash Tools/Scripts/set-webkit-configuration --asan Tools/Scripts/build-jsc --jsc--only --debug

Isto construirá uma build de depuração do JSC com ASAN habilitado, permitindo-nos verificar se conseguimos ou não acionar a vulnerabilidade.

Aqui está a primeira iteração do 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)

Ao executar isso, obtenho o seguinte erro:

Programa terminado com o sinal SIGKILL, Morto. O programa não existe mais.

Meu palpite foi que muita memória estava sendo consumida ao tentar alocar um array tão grande. Para confirmar isso, adicionei um breakpoint ao código JITed adicionando uma chamada a m_jit.breakpoint() dentro de compileNewArrayWithSpread, que adiciona uma instrução int3 ao código JITed.

Depois de adicionar o breakpoint, descobri que ele não foi atingido e então decidi testar um comprimento de 0x20001. Então percebi que o código nem estava sendo compilado, então adicionei mais iterações para ativar o 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)

Testar o programa como está ainda leva ao SIGKILL, no entanto, ao testar com um comprimento menor, o breakpoint é acionado. Neste ponto, ainda me parece que o JSC está ficando sem memória ao tentar processar aquele grande array.

Para lidar com isso, decidi alocar um array `a` menor e depois usar a sintaxe de espalhamento para usá-lo várias vezes ao criar o array corrompido, resultando no seguinte 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)

Utilizando este código, conseguimos atingir o breakpoint sem um SIGKILL! Como geralmente acontece, ao corrigir um problema surge outro e obtivemos um SIGABORT... Usando o comando gdb bt podemos ver que operationNewArrayWithSize foi chamada, que por sua vez chamou create.backtrace1

Parece estranho que nosso código JIT estivesse chamando operationNewArrayWithSize e deve ser que o código JIT teve que seguir um slow path para o motor JavaScript por algum motivo.

slowcases

Podemos ver em compileAllocateNewArrayWithSize que há de fato um bailout para operationNewArrayWithSize. Precisamos então descobrir exatamente por que estamos fazendo o bailout para o slow case.

Podemos ver que em compileNewArrayWithSpread o shouldConvertLargeSizeToArrayStorage está definido como false e que esse slow path não estará no código compilado.compileNewArrayWithSpread2

Portanto, faz sentido que o slow path esteja sendo acionado em algum lugar dentro de emitAllocateJSObject

Baixar ferramenta