Ciberataques com IA: Como detetar, prevenir e defender-se contra ameaças inteligentes

Ler agora
Utilizamos inteligência artificial para as traduções dos sítios e, embora nos esforcemos por garantir a exatidão, estas podem nem sempre ser 100% precisas. Agradecemos a sua compreensão.

Correção da vulnerabilidade CVE-2024-0517 no Google Chrome

Desenvolvido pelo MetaDefender Endpoint
por OPSWAT
Partilhar esta publicação
Fotografia dos participantes no programa de bolsas OPSWAT , Hoai Nam Do e Minh Quan Le
Participantes do programa de bolsas de estudo OPSWAT

Sobre o CVE-2024-0517

A CVE-2024-0517 é uma vulnerabilidade de escrita fora dos limites no motor V8 JavaScript do Google Chrome anterior à versão 120.0.6099.224, que permite a atacantes remotos explorar a corrupção de heap através de uma página HTML criada. A vulnerabilidade foi relatada pela primeira vez por Toan (Suto) Pham da Qrious Secure. 

Captura de ecrã que mostra uma pontuação base de gravidade CVSS 3.x de 8,8 (Alta) com uma descrição detalhada do vetor a partir do NVD
CVE-2024-0517 na Base de Dados Nacional de Vulnerabilidades (NVD)

Esta vulnerabilidade surge da confusão de tipos, que ocorre quando uma aplicação aloca ou inicializa um recurso como um ponteiro, objeto ou variável utilizando um tipo, mas mais tarde acede a esse recurso utilizando um tipo que é incompatível com o tipo original (CWE-843). Neste CVE, a confusão de tipos é despoletada durante um processo de alocação de memória chamado folded allocation, que é empregue para otimização de memória pelo Maglev, um compilador de otimização para o motor V8 JavaScript. 

Ao explorar a confusão de tipos e escrever códigos de shell arbitrários através do WebAssembly, um atacante pode executar comandos no computador da vítima. 

Fases de ataque

Os atacantes podem alojar um sítio Web que contém uma página HTML criada e enganar os utilizadores para que acedam ao mesmo através de e-mails de phishing ou redes sociais. Quando os utilizadores visitam o site utilizando uma versão vulnerável do Google Chrome, o código malicioso incorporado executa comandos arbitrários. 

Diagrama que mostra um processo de quatro passos para explorar uma vulnerabilidade utilizando uma mensagem de correio eletrónico de phishing com um ficheiro HTML malicioso que conduz à execução remota de código
Campanha ofensiva passo a passo 

Motor JavaScript V8 

Os atacantes podem alojar um sítio Web que contém uma página HTML criada e enganar os utilizadores para que acedam ao mesmo através de e-mails de phishing ou redes sociais. Quando os utilizadores visitam o site utilizando uma versão vulnerável do Google Chrome, o código malicioso incorporado executa comandos arbitrários. 

Maglev e afetação dobrada

O Maglev, um compilador de otimização no V8, melhora a execução do código e a atribuição de memória. O Maglev é executado apenas quando o código é executado frequentemente e marcado como "quente", indicando a necessidade de uma execução mais rápida através da compilação em vez de uma interpretação linha a linha mais lenta. 

Normalmente, as alocações ocorrem em regiões de memória não contíguas, levando ao uso esparso e ineficiente da memória. Para resolver este problema, o V8 emprega uma técnica chamada alocação dobrada, que aloca múltiplas variáveis de forma contínua e simultânea. O Maglev também optimiza as atribuições utilizando a atribuição dobrada no seu progresso. 

Diagrama com representações codificadas por cores das atribuições de pastas com e sem pastas atribuídas
Malev e atribuição de pastas

Recolha de lixo geracional 

Para limpar as regiões de memória não utilizadas, o V8 emprega uma técnica de coleta de lixo geracional (GC), dividindo a memória em dois espaços: a geração jovem e a geração antiga. Além disso, há dois coletores de lixo: o coletor de lixo menor, que é responsável pela limpeza do espaço jovem, e o coletor de lixo maior, que lida com a limpeza do espaço antigo. A geração jovem é a área da memória onde os objetos recém-criados são inicialmente alocados e a geração antiga é uma região da memória onde os objetos de longa duração são armazenados. Os objectos que sobreviveram a vários ciclos menores do GC na geração jovem são eventualmente promovidos para a geração antiga. 

