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

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

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

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

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

Категории

Все категории
Loading categories
xpc-string-leak — CVE-2018-4248: Чтение за пределами буфера в libxpc во время сериализации строк. | Kitploit
Инструменты/GitHubGitHub/bazad/xpc-string-leak
РазведкаКриминалистика памятиАнализ уязвимостейЭксплуатацияСбор информацииЭксплуатация Бинарных Файлов
GitHubbazad/xpc-string-leak

xpc-string-leak

CVE-2018-4248: Чтение за пределами буфера в libxpc во время сериализации строк.

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

Популярное

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

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

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

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

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

xpc-string-leak

xpc-string-leak — это демонстрационный эксплойт для чтения памяти за пределами границ в libxpc. Этот эксплойт использует уязвимость для чтения памяти кучи за пределами границ из diagnosticd, процесса с корневыми привилегиями без песочницы и правами task_for_pid-allow.

Уязвимость: CVE-2018-4248

На macOS 10.13.5 и iOS 11.4 функция _xpc_string_deserialize не проверяет, что десериализованная строка имеет правильную длину, перед созданием объекта XPC-строки с помощью _xpc_string_create. Это может привести к чтению кучи за пределами границ в стиле Heartbleed, если XPC-строка затем сериализуется в другое XPC-сообщение.

Вот реализация _xpc_string_deserialize, декомпилированная с помощью IDA:

OS_xpc_string *__fastcall _xpc_string_deserialize(OS_xpc_serializer *xserializer)
{
    OS_xpc_string *xstring; // rbx@1
    char *string; // rax@4
    char *contents; // [rsp+8h] [rbp-18h]@1
    size_t size; // [rsp+10h] [rbp-10h]@1 MAPDST

    xstring = 0LL;
    contents = 0LL;
    size = 0LL;
    if ( _xpc_string_get_wire_value(xserializer, (const char **)&contents, &size) )
    {
        if ( contents[size - 1] || (string = _xpc_try_strdup(contents)) == 0LL )
        {
            xstring = 0LL;
        }
        else
        {
            xstring = _xpc_string_create(string, size - 1);
            LOBYTE(xstring->flags) |= 1u;
        }
    }
    return xstring;
}

_xpc_string_deserialize сначала вызывает _xpc_string_get_wire_value для получения указателя на данные строки, а также сериализованного размера строки, указанного в заголовке строки. Затем _xpc_string_deserialize проверяет, что строка имеет нулевой терминатор в конце указанного размера, но, что критично, не проверяет, что нет нулевого терминатора раньше в данных. И наконец, она создает копию строки в куче и создает объект OS_xpc_string с помощью _xpc_string_create.

Вот декомпилированный код для _xpc_string_create:

OS_xpc_string *__fastcall _xpc_string_create(const char *string, size_t length)
{
    OS_xpc_string *xstring; // rax@1

    xstring = (OS_xpc_string *)_xpc_base_create(&OBJC_CLASS___OS_xpc_string, 16LL);
    if ( (((_DWORD)length + 4) & 0xFFFFFFFC) + 4 < length )
        _xpc_api_misuse("Unreasonably large string");
    xstring->wire_length = ((length + 4) & 0xFFFFFFFC) + 4;
    xstring->string = string;
    xstring->length = length;
    return xstring;
}

_xpc_string_create доверяет значению длины, переданному из _xpc_string_deserialize, и устанавливает соответствующие поля в объекте OS_xpc_string. В этот момент десериализованная строка может иметь поле length, превышающее размер выделенных данных строки.

Эксплуатация

Теоретически это можно было бы использовать для вызова повреждения памяти в сервисах, которые получают длину строки с помощью xpc_string_get_length, но такой шаблон встречается редко. Менее мощная, но более практичная стратегия эксплуатации — заставить строку повторно сериализоваться и отправиться обратно нам, предоставив окно в память процесса-жертвы в стиле Heartbleed.

Вот реализация _xpc_string_serialize:

void __fastcall _xpc_string_serialize(OS_xpc_string *string, OS_xpc_serializer *serializer)
{
    int type; // [rsp+8h] [rbp-18h]@1
    int size; // [rsp+Ch] [rbp-14h]@1

    type = *((_DWORD *)&OBJC_CLASS___OS_xpc_string + 10);
    _xpc_serializer_append(serializer, &type, 4uLL, 1, 0, 0);
    size = LODWORD(string->length) + 1;
    _xpc_serializer_append(serializer, &size, 4uLL, 1, 0, 0);
    _xpc_serializer_append(serializer, string->string, string->length + 1, 1, 0, 0);
}

Параметр length объекта OS_xpc_string используется при сериализации без проверки, то есть множество байт читается из кучи в сериализованное сообщение. Если десериализованная строка была короче указанной длины, сообщение будет заполнено данными кучи за пределами границ.

Мы все еще ограничены эксплуатацией XPC-сервисов, которые отражают часть XPC-сообщения обратно клиенту, но это встречается гораздо чаще. Например, на macOS и iOS diagnosticd является многообещающим кандидатом, который также не имеет песочницы, работает с root-правами и имеет привилегии task_for_pid. Diagnosticd отвечает за обработку диагностических сообщений (например, сообщений, генерируемых os_log) и их потоковую передачу клиентам, заинтересованным в получении этих сообщений. Зарегистрировавшись для получения собственного диагностического потока и отправив диагностическое сообщение с более короткой, чем ожидалось, строкой, мы можем получить снимок некоторых данных в куче diagnosticd, что может помочь в получении выполнения кода в процессе.

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

Чтобы собрать, выполните make. Смотрите верхнюю часть Makefile для различных опций сборки.

Запустите эксплойт, указав размер утечки в командной строке:

$ ./xpc-string-leak 0x40
0x2000000000000000 0xe00007ff39bf0992
0x00007fff56858570 0x00007fff7ed23d0e
0x0000000000000000 0x0000000000000000
0x00007fff7ed52be2 0x00007fff7ed29ed6

Размер утечки должен быть кратен 8 и не менее 16.

Лицензия

Код xpc-string-leak выпущен в общественное достояние. В качестве любезности я прошу, чтобы при ссылке или использовании любого из этого кода вы указывали мое авторство.

Хронология

Я обнаружил эту ошибку в начале 2018 года (январь или февраль), но забыл исследовать ее до мая. Я сообщил о проблеме в Apple 9 мая, ей был присвоен CVE-2018-4248, и она была исправлена в iOS 11.4.1 и macOS 10.13.6 9 июля.


Brandon Azad

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