Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2024-38063 — CVE-2024-38063 - 通过 IPv6 远程利用内核 | Kitploit
Инструменты/GitHubGitHub/faizan-khanx/cve-2024-38063
Криминалистика памятиАнализ уязвимостейЭксплуатацияОбратная инженерияСетевая безопасностьСтатьи и ИсследованияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubfaizan-khanx/cve-2024-38063

CVE-2024-38063

CVE-2024-38063 - 通过 IPv6 远程利用内核

Репозиторий
1152 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2024-38063 - Удаленная эксплуатация ядра через IPv6

  • С момента выхода последнего патча Windows 13 августа я глубоко погрузился в дебри tcpip.sys (драйвера ядра, отвечающего за обработку пакетов TCP/IP). Уязвимость с оценкой CVSS 9.8 в самой доступной части ядра Windows — от такого я просто не мог отказаться. Я никогда серьезно не изучал IPv6 (и драйверы, отвечающие за его разбор), поэтому знал, что попытка обратного инжиниринга этой уязвимости будет крайне сложной, но хорошим опытом обучения.

Самый легкий анализ патча в истории

  • Обычно даже обратный инжиниринг патча, чтобы выяснить, какое изменение кода соответствует уязвимости, может занять дни или даже недели, но в этом случае всё было мгновенно. Это было настолько просто, что несколько человек в социальных сетях сказали мне, что я ошибаюсь и что ошибка находится в другом месте. Прислушался ли я к ним и затем потратил целый день на реверс-инжиниринг неправильного драйвера? Мы, возможно, никогда не узнаем.

Во всём файле драйвера было сделано ровно одно изменение, которое, как оказалось, и было ошибкой. image Обзор bindiff tcpip.sys до и после установки патча.

Во всём драйвере была изменена только одна функция. Обычно я мог потратить целый день, разбирая 20 и более изменений функций, чтобы понять, на какую из них стоит смотреть, но не в этот раз. image

Ipv6pProcessOptions() до установки патча.

image Ipv6pProcessOptions() После установки патча.

Была изменена не только одна функция, но и всего одна строка кода.

  • Функция с чрезвычайно длинным именем Feature_2660322619__private_IsEnabledDeviceUsage_3() иногда добавляется Microsoft для обеспечения частичного отката патчей. Этот вызов проверяет наличие глобального флага или настройки реестра, при установке которых функция возвращает false, в результате чего выполняется оригинальный код вместо исправленной версии.

  • Причина, по которой Microsoft делает это, заключается в том, что патчи безопасности иногда непреднамеренно ломают что-то, поэтому эта настройка позволяет администратору отменить патч для отдельной уязвимости без удаления всего ежемесячного набора обновлений и существенного ослабления безопасности системы.

  • Учитывая это, становится ясно, что весь этот патч просто заменяет вызов IppSendErrorList() на IppSendError(), что даёт нам подсказку: проблема связана с каким-то списком. Самый простой дифф патча за всю историю (или я так думал).

Уязвимости необязательны, эксплуатация обязательна

  • Обратный инжиниринг патча для нахождения изменённого кода — это лишь половина задачи (или в данном случае менее 0,1%). Оставшаяся часть процесса включает достаточный обратный инжиниринг кодовой базы, чтобы понять, что вообще происходит, выяснить, какой тип уязвимости был исправлен, как сформировать запрос для достижения целевого кода, и какое состояние приводит к эксплуатабельной ситуации.

  • Первая часть достаточно проста. Изменение находится в Ipv6pProcessOptions(), что говорит нам о том, что это IPv6 и связано с обработкой опций. Быстрый запрос к RFC даёт точное определение, что такое опция IPv6 и где её можно найти.

image Структура заголовка опций назначения из Wikipedia.

Ок, отлично. Похоже, то, что мы ищем, — это заголовок опций назначения, который находится сразу после основного заголовка IPv6. Давайте используем библиотеку Python 'scapy', чтобы сформировать тестовый IPv6-пакет.

Примечание. Для смягчения DDoS-атак с использованием поддельных IP-адресов Windows ограничивает возможность создания сырых IP-пакетов. По этой причине я решил использовать Linux для разработки своего proof-of-concept. Хотя Linux позволяет пользователям создавать и отправлять сырые пакеты канального и сетевого уровней, для запуска Python-скрипта требуются права 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])
  • Установив точку останова на tcpip!Ipv6pProcessOptions и запустив скрипт, я понял, что для достижения уязвимой функции достаточно отправить IPv6-пакет с пустой структурой опций. Затем я попробовал добавить недопустимые опции в структуру, чтобы увидеть, смогу ли я добраться до вызова IppSendErrorList().

Краткий обзор кода показал, что почти любое недопустимое форматирование опций может вызвать вызов IppSendErrorList. Поэтому я решил использовать опцию Jumbo Packet с недопустимой длиной (меньше 65535 байт).

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

  • Итак, что же на самом деле делает IppSendErrorList()? Ну, код довольно прост. image Вся функция IppSendErrorList.

  • Код проходит по связному списку и вызывает IppSendError() для каждого элемента списка. Опять звёзды сошлись, и всё пока было просто. Если IppSendErrorList просто вызывает IppSendError для каждого элемента списка, а патч заменяет вызов IppSendErrorList на IppSendError, то проблема возникает, когда IppSendError вызывается для элемента списка, отличного от первого.

Он составляет список, он проверяет его 52 567 раз

  • Вот тут всё перестало быть очевидным и стало чрезвычайно сложным, хотя я думаю, что большая часть этого была вызвана тем, что одна из моих двух доступных клеток мозга была занята борьбой с тяжёлой формой ковида. Я потратил пару дней на попытки понять части кода, засыпал, а затем забывал, что же я выяснил. Весь процесс потребовал более недели обратного инжиниринга частей tcpip.sys, чтобы разобраться, что происходит. Но пост в блоге Акселя был чрезвычайно полезен.

  • Изучив функции и структуры, которые Аксель восстановил, а также то, куда они передаются, становится ясно, что единственный аргумент, передаваемый в Ipv6pProcessOptions(), — это та же структура packet_t, описанная в статье. По сути, указатель, передаваемый в Ipv6pProcessOptions и итерируемый IppSendErrorList, представляет собой связный список пакетов.

  • Итак, я установил точку останова на Ipv6pProcessOptions() и проверил список.

image

Поле list->Next равно NULL.

  • Каждый раз, когда срабатывала моя точка останова, список содержал только один пакет. Я потратил больше времени, чем хотелось бы признавать, пытаясь понять, почему и как сделать так, чтобы мой список действительно был списком. Моей первой мыслью была фрагментация IPv6: IPv6 позволяет отправителю разбивать большие пакеты на отдельные меньшие, и было бы логично хранить их вместе в списке.

  • После обширного обратного инжиниринга я подтвердил свои предположения, хотя список фрагментов не связан с тем, с которым мы имеем дело здесь.

Скачать инструмент