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

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

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

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

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

Категории

Все категории
Loading categories
LSPromise — Android полная цепочка эксплойтов, позволяющая повысить привилегии от локального недоверенного приложения до root/ядра, объединяющая CVE-2026-49881 и CVE-2026-43284 | Kitploit
Инструменты/GitHubGitHub/lsposed/lspromise
Безопасность AndroidПовышение привилегийФреймворки для эксплойтовАнализ уязвимостейЭксплуатацияПост-эксплуатацияРазработка Полезной Нагрузки
GitHublsposed/lspromise

LSPromise

Android полная цепочка эксплойтов, позволяющая повысить привилегии от локального недоверенного приложения до root/ядра, объединяющая CVE-2026-49881 и CVE-2026-43284

Репозиторий
51914 ч 15 мин назадПроверено Kitploit

Популярное

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

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

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

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

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

LSPromise

Полная цепочка эксплуатации, которая позволяет повысить привилегии от локального ненадёжного приложения до root/ядра. Она не включает повреждения памяти или гонки данных, поэтому атакующим не нужно выполнять сложный heap spraying или обходить механизмы защиты от уязвимостей повреждения памяти, такие как KASLR, MTE или CFI, что делает эту цепочку эксплуатации успешной на 100% на уязвимых устройствах.

Протестировано на Pixel 10 с первоначальным официальным релизом Android 17. Обратите внимание, что она не работает на Pixel 6a, и эта проблема также может возникать на других устройствах с деревьями ядра 6.1.xxx-android14 из-за другой ошибки в этих ядрах.

Использование: установите приложение KernelSU, откройте это приложение, нажмите «Run userspace exploit», затем «Run kernel exploit and load KernelSU». После успешной эксплуатации KernelSU будет активирован, и вы сможете использовать его для предоставления root-доступа другим приложениям. Известная проблема: если вы уже запускали эксплойт ядра и хотите запустить его снова, необходимо перезагрузить устройство.

Видеозапись экрана: нажмите здесь

Writeup

Цепочка состоит из двух различных уязвимостей: одна — 0-day в сервисе Telecom, а другая — 1-day в ядре, раскрытая 3 месяца назад. Но AOSP и устройства Pixel (кроме тех, что работают на бета-версиях QPR) остаются уязвимыми на момент написания.

Проникновение в system_server

Первая уязвимость цепочки — простая логическая ошибка, появившаяся в Android 17. Она берёт начало из безумного изменения, которое добавляет следующий код в InCallController.java:

root@kitploit:~
        PackageManager packageManager = mContext.getPackageManager();
        Context userContext = mContext.createContextAsUser(userHandle,
                0 /* flags */);
        PackageManager userPackageManager = userContext != null ?
                userContext.getPackageManager() : packageManager;

        List<ResolveInfo> entries;
        entries = userPackageManager.queryIntentServices(
                serviceIntent,
                PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_COMPONENTS);
        for (ResolveInfo entry : entries) {
            ServiceInfo serviceInfo = entry.serviceInfo;

            if (serviceInfo != null) {
                boolean isMetaFlag = serviceInfo.metaData != null &&
                        serviceInfo.metaData.getBoolean(
                                "android.telecom.CLASS_EXISTENCE_CHECK", false);
                if (isMetaFlag && !serviceClassExists(serviceInfo, userHandle)) {
                    continue;
                }
            }
        }

Соответствующий метод serviceClassExists() определён следующим образом:

root@kitploit:~
    /**
     * Verifies that the class for a given ServiceInfo exists within its package.
     * This prevents a system crash if a service is declared in the manifest but its
     * class was not included in the compiled code.
     * @param serviceInfo The ServiceInfo of the service to check.
     * @param userHandle The user under which to check for the service.
     * @return {@code true} if the class exists, {@code false} otherwise.
     */
    private boolean serviceClassExists(ServiceInfo serviceInfo, UserHandle userHandle) {
        Log.i(this, "serviceClassExists check");
        try {
            Context packageContext = mContext.createPackageContextAsUser(
                    serviceInfo.packageName,
                    Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY, userHandle);
            ClassLoader classLoader = packageContext.getClassLoader();
            Class.forName(serviceInfo.name, false, classLoader);
            return true;
        } catch (NameNotFoundException | ClassNotFoundException e) {
            Log.w(this, "Skipping InCallService: class not found for " + serviceInfo.name);
            return false;
        } catch (Exception e) {
            Log.e(this, e, "Error checking for existence of " + serviceInfo.name);
            return false;
        }
    }

Это самая невероятная уязвимость, которую я когда-либо видел. Код использует Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY для загрузки кода из произвольного приложения; хотя, похоже, существуют некоторые меры, предназначенные для предотвращения произвольного выполнения кода, такие как передача false в Class.forName() для предотвращения инициализации класса, приложение всё равно может объявить собственный AppComponentFactory, который вызывается при обращении к getClassLoader().

