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

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

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

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

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

Категории

Все категории
Loading categories
multi_path — CVE-2018-4241: переполнение кучи ядра XNU из-за плохой проверки границ в MPTCP для iOS 11 - 11.3.1 выпущено Яном Биром. | Kitploit
Инструменты/GitHubGitHub/0neday/multi_path
Фреймворки для эксплойтовБезопасность iOSКриминалистика памятиАнализ уязвимостейЭксплуатацияМобильная безопасностьЭксплуатация Бинарных Файлов
GitHub0neday/multi_path

multi_path

CVE-2018-4241: переполнение кучи ядра XNU из-за плохой проверки границ в MPTCP для iOS 11 - 11.3.1 выпущено Яном Биром.

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

Популярное

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

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

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

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

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

multi_path - эксплойт для проблемы p0 1558 (CVE-2018-4241)

@i41nbeer

mptcp_usr_connectx является обработчиком системного вызова connectx для семейства сокетов AP_MULTIPATH.

Логика этой функции неверно обрабатывает sockaddr источника и назначения, которые не являются AF_INET или AF_INET6:

  // verify sa_len for AF_INET:

  if (dst->sa_family == AF_INET &&
      dst->sa_len != sizeof(mpte->__mpte_dst_v4)) {
    mptcplog((LOG_ERR, "%s IPv4 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
    error = EINVAL;
    goto out;
  }

  // verify sa_len for AF_INET6:

  if (dst->sa_family == AF_INET6 &&
      dst->sa_len != sizeof(mpte->__mpte_dst_v6)) {
    mptcplog((LOG_ERR, "%s IPv6 dst len %u\n", __func__, dst->sa_len), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
    error = EINVAL;
    goto out;
  }

  // code doesn't bail if sa_family was neither AF_INET nor AF_INET6

  if (!(mpte->mpte_flags & MPTE_SVCTYPE_CHECKED)) {
    if (mptcp_entitlement_check(mp_so) < 0) {
      error = EPERM;
      goto out;
    }

    mpte->mpte_flags |= MPTE_SVCTYPE_CHECKED;
  }

  // memcpy with sa_len up to 255:

  if ((mp_so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) {
    memcpy(&mpte->mpte_dst, dst, dst->sa_len);
  }

Изучая структуру, которую вы переполняете, вы замечаете, что можете затронуть оба поля здесь:

if (mpte->mpte_itfinfo_size > MPTE_ITFINFO_SIZE) _FREE(mpte->mpte_itfinfo, M_TEMP);

mpte_itfinfo_size находится непосредственно перед mpte_itfinfo.

При инициализации структуры указатель mpte_itfinfo указывает на небольшой встроенный массив. Если добавляется больше подпотоков, чем туда помещается, они вместо этого помещаются в буфер кучи, и mpte_itfinfo будет указывать на него.

Если бы у вас была другая ошибка (например, ошибка раскрытия кучи ядра из async_wake), вы могли бы перезаписать поле mpte_itfinfo любым допустимым объектом зоны, и оно было бы освобождено (на самом деле, вы также могли бы перезаписать его смещением внутри этого объекта для еще большего веселья!)

Однако у нас этого нет.

Вместо этого другой подход — частично перезаписать указатель. Если мы частично перезапишем его нулевыми байтами, мы можем указать его на значение, выровненное по границе 256 байт, 65 Кбайт, 16 Мбайт или 4 Гбайт.

В этом эксплойте я выбираю перезапись 3 байт нулями, что приведет к kfree адреса mpte_itfinfo, округленного вниз до следующей границы 16 Мбайт.

Поток эксплуатации выглядит следующим образом:

Поочередно выделяйте 16 Мбайт ipc_kmsgs, затем кучу сокетов mptcp. Цель здесь — получить выделение kalloc.2048 на этой границе 16 Мбайт.

Используйте ошибку, чтобы освободить одно из ipc_kmsgs, переместив эту страницу в промежуточный список и поместив выровненное по 16 Мбайт выделение в список свободных страниц kalloc.2048.

Выделите кучу заполненных каналов по 2047 байт; резервные буферы для этих каналов будут взяты из kalloc.2048, надеюсь, включая наш выровненный по 16 Мбайт адрес.

Запустите ошибку второй раз, освободив тот же адрес, а затем выделите кучу предварительно выделенных буферов ipc_kmsg из kalloc.2048.

Теперь у нас, надеюсь, есть ipc_kmsg (в который мы можем отправлять сообщения и затем получать) и буфер канала (который мы можем читать и записывать), перекрывающиеся друг с другом.

Я использую трюк с портом исключения потока из extra_recipe, чтобы отправлять сообщения в предварительно выделенный буфер ipc_kmsg. Каждый раз мы проверяем каждый из каналов, чтобы увидеть, содержит ли какой-нибудь из них сообщение. Когда мы находим правильную пару (ipc_kmsg, канал), мы можем переписать сообщение, чтобы отправить себе фиктивный порт, который находится внутри буфера канала. Я структурирую этот фиктивный порт как в async_wake (который я основал на yalu 10.2 от @qwertyoruiopz и @marcograss), чтобы получить примитив раннего чтения ядра.

Используя примитив чтения ядра, я нахожу задачу ядра и создаю фиктивный порт, который позволяет более легко читать/записывать память ядра через mach_vm_read/mach_vm_write.

Предостережение: Для подключения сокетов mptcp требуется право com.apple.developer.networking.multipath, которое требует сертификата разработчика Apple, который может купить любой желающий.

Надёжность: Это инструмент для исследований в области безопасности и очень далёк от совершенства. Однако он должен работать большую часть времени, и когда он работает, он должен хорошо очищать ресурсы, чтобы не произошло паники позже.

Чтобы повысить вероятность его работы:

  • выключите Wi-Fi и перейдите в режим полёта
  • перезагрузите устройство
  • подождите 30 секунд после перезагрузки
  • запустите приложение из Xcode

Поддерживаемые устройства: Он должен работать на iOS 11.0 - 11.3.1 включительно. Я тестировал на: iPod Touch 6g, iPhone 6s, iPhone SE, iPhone 7, iPhone 8

API: #include "sploit.h" и вызовите go() для запуска эксплойта. Если он сработал, вы можете использовать функции из kmem.h для чтения и записи памяти ядра

Примечания: Несколько человек публично сравнили эту ошибку с патчем (или их 0day был исправлен ;) читайте их материалы для более подробной информации: @elvanderb сделал короткий доклад об этой ошибке на rump.beer в Париже 31 мая: https://www.rump.beer/2018/slides/ios_48h.pdf @jaakerblom опубликовал рабочий эксплойт на github 1 июня: https://github.com/potmdehex/multipath_kfree Техника Джона похожа на мою, но он делает переполнение на два байта, а не на три, и заменяет другими объектами. хорошая работа!

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