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.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/adminpentester/cve-2024-38063-
Forensia de MemóriaAnálise de VulnerabilidadesExploraçãoEngenharia ReversaAprendizado e EducaçãoExploração de Binários
GitHubadminpentester/cve-2024-38063-

CVE-2024-38063-

Explorando o kernel remotamente via IPv6

Ver Repositório
2111há 2 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

CVE-2024-38063-

Explorando Remotamente o Kernel Através do IPv6

CVE-2024-38063 - Explorando Remotamente o Kernel Através do IPv6 Marcus Hutchins

Desde a última atualização de segurança da Microsoft lançada em 13 de agosto, mergulhei fundo no tcpip.sys (o driver do kernel responsável por processar pacotes TCP/IP). Uma vulnerabilidade com pontuação 9,8 no CVSS na parte mais facilmente acessível do kernel do Windows era algo que eu simplesmente não podia deixar passar. Nunca havia realmente examinado o IPv6 antes (nem os drivers responsáveis por analisá-lo), então sabia que tentar fazer engenharia reversa dessa vulnerabilidade seria extremamente desafiador, mas uma boa experiência de aprendizado.

Na maior parte, o tcpip.sys é amplamente não documentado. Consegui encontrar alguns write-ups de exploração para bugs antigos: aqui, aqui e aqui, mas pouco mais. Quando o principal resultado da minha pesquisa no Google em inglês está escrito em chinês, imediatamente sei que estou muito além da minha profundidade e vou passar por maus bocados, mas aprender é necessário. Apesar do Google Tradutor ter feito um trabalho medíocre, o post forneceu uma visão incrivelmente detalhada sobre como a fragmentação IPv6 funciona e me deu um bom ponto de partida.

Mais tarde, enquanto pesquisava alguns nomes de funções no Google, me deparei com outra análise da mesma vulnerabilidade de 2021, escrita por Axel Souchet (também conhecido como 0vercl0k), que se aprofundou ainda mais nos detalhes internos do tcpip.sys e me deu informações suficientes para definir várias estruturas não documentadas. A análise de patch mais fácil de todos os tempos

Normalmente, até mesmo fazer engenharia reversa do patch para descobrir qual mudança no código corresponde à vulnerabilidade pode levar dias ou até semanas, mas neste caso foi instantâneo. Foi tão fácil, na verdade, que várias pessoas nas redes sociais me disseram que eu estava errado e que o bug estava em outro lugar. Será que eu realmente as ouvi e perdi um dia inteiro revertendo o driver errado? Talvez nunca saberemos.

Houve exatamente uma mudança feita em todo o arquivo do driver, que, no final das contas, era realmente o bug.

Uma visão geral do bindiff do tcpip.sys antes e depois da instalação do patch.

Apenas uma única função em todo o driver foi modificada. Normalmente, eu poderia passar um dia inteiro analisando mais de 20 mudanças de função diferentes apenas para descobrir qual delas deveria estar observando, mas desta vez não.

Ipv6pProcessOptions() antes do patch.

Ipv6pProcessOptions() depois do patch.

Não foi apenas uma única função que foi alterada, mas uma única linha de código.

A função de nome extremamente longo Feature_2660322619__private_IsEnabledDeviceUsage_3() é algo que a Microsoft às vezes adiciona para permitir reversões parciais de patches. A chamada verifica a presença de uma flag global ou configuração de registro que, se definida, fará com que a função retorne falso, resultando na execução do código original em vez da versão corrigida.

O motivo pelo qual a Microsoft faz isso é porque patches de segurança às vezes quebram coisas involuntariamente, então essa configuração permite que um administrador desfaça o patch de uma única vulnerabilidade sem desinstalar todo o pacote de patches mensal e enfraquecer drasticamente a segurança do sistema.

Levando isso em conta, fica claro que tudo o que esse patch faz é substituir uma chamada para IppSendErrorList() por IppSendError(), nos dando uma pista de que o problema está em algum tipo de lista. A diferença de patch mais fácil de todos os tempos (ou pelo menos foi o que pensei). Vulnerabilidades opcionais, exploração obrigatória