Diagrama que mostra o processo de atribuição de objectos nas gerações de memória nova, intermédia e antiga durante a recolha do lixo (GC)
Espaços de memória: geração jovem e geração velha

Análise de vulnerabilidade

Visão geral

A vulnerabilidade surge quando um objeto é criado a partir de uma classe herdada de uma classe de base sem construtor explicitamente definido (construtor de base por defeito) e outro objeto é subsequentemente criado. Devido à atribuição dobrada, a atribuição do primeiro objeto pode ser seguida pela atribuição do segundo objeto. Se ocorrer um evento como a recolha de lixo entre estas duas atribuições, pode surgir uma vulnerabilidade de confusão de tipos.

Análise da causa raiz 

Os Graduate Fellows OPSWAT efectuaram uma análise detalhada do fluxo de trabalho V8 durante o processo de atribuição e determinaram que as seguintes funções são invocadas durante este processo: 

Diagrama que ilustra o fluxo de trabalho do V8 durante o processo de atribuição de objectos, desde a procura do construtor até à extensão da atribuição bruta
Fluxo de trabalho V8 durante o processo de atribuição 

Neste processo, foi identificado um problema na função TryBuildFindNonDefaultConstructorOrConstruct: A função BuildAllocateFastObject estende current_raw_allocation_ (um ponteiro para a região de memória alocada para múltiplas variáveis simultaneamente) para construir a instância da classe filha, mas não a limpa definindo-a como nula. 

Como resultado, o próximo objeto criado é sempre atribuído imediatamente a seguir à memória apontada por current_raw_allocation_, independentemente de quaisquer eventos anteriores à segunda atribuição. 

Diagrama que mostra a criação de um novo objeto na memória, passando da "atribuição bruta atual" para o "objeto seguinte"
'current_raw_allocation' e 'Next object' na região da memória

Se o GC for invocado, a região de memória próxima da memória adjacente a current_raw_allocation_ pode ser atribuída a outros objectos. Isto pode levar a uma situação em que, após o GC ser acionado e outro objeto ser criado, dois ponteiros referenciam a mesma região de memória mas têm tipos de dados diferentes, resultando numa vulnerabilidade de confusão de tipos.

Um diagrama que mostra um processo de vulnerabilidade de confusão de tipos, ilustrando o acionamento da recolha de lixo e a atribuição de objectos que conduz a potenciais problemas
Vulnerabilidade de confusão de tipos 

Exploração

Para explorar esta vulnerabilidade, os bolseiros de pós-graduação OPSWAT criaram instâncias WebAssembly que continham código de shell e tentaram desencadear confusão de tipos pelo GC para controlar a memória e executar o código de shell: 

Um fluxograma passo a passo de como desencadear a execução remota de código através de confusão de tipos no motor V8, desde o desencadeamento da confusão de tipos até à execução de código de shell
Passos para acionar a execução remota de código no motor V8 

Confusão de tipos de gatilho

Durante a inicialização, primeiro definimos uma matriz (_arrayObject) contendo objectos vazios. Em seguida, construímos uma instância da classe filha, bem como um coletor de lixo de gatilho. Finalmente, definimos outro array com um número de ponto flutuante, chamado _arrayDouble. 

Um excerto de código que demonstra uma função que acciona a recolha de lixo em JavaScript, criando um buffer de matriz

Essas construções devem ser repetidas para que o código seja executado várias vezes, fazendo com que o V8 o marque como "quente" e acione o compilador Maglev. Conseguimos isso invocando o construtor da classe filha dentro de um loop, como segue: 

Um pequeno trecho de código JavaScript que ilustra um loop que cria várias instâncias de uma classe filha

A confusão de tipos será desencadeada após a inicialização repetida destes objectos num ciclo.

Criar primitivas de leitura e escrita

