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

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

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

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

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

Категории

Все категории
Loading categories
cve-2026-43687 — Заметки по обратной разработке и самодостаточный PoC для гонки в кэше доступа клиента NFS в macOS (CVE-2026-43687), с diff дизассемблирования kext и захватом гонки через dtrace. | Kitploit
Инструменты/GitHubGitHub/jvidhan/cve-2026-43687
Криминалистика памятиАнализ уязвимостейЭксплуатацияОбратная инженерияАнализ Бинарных ФайловСтатьи и ИсследованияОбучение и Образование
GitHubjvidhan/cve-2026-43687

cve-2026-43687

Заметки по обратной разработке и самодостаточный PoC для гонки в кэше доступа клиента NFS в macOS (CVE-2026-43687), с diff дизассемблирования kext и захватом гонки через dtrace.

Репозиторий
410 ч 17 мин назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-43687 — Заметки по обратной разработке и воспроизведение

Независимая обратная разработка гонки в кэше доступа клиента NFS в macOS (CVE-2026-43687), а также рабочий PoC, который вызывает гонку и фиксирует её в реальном времени с помощью dtrace.

Ошибка представляет собой несинхронизированное чтение указателя кэша доступа nfsnode в _nfs_vnop_access. Вредоносный сервер NFSv3 может заставить кэш доступа перераспределиться в тот момент, когда другой поток читает его, что приводит к раскрытию памяти ядра, на которое может влиять враждебный сервер. macOS 26.7 исправляет это путём вставки lck_rw_t по адресу nfsnode+0x158 и взятия его в разделяемом режиме вокруг чтения кэша.


CVE кратко

ПолеЗначение
CVECVE-2026-43687
Компонентcom.apple.filesystems.nfs (_nfs_vnop_access)
ЗатронутоmacOS Tahoe 26.6 и более ранние, iOS 26.x и более ранние
Исправлено вmacOS Tahoe 26.7, macOS Golden Gate 27, iOS 26.7, iOS 27
Влияние по бюллетеню"Подключение к вредоносному серверу NFS может раскрыть память ядра."
CVSS v3.16.5 (Средний) — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
СообщеноR4mbb из KRsecurity и Peter Malone (согласно бюллетеню Apple)

Зачем нужен этот разбор

Бюллетень Apple по CVE-2026-43687 описывает влияние и версию с исправлением. Он не описывает технический механизм:

  • Какое поле в nfsnode подвержено гонке
  • Где происходит второе чтение
  • Почему исправление вставляет блокировку именно по этому смещению
  • Почему PoC должен использовать access(2), а не stat(2)
  • Почему некоторые формы ответов NFSv3 молча ломают монтирование, даже когда формат передачи почти корректен

На момент написания публичного технического разбора найдено не было. Этот репозиторий восполняет этот пробел независимым анализом обратной разработки NFS kext между 26.6 и 26.7, а также рабочим PoC, который воспроизводит гонку на живой цели.

Это не заявка на открытие. CVE был сообщён R4mbb и Peter Malone и исправлен Apple. Вклад здесь — это технический анализ и воспроизведение.


Краткое описание уязвимости

_nfs_vnop_access в клиенте NFS читает nfsnode+0x158 — указатель на массив кэша доступа для каждого UID — дважды в рамках одного вызова, не удерживая никакой блокировки:

root@kitploit:~
; macOS 26.6, com.apple.filesystems.nfs
fffffe000b52def4   ldr  w8,  [x20, #0x160]     ; count
fffffe000b52def8   cmp  w23, w8
fffffe000b52defc   b.ge ...
fffffe000b52df00   ldr  x8,  [x20, #0x158]     ; cache ptr (read #1)
...
fffffe000b52df98   ldr  x8,  [x20, #0x158]     ; cache ptr (read #2)
fffffe000b52dfb0   ldr  w21, [x9]              ; dereference

Писатель, _nfs_nget, перераспределяет массив с помощью kalloc_data и сохраняет результат по +0x158 всякий раз, когда клиент видит новый UID от сервера:

root@kitploit:~
fffffe000b52100c   bl   0xfffffe000b6a1dd8    ; kalloc
fffffe000b521010   str  x0,  [x22, #0x158]    ; cache ptr
fffffe000b521018   str  w20, [x22, #0x160]    ; cache count

Если другой поток достигает _nfs_nget на том же nfsnode между двумя загрузками читателя, вторая загрузка возвращает новый указатель, тогда как первое чтение — уже использованное для вычисления смещения — было основано на старом. Последующее разыменование читает из освобождённой кучи ядра.

Исправление в 26.7:

root@kitploit:~
fffffe000b9e3064   str  x0,  [x22, #0x168]    ; cache ptr moved
fffffe000b9e306c   str  w28, [x22, #0x170]    ; cache count moved
fffffe000b9e307c   add  x0,  x22, #0x158      ; lock slot
fffffe000b9e3084   bl   _lck_rw_init          ; init RW lock

и в _nfs_vnop_access:

root@kitploit:~
fffffe000b9f0200   add  x0,  x20, #0x158
fffffe000b9f0204   bl   _lck_rw_lock_shared    ; take the lock
fffffe000b9f0208   ldr  x9,  [x20, #0x168]    ; cache pointer
...
fffffe000b9f0230   bl   _lck_rw_unlock_shared  ; release the lock

Изменение структуры:


Что содержит этот репозиторий

Обратная разработка

  • Дифф дизассемблирования _nfs_nget и _nfs_vnop_access между NFS kext 26.6 и 26.7 — см. docs/PATCH_DIFF.md
  • Идентификация поля, подверженного гонке: nfsnode+0x158 в 26.6
  • Идентификация исправления: lck_rw_t вставлен по +0x158, указатель кэша перемещён на +0x168, lck_rw_lock_shared берётся вокруг чтения
  • Анализ системных вызовов: access(2) входит в _nfs_vnop_access; stat(2) идёт через _nfs_getattr и никогда не достигает уязвимой функции
  • Подтверждение гонки во время выполнения с помощью dtrace, фиксация изменения указателя кэша в середине вызова

Полный разбор см. в docs/ANALYSIS.md, а адреса и образцы логов — в docs/ARTIFACTS.md.

Воспроизведение

  • poc.sh — самодостаточный PoC в одном файле:
    1. Останавливает nfsd от Apple, чтобы освободить порт 2049
    2. Запускает вредоносный сервер NFSv3 на 127.0.0.1, который меняет сообщаемый UID в каждом ответе
    3. Монтирует экспорт в новую точку монтирования с noac
    4. Запускает hammer-потоки для каждого пользователя, выполняющие access(2) через test -r / test -w
    5. Подключает зонд dtrace к nfs_vnop_access, записывая любой вызов, в котором nfsnode+0x158 меняется в середине вызова
    6. Выводит сводку с количеством гонок

Что демонстрирует этот PoC

  • Вредоносный сервер NFSv3, меняющий сообщаемый UID в каждом ответе
  • Перераспределение массива кэша доступа ядром жертвы в ответ на это
  • Несинхронизированное чтение в _nfs_vnop_access, наблюдающее изменение массива в течение одного вызова
  • Захват этого чередования в реальном времени с помощью dtrace

Что этот PoC НЕ демонстрирует

  • Утечку памяти ядра на уровне байтов, видимую атакующему
  • Выполнение кода, повышение привилегий или получение оболочки на жертве

Гонка — это предварительное условие для раскрытия. Чтобы превратить гонку в реальную утечку, атакующему потребовалось бы наблюдать, как читатель использует устаревший указатель, и распространить эти байты туда, откуда он может их прочитать. На arm64e значение по nfsnode+0x158 подписано PAC, а ключ, уникальный для каждой загрузки, недоступен из пользовательского пространства, поэтому один только dtrace может наблюдать гонку, но не может декодировать указатель. См. раздел "Paths tested and ruled out" в docs/ANALYSIS.md.

Продемонстрированное влияние — это сама гонка — именно то окно, которое закрывает исправление с RW-блокировкой в 26.7.


Требования

Целевой (жертвенный) хост

  • macOS 26.6 или более ранняя (уязвимое ядро)
  • Доступен dtrace (в некоторых установках может потребоваться корректировка SIP)
  • python3, dscl, mount
  • Root

Отдельный хост атакующего не нужен

PoC полностью выполняется на цели. Вредоносный сервер NFS привязывается к 127.0.0.1, а монтирование идёт через loopback. Это делает PoC самодостаточным и воспроизводимым без настройки сети.


Использование

root@kitploit:~
chmod +x poc.sh
sudo ./poc.sh

Необязательная настройка через переменные окружения:

root@kitploit:~
sudo HAMMER_COUNT=30 RUN_SECONDS=600 ./poc.sh

HAMMER_COUNT задаёт количество hammer-потоков для каждого пользователя (используются любые существующие учётные записи nfsuserNNN, при необходимости создаются). RUN_SECONDS задаёт окно dtrace.

Ожидаемый вывод

root@kitploit:~
[*] ensuring nfsuser accounts exist (UID 201..240)
    nfsuser accounts available: 12
[*] starting evil NFS server on 127.0.0.1:2049
[*] mounting /Users/Shared/nfs_test (with noac)
    mount check: hello.txt statable
[*] spawning up to 12 per-user threads + 1 root loop
    started 12 user threads + 1 root loop
[*] running dtrace for 180s — looking for RACE lines
[*] stopping dtrace
[*] cleaning up

=================== SUMMARY ===================
RACE events caught: 16

Vulnerable interleaving observed — sample:
RACE nd=fffffe5f53cbb940 in=(0,0) out=(b0967e0023297878,0)
RACE nd=fffffe5f534db940 in=(0,0) out=(84dd7e0023297878,0)
RACE nd=fffffe5f53cbb940 in=(0,0) out=(c9a37e0023297878,0)
RACE nd=fffffe5f538ab940 in=(0,0) out=(1867e0023297878,0)
RACE nd=fffffe5f539db940 in=(0,0) out=(149bfe0023297878,0)

CVE-2026-43687 trigger SUCCESSFUL
===============================================

Каждая строка RACE — это один вызов nfs_vnop_access, в котором указатель кэша доступа изменился в середине вызова.

Проверка исправления

На исправленной системе (26.7 / 27) та же нагрузка даёт ноль событий RACE. Сравнение дизассемблирования см. в docs/PATCH_DIFF.md.


Подводные камни сервера NFSv3 (для воспроизводимости)

Две ошибки в сервере PoC были исправлены в ходе разработки и задокументированы здесь, чтобы другие, создающие аналогичные инструменты, не наткнулись на них:

  1. ACCESS3resok требует post_op_attr, а не fattr3. RFC 1813 определяет ответ как post_op_attr obj_attributes; uint32 access;. post_op_attr включает префикс bool перед fattr3. Пропуск этого bool делает ответ на 4 байта короче; клиент молча отвергает его, и монтирование так и не становится рабочим.

  2. LOOKUP для имён AppleDouble (._*) должен возвращать NFS3ERR_NOENT (2), а не NFS3ERR_STALE (70). macOS проверяет наличие сайдкаров ._<name> при обычном разрешении пути. Возврат STALE отравляет монтирование.

Оба случая задокументированы в docs/ANALYSIS.md.


Замечание о значении во время выполнения

Значения out в выводе RACE имеют постоянный шаблон младших 48 бит (...7e0023297878) для разных nfsnode, различаясь только в старших 16 битах. Это подтверждает, что поле подписано PAC или обфусцировано, а не является сырым указателем ядра. Вы можете наблюдать переход состояния (NULL → заполнено) из пользовательского пространства, но не можете декодировать или разыменовать указатель без PAC-ключа ядра, уникального для каждой загрузки.

По той же причине символизация по KDK бесполезна для этих значений — они не являются адресами относительно текста.


Благодарности

  • Первоначальное обнаружение: R4mbb из KRsecurity и Peter Malone, согласно бюллетеню безопасности Apple по CVE-2026-43687.
  • Независимый анализ и PoC: jvidhan
  • Ссылки: бюллетень Apple и исправленный бинарник послужили базой для сравнения с уязвимой версией. KDK для macOS 26.6 (сборка 25G72) предоставил символы для анализа на стороне ядра.

Отказ от ответственности

Этот репозиторий предоставлен исключительно для оборонительных исследований в области безопасности и образования.

  • Он предназначен для использования против систем, которыми вы владеете или на тестирование которых у вас есть явное письменное разрешение.
  • Использование этого инструмента против систем, которыми вы не владеете и не управляете, может нарушать местные, национальные или международные законы.
  • Автор(ы) не несут никакой ответственности за любое неправомерное использование или ущерб, вызванный этим кодом.
  • PoC ограничен демонстрацией гонки в ядре. Он не достигает выполнения кода, повышения привилегий или утечки памяти на уровне байтов. Любые заявления о RCE или полном раскрытии памяти от этого PoC не подтверждаются включённым анализом.
  • Apple, macOS, XNU, NFS, autofs и automountd являются товарными знаками Apple Inc. Этот проект не связан с Apple и не одобрен ею.

Лицензия

MIT. См. LICENSE.

Скачать инструмент
СмещениеmacOS 26.6macOS 26.7
+0x158указатель на массив кэшаlck_rw_t
+0x160счётчик кэша(часть блокировки)
+0x168(другое)указатель на массив кэша
+0x170(другое)счётчик кэша