Fazer engenharia reversa do patch para encontrar o código alterado é apenas metade do desafio (ou neste caso, menos de 0,1%). O resto do processo consiste em fazer engenharia reversa o suficiente da base de código para entender o que está acontecendo, descobrir que tipo de vulnerabilidade foi corrigida, como criar uma requisição para alcançar o código alvo e qual estado resulta em uma condição explorável.

A primeira parte é fácil o suficiente. A mudança está em Ipv6pProcessOptions(), o que nos diz que é IPv6 e envolve processamento de opções. Então, uma rápida consulta ao RFC nos diz exatamente o que é uma opção IPv6 e onde podemos encontrar uma.

O layout do cabeçalho de opções de destino da Wikipedia.

Ok, legal. O que estamos procurando parece ser o cabeçalho de opções de destino, que fica diretamente após o cabeçalho IPv6 principal. Vamos usar a biblioteca Python 'scapy' para criar um pacote IPv6 de teste.

Nota: Para mitigar ataques DDoS usando endereços IP falsificados, o Windows restringe a capacidade de construir pacotes IP brutos. Por esse motivo, optei por usar Linux para desenvolver minha prova de conceito. Embora o Linux permita que os usuários construam e enviem pacotes brutos de camada 2 e camada 3, isso requer que o script Python seja executado como root.

import sys import struct from scapy.all import *

def send_ipv6_option_packet(dest_ip): ethernet_header = Ether() ip_header = IPv6(dst=dest_ip) options_header = IPv6ExtHdrDestOpt() sendp(ethernet_header / ip_header / options_header)

if len(sys.argv) < 2: print('Use: python3 script.py <target_ipv6_address>') exit(-1)

send_ipv6_option_packet(sys.argv[1])

Depois de definir um breakpoint em tcpip!Ipv6pProcessOptions e executar o script, ficou claro que tudo o que era necessário para alcançar a função vulnerável era enviar um pacote IPv6 com uma estrutura de opções vazia. Tentei então adicionar algumas opções inválidas à estrutura para ver se conseguia alcançar a chamada para IppSendErrorList().

Uma breve revisão do código indicou que quase qualquer formatação inválida de opção poderia acionar a chamada para IppSendErrorList. Então, decidi usar a opção Jumbo Packet com um comprimento inválido (menos de 65535 bytes).

options_header = IPv6ExtHdrDestOpt(options=[Jumbo(jumboplen=0x1337)])

Então, o que IppSendErrorList() realmente faz? Bem, o código é bastante simples.

A função IppSendErrorList inteira.

O código itera uma lista encadeada e chama IppSendError() em cada item da lista. Novamente, as estrelas se alinharam e as coisas têm sido fáceis até agora. Se IppSendErrorList apenas chama IppSendError para cada item em uma lista, e o patch substitui a chamada para IppSendErrorList por IppSendError, então o problema ocorre quando IppSendError é chamado em um item da lista que não seja o primeiro.

Então, do que é essa lista e como podemos fazer uma? Ele está fazendo uma lista, ele está verificando….52.567 vezes

Foi aqui que as coisas passaram de óbvias para anormalmente difíceis, embora eu ache que grande parte disso se deveu a um dos meus dois neurônios disponíveis estar preocupado em lutar contra uma infecção grave de covid. Perdi alguns dias tentando entender partes do código, adormecendo e depois esquecendo o que havia descoberto. Todo o processo exigiu mais de uma semana de engenharia reversa de partes do tcpip.sys para descobrir o que estava acontecendo. Mas o post do blog de Axel foi extremamente útil.

Observando as funções e estruturas que Axel inverteu e para quais outras funções elas são passadas, fica claro que o único argumento passado para Ipv6pProcessOptions() é a mesma estrutura packet_t definida no artigo. Essencialmente, o ponteiro passado para Ipv6pProcessOptions, e iterado por IppSendErrorList, é uma lista encadeada de pacotes.

Então, defini um breakpoint em Ipv6pProcessOptions() e inspecionei a lista.

A entrada list->Next é NULL.

Toda vez que meu breakpoint era acionado, a lista continha apenas um pacote. Passei muito mais tempo do que gostaria de admitir tentando descobrir por que e como fazer minha lista realmente ser uma lista. Meu primeiro pensamento foi fragmentação IPv6: o IPv6 permite que remetentes dividam pacotes grandes em pacotes menores separados, o que faria sentido mantê-los juntos em uma lista.

Baixar ferramenta