Depois de desencadear com sucesso a confusão de tipos, a execução do código de shell requer a leitura da memória e a substituição da memória num endereço controlado. Para isso, criámos primitivas de leitura e escrita. As primitivas de exploração tirarão partido dos metadados nos objectos para nos darem regiões de memória de leitura/escrita arbitrárias e usá-las para executar código arbitrário. 

Uma representação visual da primitiva de leitura e escrita, mostrando as regiões de memória e os valores que estão a ser substituídos
Primitivo de leitura e escrita 

As primitivas de leitura e escrita nesta etapa permitir-nos-ão controlar o ponteiro da tabela de saltos da instância do WebAssembly na etapa seguinte. 

Criar instâncias do WebAssembly

Em seguida, criámos duas instâncias do WebAssembly: uma para armazenar o código da shell e outra para o ativar. Para evitar escrever diretamente o código shell na memória da instância do WebAssembly através de primitivas de leitura e escrita, definimos alguns valores constantes de ponto flutuante na instância do WebAssembly. 

Um trecho de código escrito em WebAssembly que ilustra o acesso à memória e as funções de armazenamento

Ponteiro da tabela de saltos de controlo da instância do WebAssembly

Usando primitivas de leitura e escrita, ajustamos o ponteiro da tabela de saltos da segunda instância do WebAssembly para saltar alguns bytes do código compilado de constantes na primeira instância do WebAssembly, de modo a que as constantes de vírgula flutuante sejam interpretadas como o nosso shellcode pretendido:

Trecho de código assembly mostrando instruções para mover dados para registos

Executar a instância do WebAssembly para executar o código de shell 

Finalmente, depois de desencadear a confusão de tipos e usar primitivas de leitura/escrita para controlar os ponteiros da tabela de saltos das instâncias do WebAssembly, invocámos a função exportada da segunda instância do WebAssembly, que faz com que o código da shell na primeira instância do WebAssembly seja executado. 

O shellcode que estamos a utilizar foi concebido para terminar todos os processos numa máquina Linux, como através do seguinte comando: 

Um simples trecho de comando de terminal com o comando 'kill' para encerrar processos

O código de montagem para executar este comando, convertido a partir dos números de vírgula flutuante, será o seguinte: 

Um trecho de código assembly para uma syscall que termina um processo usando o comando 'kill'

Simular a vulnerabilidade de segurança 

Para simular esta exploração num cenário real, os bolseiros OPSWAT criaram uma página HTML maliciosamente elaborada. 

Um fragmento de código WebAssembly concebido para executar código shell acedendo à memória e manipulando dados

É enviado à vítima um e-mail de phishing com uma hiperligação para o domínio que aloja esta página HTML criada. 

Captura de ecrã que mostra uma mensagem de correio eletrónico de phishing juntamente com uma ferramenta de monitorização do sistema, demonstrando a execução do ataque

Se a vítima aceder à ligação utilizando a versão vulnerável do Google Chrome, o shellcode é executado, fazendo com que todos os processos sejam terminados. Como resultado, o utilizador é desconectado, como se mostra abaixo: 

Captura de ecrã do ecrã de início de sessão do Kali Linux

Remediação

MetaDefender Endpoint™ foi utilizado para mitigar proactivamente este CVE, aproveitando a sua capacidade de "Aplicação Vulnerável". A solução identifica e exibe efetivamente todos os CVEs associados aos aplicativos do Google Chrome no ambiente do endpoint. Para neutralizar a ameaça, os utilizadores podem desinstalar imediatamente o Chrome ou aplicar o patch de segurança mais recente. Ao implementar qualquer uma das contramedidas, o CVE é totalmente contido, reduzindo significativamente o risco de um ataque informático bem sucedido no ponto final.

A interface MetaDefender Endpoint mostra as vulnerabilidades do Google Chrome, incluindo detalhes sobre os CVEs

Segurança de Endpoint de nível seguinte 

Descubra porque é que as organizações, instituições e entidades de todo o mundo confiam no MetaDefender Endpoint para proteger os terminais críticos. Fale com um especialista hoje para saber mais e veja por si mesmo com uma demonstração gratuita.  


Mantenha-se atualizado com OPSWAT!

Inscreva-se hoje para receber as últimas actualizações da empresa, histórias, informações sobre eventos e muito mais.