С другой стороны, ошибка существует в InCallController.java, который является частью пакета com.android.server.telecom, а не com.android.phone. Стоит отметить, что пакет объявляет android:sharedUserId="android.uid.system" и android:process="system" в AndroidManifest.xml, поэтому он работает в процессе system_server, одном из наиболее привилегированных пользовательских процессов в Android. Таким образом, теперь у нас есть возможность выполнять произвольный Java-код внутри system_server.

Удивительно, что даже инженер Google может совершить такую большую ошибку в эпоху ИИ. Мы обнаружили её и сообщили в команду безопасности Android 23 июля 2026 года. Они сказали нам, что это дубликат. Google перешёл с ежемесячного на ежеквартальный выпуск бюллетеня безопасности, что может объяснить, почему уязвимость не была исправлена через 3 месяца после выпуска Android 17.

Уязвимости присвоен номер CVE-2026-49881, и она исправлена в сентябре 2026 года с помощью Remove serviceClassExists logic to address security vulnerability.

Проникновение в сетевой стек

Первая ошибка позволяет нам повысить привилегии до system, но это всё ещё далеко от root. Полный root требует как минимум UID 0 и отсутствия ограничений со стороны SELinux.

Теперь пришло время представить 1-day в ядре: уязвимости DirtyFrag. Основные принципы здесь подробно описываться не будут; пожалуйста, обратитесь к writeup первоначального репортёра. Существует 2 варианта: CVE-2026-43500 требует RxRPC, который отключён для Android Generic Kernels; CVE-2026-43284 требует xfrm-ESP и эксплуатируется на Android. Однако SELinux запрещает ненадёжным приложениям использовать эту функцию:

root@kitploit:~
# Privileged netlink socket interfaces.
neverallow { appdomain -network_stack }
    domain:{
        netlink_tcpdiag_socket
        netlink_nflog_socket
        netlink_xfrm_socket
        netlink_audit_socket
        netlink_dnrt_socket
    } *;

Единственные разрешённые домены — это system_server, network_stack и netd. Чтобы эксплуатировать DirtyFrag, атакующие должны сначала скомпрометировать один из процессов, включённых в белый список.

Объединим две ошибки. В то время как ошибка в пользовательском пространстве позволяет нам выполнять Java-код внутри system_server, SELinux также запрещает system_server как загружать нативные библиотеки из /data, так и отображать анонимную исполняемую память. Это делает невозможным использование нативного кода, что повышает сложность эксплуатации. Поэтому предпочтительнее выполнять код внутри com.android.networkstack, который может загружать нативный код из нашего APK и имеет достаточные привилегии для эксплуатации DirtyFrag.

К счастью, system_server — это процесс, в котором работает ActivityManager. ActivityManager хранит дескрипторы IApplicationThread каждого процесса приложения в Java-карте, и, поскольку мы работаем в том же процессе, что и ActivityManager, мы можем получить их с помощью Java-рефлексии. С их помощью мы можем отправлять произвольные команды в com.android.networkstack, чтобы заставить его загрузить наш код. Для получения дополнительной информации об этом трюке, пожалуйста, обратитесь к моему предыдущему эксплойту для CVE-2026-0091.

Проникновение в ядро

DirtyFrag позволяет перезаписывать файлы, доступные только для чтения. Это мощный примитив в мире Linux, поскольку мы можем перезаписать бинарный файл su, у которого установлен бит SUID. Однако в мире Android у нас нет su. Мы обращаемся к эксплойту polygraphene для DirtyPipe, чтобы превратить DirtyFrag в выполнение кода ядра на Android:

  1. Мы пропатчиваем libc.so, libc++.so и /vendor/lib64/libstagefright_aidl_bufferpool2.so через DirtyFrag. libstagefright_aidl_bufferpool2.so помечен доменом vendor_file, поэтому к нему нельзя получить доступ из процесса сетевого стека. Решение состоит в том, чтобы сначала пропатчить /apex/com.android.runtime/bin/crash_dump64, выполнить его, и как только мы перейдём в домен crash_dump, мы сможем открыть libstagefright_aidl_bufferpool2.so.
  2. Создаём и уничтожаем осиротевший процесс, чтобы вызвать выполнение кода в процессе init. Поскольку libc++.so пропатчен, наш код выполняется с UID 0 в домене init. Затем мы выполняем /vendor/bin/modprobe, чтобы перейти в домен .
Скачать инструмент
vendor_modprobe
  • Когда выполняется modprobe, поскольку libc.so также пропатчен, наш код выполняется в домене vendor_modprobe. Теперь мы можем загружать модули ядра, но только для файлов с определёнными метками. Мы загружаем libstagefright_aidl_bufferpool2.so, у которого есть метка vendor_file.
  • Поскольку мы пропатчили libstagefright_aidl_bufferpool2.so, реальное содержимое этого файла было заменено нашим собственным модулем ядра. Модуль ядра загружается, и теперь мы можем делать что угодно, включая изменение политики SELinux или перевод SELinux в permissive-режим.
  • Мы переводим SELinux в permissive-режим. Теперь у нас есть UID 0 с отключённым SELinux; мы запускаем KernelSU для вас.