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

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

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

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

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

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/bazad/launchd-portrep
Повышение привилегийФреймворки для эксплойтовЭксплуатацияТестирование на ПроникновениеRed TeamingЭксплуатация Бинарных Файлов
GitHubbazad/launchd-portrep

launchd-portrep

CVE-2018-4280: Уязвимость замены портов Mach в launchd на macOS 10.13.5, приводящая к локальному повышению привилегий и обходу SIP.

Репозиторий
596107 лет назадПроверено Kitploit

Популярное

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

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

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

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

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

launchd-portrep

launchd-portrep — это эксплойт для уязвимости замены портов в launchd, начальном процессе пользовательского пространства и демоне управления службами в macOS. Отправляя специально сформированное сообщение Mach на загрузочный порт, можно вынудить launchd освободить своё право отправки для любого порта Mach, к которому атакующий также имеет право отправки. Это позволяет атакующему выдавать себя за любую службу launchd, к которой он может обратиться, перед остальной системой.

Уязвимость

Launchd мультиплексирует несколько различных обработчиков сообщений Mach на своём основном порту, включая MIG-обработчик для сообщений исключений. Если процесс отправляет сообщение mach_exception_raise или mach_exception_raise_state_identity на свой собственный загрузочный порт, launchd получает и обрабатывает это сообщение как исключение уровня хоста.

К сожалению, обработка этих сообщений в launchd содержит ошибку. Если тип исключения — EXC_CRASH, то launchd освобождает порты потока и задачи, отправленные в сообщении, а затем возвращает KERN_FAILURE из служебной процедуры, что заставляет систему MIG снова освободить эти порты. (Предполагается, что если служебная процедура возвращает успех, то она приняла владение всеми ресурсами в сообщении Mach; если же процедура возвращает ошибку, то не приняла владение ни одним из ресурсов.)

Вот код служебной процедуры launchd для сообщений mach_exception_raise, декомпилированный с помощью IDA/Hex-Rays и слегка отредактированный для удобства чтения:

kern_return_t __fastcall
catch_mach_exception_raise(                             // (a) Служебная процедура
        mach_port_t           exception_port,           //     вызывается со значениями
        mach_port_t           thread,                   //     непосредственно из сообщения
        mach_port_t           task,                     //     Mach, отправленного клиентом.
        unsigned int          exception,                //     Порты thread и task могут
        mach_exception_data_t code,                     //     быть произвольными правами
        unsigned int          codeCnt)                  //     отправки.
{
    kern_return_t kr;      // eax@1 MAPDST
    kern_return_t result;  // eax@10
    int pid;               // [rsp+14h] [rbp-43Ch]@1
    char codes_str[1024];  // [rsp+20h] [rbp-430h]@5
    __int64 __stack_guard; // [rsp+420h] [rbp-30h]@1

    __stack_guard = *__stack_chk_guard_ptr;
    pid = -1;
    kr = pid_for_task(task, &pid);
    if ( kr )
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    if ( codeCnt )
    {
        do
        {
            __snprintf_chk(codes_str, 0x400uLL, 0, 0x400uLL, "0x%llx", *code);
            ++code;
            --codeCnt;
        }
        while ( codeCnt );
    }
    launchd_log_2(
        0LL,
        3LL,
        "Исключение уровня хоста: pid = %d, thread = 0x%x, "
            "type exception = 0x%x, codes = { %s }",
        pid,
        thread,
        exception,
        codes_str);
    kr = deallocate_mach_port(thread);                  // (b) Порт "thread", отправленный
    if ( kr )                                           //     в сообщении, освобождается.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    kr = deallocate_mach_port(task);                    // (c) Порт "task", отправленный в
    if ( kr )                                           //     сообщении, освобождается.
    {
        _os_assumes_log(kr);
        _os_avoid_tail_call();
    }
    result = 0;
    if ( *__stack_chk_guard_ptr == __stack_guard )
    {
        LOBYTE(result) = exception == 10;               // (d) Если тип исключения — 10
        result *= 5;                                    //     (EXC_CRASH), то возвращается
    }                                                   //     ошибка KERN_FAILURE.
    return result;                                      //     MIG снова освободит порты.
}                                                       //

Это двойное освобождение имён портов проблематично, поскольку процесс может установить любые порты в качестве портов задачи и потока в сообщении об исключении. Launchd не проверяет, соответствуют ли полученные права отправки реальному потоку и задаче; порты могут быть, например, правами отправки на порты, уже находящиеся в IPC-пространстве launchd. Тогда двойное освобождение приведёт к тому, что launchd потеряет пользовательскую ссылку на один из своих собственных портов.

Эта ошибка может быть использована для освобождения права отправки launchd на любой порт Mach, к которому атакующий процесс также имеет право отправки. В частности, если атакующий процесс может найти системную службу через launchd, то он может освободить право отправки launchd на эту службу, а затем выдать себя за эту службу перед остальной системой. После этого существует множество способов получения системных привилегий.

Стратегия эксплуатации для получения task_for_pid-allow

Эта ошибка является менее общей версией CVE-2016-7637 — проблемы обработки пользовательских ссылок на порты Mach в XNU, обнаруженной Иэном Биром, которая позволяла процессам освобождать порты Mach в других процессах. Иэн Бир использовал эту уязвимость в macOS, заменяя право отправки launchd на конечную точку com.apple.CoreServices.coreservicesd и выдавая себя за coreservicesd перед остальной системой. Coreservicesd является привлекательной целью, потому что это одна из немногих служб, которым клиенты отправляют свой порт задачи в сообщении Mach. Заменив право отправки launchd на coreservicesd своим собственным портом и затем запуская привилегированных клиентов, чтобы те обращались к coreservicesd и общались с ним, он смог получить порт задачи привилегированного процесса и выполнить код внутри этого процесса.

Поскольку поведение macOS не изменилось, я в основном скопировал стратегию эксплуатации Иэна Бира для данной уязвимости. Мы отправляем сообщения об исключениях в launchd, содержащие порт службы coreservicesd, до тех пор, пока не освободим право отправки launchd на этот порт. Мы можем обнаружить, когда право освобождено, снова вызвав bootstrap_look_up() для этой службы: если launchd возвращает недействительное имя порта, значит, мы успешно освободили право отправки launchd на порт. Затем мы многократно регистрируем и отменяем регистрацию большого количества служб в launchd, пока одна из зарегистрированных служб не получит то же имя порта Mach в IPC-пространстве launchd, что и исходный порт coreservicesd. В этот момент любой процесс, который ищет com.apple.CoreServices.coreservicesd в launchd, получит право отправки на нашу поддельную службу вместо реальной coreservicesd. Затем мы запускаем MITM-сервер на порту поддельной службы, проверяя все порты Mach в сообщениях, полученных от клиентов, прежде чем пересылать их реальной coreservicesd. На этом этапе мы отправляем сообщение sysdiagnose, заставляя его запустить tailspin, что приводит к подключению sysdiagnose к нашему поддельному порту coreservicesd и отправке нам своего порта задачи. Поскольку sysdiagnose имеет право task_for_pid-allow, мы теперь можем получить порт задачи для любого процесса.

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

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