Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
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
Outils/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

Voir le dépôt
951250il y a 21 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Ceci est un PoC et un writeup pour CVE-2026-49881, un problème logique dans la classe InCallController du service Telecom d'Android 17 qui permet à une application non privilégiée d'obtenir une exécution de code arbitraire en tant que UID 1000 system_server sans aucune interaction supplémentaire de l'utilisateur. Nous montrons également ici que l'exécution de code dans system_server peut encore être facilement adaptée pour obtenir une persistance, même sur les versions modernes d'Android.

J'ai signalé cette vulnérabilité à l'équipe de sécurité Android le 2026-04-10, elle a été confirmée le 2026-05-06, et elle a été corrigée dans le bulletin de sécurité Android de septembre 2026. (voir ici pour le patch)

Au moment du signalement, elle n'affectait activement que les builds Pixel à partir d'Android 16 QPR3 (ainsi que les builds bêta 17) à ma connaissance, mais elle s'est ensuite propagée à la version stable AOSP d'Android 17.

Pour vous protéger de ce problème, assurez-vous d'installer la mise à jour du système Google Play ainsi que le correctif de sécurité système. (Telecom est un composant mainline depuis Android 17)

TLPE

Notes sur le PoC

  • Le PoC démontre l'obtention d'une exécution de code dans system_server en utilisant la vulnérabilité, journalise id et la trace de pile dans logcat, et se réinstalle en tant que composant system_server.
  • Une fois le PoC installé, appuyer sur le bouton Start Exploit ou passer un appel via la pile telecom déclenchera l'exploit.
  • Compilez le PoC en exécutant le build.sh inclus. Sinon, vous pouvez exécuter manuellement ./gradlew assembleSystemRelease, déplacer le app-system-release.apk résultant vers app/src/poc/assets/system.apk, puis exécuter ./gradlew assemblePocRelease.
  • Le PoC enregistrera son propre certificat comme certificat ancêtre pour l'UID 1000 après une exploitation réussie. Cet état persiste à travers les OTA, y compris le correctif de la vulnérabilité elle-même. Pour nettoyer votre appareil après une exécution du PoC, vous devez appuyer sur le bouton « Uninstall » dans le PoC (qui nettoie le certificat injecté) — néanmoins, je recommande fortement d'utiliser votre propre keystore de release pour signer un APK PoC compilé pendant les tests. (plutôt que celui que le PoC utilise par défaut à TLPE/app/teststore.jks)
  • Notez que le PoC après être entré dans system_server désactive également Play Protect en définissant package_verifier_user_consent à -1 dans Settings.Global car il peut parfois intercepter la transaction de réinstallation en raison de signatures inconnues. Vous devez le réactiver dans les Paramètres après les tests.
  • Il a été validé sur Pixel Android et AOSP, mais l'étape d'exécution de code devrait fonctionner sur les versions Android 17 personnalisées par les OEM. L'étape de réinstallation en tant que system_server pourrait nécessiter une personnalisation par OEM car elle repose sur la traversée de la structure PMS en utilisant des symboles que les OEM modifient parfois.

La sortie logcat attendue du PoC est :

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

C'est une vulnérabilité inhabituellement directe. Chaque fois que certaines actions liées à Telecom se produisent, InCallController tente de découvrir les services disponibles via getInCallServiceComponents. Cela se déclenche naturellement lorsqu'un appel est enregistré auprès du système, mais une application peut en réalité le déclencher à la demande également grâce à l'API d'appels transactionnels TelecomManager.addCall. (note : c'est ce que le bouton Start Exploit du PoC utilise) Cette API nécessite MANAGE_OWN_CALLS, mais c'est une permission normale et invisible pour l'utilisateur, accordée automatiquement lors de l'installation.

Cette énumération est implémentée sur les versions vulnérables comme :

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;
Télécharger l’outil