Skip to content
KitploitKITPLOIT
HerramientasBlog
Log in
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2024-38063 — CVE-2024-38063 - Explotando el kernel de forma remota a través de IPv6 | Kitploit
Herramientas/GitHubGitHub/faizan-khanx/cve-2024-38063
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónIngeniería InversaSeguridad de RedesPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHubfaizan-khanx/cve-2024-38063

CVE-2024-38063

CVE-2024-38063 - Explotando el kernel de forma remota a través de IPv6

Ver Repositorio
115hace 2 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

CVE-2024-38063 - Explotando el kernel de forma remota mediante IPv6

  • Desde que cayó el último parche de Windows el 13 de agosto, he estado metido de lleno en tcpip.sys (el controlador del kernel responsable de manejar los paquetes TCP/IP). Una vulnerabilidad con una puntuación CVSS de 9.8 en la parte más fácilmente alcanzable del kernel de Windows era algo a lo que simplemente no podía renunciar. Nunca había mirado IPv6 antes (ni los controladores responsables de analizarlo), así que sabía que intentar aplicar ingeniería inversa a esta vulnerabilidad iba a ser extremadamente difícil, pero una buena experiencia de aprendizaje.

El análisis de parche más fácil de la historia

  • Normalmente, incluso solo aplicar ingeniería inversa al parche para averiguar qué cambio de código corresponde a la vulnerabilidad puede llevar días o incluso semanas, pero en este caso fue instantáneo. De hecho, fue tan fácil que varias personas en las redes sociales me dijeron que estaba equivocado y que el bug estaba en otro sitio. ¿Les hice caso y perdí un día entero haciendo ingeniería inversa al controlador equivocado? Puede que nunca lo sepamos.

Hubo exactamente un cambio realizado en todo el archivo del controlador, que resulta ser, efectivamente, el bug después de todo. image Una vista bindiff de tcpip.sys antes y después de instalar el parche.

Solo se ha modificado una única función en todo el controlador. Normalmente, podría pasarme un día entero revisando más de 20 cambios de funciones diferentes solo para averiguar cuál es la que debería estar mirando, pero esta vez no. image

Ipv6pProcessOptions() antes del parche.

image Ipv6pProcessOptions() . Después del parche.

No solo se cambió una única función, sino una única línea de código.

  • La función de nombre extremadamente largo Feature_2660322619__private_IsEnabledDeviceUsage_3() es algo que Microsoft añade a veces para permitir reversiones parciales de parches. La llamada comprueba la presencia de una marca global o un ajuste de registro que, si está establecido, hará que la función devuelva false, lo que resulta en la ejecución del código original en lugar de la versión parcheada.

  • La razón por la que Microsoft hace esto es porque los parches de seguridad a veces rompen cosas sin querer, así que este ajuste permite a un administrador desparchear una única vulnerabilidad, sin desinstalar todo el paquete de parches mensual y debilitar drásticamente la seguridad del sistema.

  • Teniendo esto en cuenta, está claro que todo lo que hace este parche es sustituir una llamada a IppSendErrorList() por IppSendError(), lo que nos da una pista de que el problema está relacionado con algún tipo de lista. El diff de parche más fácil de la historia (o eso creía)

Vulnerabilidades opcionales, explotación obligatoria

  • Aplicar ingeniería inversa al parche para encontrar el código alterado es solo la mitad del desafío (o en este caso, menos del 0.1%). El resto del proceso consiste en aplicar ingeniería inversa a suficiente parte del código base para entender qué está pasando, averiguar qué tipo de vulnerabilidad se parcheó, cómo construir una solicitud para llegar al código objetivo y qué estado resulta en una condición explotable.

  • La primera parte es bastante fácil. El cambio está en Ipv6pProcessOptions(), lo que nos dice que es IPv6 y que implica procesar opciones. Así que una consulta rápida al RFC nos dice exactamente qué es una opción de IPv6 y dónde podemos encontrar una.

image El diseño de la cabecera de opciones de destino de Wikipedia.

Vale, genial. Lo que buscamos parece ser la cabecera de opciones de destino, que se sitúa justo después de la cabecera IPv6 principal. Usemos la biblioteca de Python ‘scapy’ para construir un paquete IPv6 de prueba.

Nota: Para mitigar los ataques DDoS que utilizan direcciones IP falsificadas, Windows restringe la capacidad de construir paquetes IP sin procesar. Por esta razón, opté por usar Linux para desarrollar mi prueba de concepto. Aunque Linux sí permite a los usuarios construir y enviar paquetes sin procesar de capa 2 y capa 3, requiere que el script de Python se ejecute 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])
  • Después de establecer un punto de interrupción en tcpip!Ipv6pProcessOptions y ejecutar el script, quedó claro que todo lo que se necesitaba para llegar a la función vulnerable era enviar un paquete IPv6 con una estructura de opciones vacía. Entonces probé a añadir algunas opciones no válidas a la estructura para ver si podía llegar a la llamada a IppSendErrorList().

Una breve revisión del código indicó que casi cualquier formato de opción no válido podría desencadenar la llamada a IppSendErrorList. Así que decidí usar la opción de paquete Jumbo con una longitud no válida (menos de 65535 bytes).

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

  • Entonces, ¿qué hace realmente IppSendErrorList()? Bueno, el código es bastante sencillo. image La función IppSendErrorList completa.

  • El código itera sobre una lista enlazada y llama a IppSendError() para cada elemento de la lista. Una vez más, los astros se han alineado y las cosas han sido fáciles hasta ahora. Si IppSendErrorList simplemente llama a IppSendError para cada elemento de una lista, y el parche sustituye la llamada a IppSendErrorList por IppSendError, entonces el problema ocurre cuando se llama a IppSendError sobre un elemento de la lista que no es el primero.

Está haciendo una lista, la está comprobando 52,567 veces

  • Aquí es donde las cosas pasaron de obvias a anormalmente difíciles, aunque creo que gran parte fue debido a que una de mis dos células cerebrales disponibles estaba ocupada luchando contra una mala infección de covid. Perdí un par de días entendiendo partes del código, quedándome dormido y luego olvidando lo que había descubierto. Todo el proceso requirió más de una semana de ingeniería inversa de partes de tcpip.sys para averiguar qué estaba pasando. Pero la entrada del blog de Axel fue extremadamente útil.

  • Al observar las funciones y la estructura a las que Axel aplicó ingeniería inversa, y a qué otras funciones se pasan, está claro que el único argumento pasado a Ipv6pProcessOptions() es la misma estructura packet_t definida en el artículo. En esencia, el puntero pasado a Ipv6pProcessOptions, e iterado por IppSendErrorList, es una lista enlazada de paquetes.

  • Así que establecí un punto de interrupción en Ipv6pProcessOptions() e inspeccioné la lista.

image

La entrada list->Next es NULL.

Descargar herramienta