
Une méthode pour CVE-2025-31710 et pour se connecter à cmd_skt afin d'obtenir un shell root sur les modèles unisoc non corrigés
Une méthode pour CVE-2025-31710 et pour se connecter à la socket abstraite cmd_skt afin d'obtenir un shell root sur les modèles unisoc non patchés
Avant que tout le monde ne crie, Unisoc lui-même m'a autorisé à publier ceci après le bulletin CVE-2025-31710, alors restez calmes.
Commençons par une blague

Oui, vous ne rêvez pas, aujourd'hui je veux vous présenter un exploit pour un shell système sur l'application com.sprd.engineermode et comme elle fait partie des clients de confiance de cmd_skt, j'ai aussi pu y entrer. Cette socket abstraite fait partie d'un service tournant en root (cmd_services), alors oui, je suis heureux de vous présenter unisoc-su. Voici une liste des clients de confiance de cmd_skt extraite du binaire cmd_services avec ghidra qui montre que com.sprd.engineermode est présent :

Pour cet exploit, on utilise l'application com.sammy.systools de pascua28 et cli-pie de TomKing062. Il existe deux versions de cette application, l'une contient divers binaires à utiliser depuis le shell système, l'autre uniquement le cli-pie et quelques clis pour se connecter à diverses autres sockets (pour engpc vous pouvez maintenant sourcer ceci depuis le shell système, je suggère de sourcer d'abord le tools.sh), puis il existe pour chacune d'elles une version pour Android 9 (pour les appareils plus anciens, vous pouvez de toute façon reconditionner l'application avec Apktool M en sélectionnant la version souhaitée).
Comment fonctionne cette méthode : vous exécutez d'abord en tant qu'adb ou shizuku rish le UnisocEngSyshell_Enabler_Script.sh pour activer l'application com.sprd.engineermode (uniquement nécessaire sur les nouveaux modèles), puis en suivant les instructions, composez sur le téléphone *#*#83781#*#* pour lancer l'activité principale, puis entrez dans l'activité Adb shell. Ensuite, entrez sur une ligne le chemin complet du cli-pie (y compris l'applet), sur l'autre "setprop persist.sys.cmdservice.enable enable", puis appuyez sur start le plus vite possible, d'abord sur setprop puis sur la ligne du cli-pie, et boum, il affichera connected. Ensuite, appuyez sur end sur l'activité setprop et supprimez son texte, saisissez "nc -s 127.0.0.1 -p 1234 -L sh -l" ou ce que vous utilisez pour lancer le reverse shell. Puis allez dans le terminal et reconnectez-vous avec le binaire correspondant, s'il ne s'exécute pas, sourcez le script correspondant ou connectez-vous simplement avec "nc 127.0.0.1 1234", après cela "source /sdcard/Documents/unisoc-su.sh" (ou là où vous avez placé le script, mais il doit être accessible depuis le shell système). Et voilà, vous venez d'obtenir un shell root si tout est correct.
Maintenant, parlons de cet exploit : le contexte est fortement protégé par selinux, nous avons root mais toutes les protections sont toujours actives. Ce root est énorme car nous n'avons rien désactivé pour l'obtenir, contrairement à d'autres exploits similaires. Malheureusement, ce contexte n'a pas assez de pouvoir pour désactiver selinux et l'exécution semble également ne fonctionner que sur le PATH système. Concernant le service lui-même, il semble que sur Android 9 (donc avant le patch de CVE-2022-47339) il n'ait pas de groupes dans son rc de service et donc ils sont par défaut root, plus tard des groupes ont en revanche été ajoutés (et root comme gid/groupes retiré) il est donc évident que le service a été davantage restreint, mais avec selinux actif, c'est de toute façon lui qui fait la loi. Concernant le comportement du service : sur les appareils plus récents, le service semble tourner jusqu'à ce que quelque chose l'utilise ou s'y connecte, s'il n'y a aucun client connecté ni aucune commande émise, le service s'éteindra et il faudra la propriété setprop pour le rallumer, le service fait cela presque immédiatement, c'est pourquoi dans cette méthode nous exécutons le setprop et nous nous connectons rapidement, sur Android 9 le service semble attendre une commande après l'émission du setprop, cela semble être la différence entre les anciens et les nouveaux appareils, après l'exécution il s'éteint, bien sûr il est possible de simplement s'y connecter avec socat ou avec le cli-pie (ou d'exécuter le bridge), dans ce cas le service restera actif car il sera occupé par cette connexion, si aucune commande n'est fournie, le service restera en attente indéfiniment.
cmd_services.rc de la rom user d'Android 13 et de la rom eng d'Android 9 pour montrer les différences

Les CVE qui ont inspiré cette méthode : CVE-2022-47339 (cmd_services) par Lewei Qu(曲乐炜) et CVE-2025-31710 (shell système com.sprd.engineermode) par moi, bien que Lewei Qu(曲乐炜) ait apparemment eu un CVE similaire sur com.sprd.engineermode, je ne l'ai découvert qu'après avoir obtenu le mien.
Il y a aussi trois cas particuliers apparus plus tard, ils ne font pas partie de la liste des CVE inspirantes, le premier est une vulnérabilité réintroduite, je l'ajoute ici pour clarifier les choses : CVE-2025-67264 (mauvais patch de Doogee sur com.sprd.engineermode pour les nouveaux modèles unisoc, couvert ici) par moi également, le deuxième cas concerne les nouveaux modèles ZTE, on ne sait pas si cela s'applique à tous ou seulement à certains, l'activité Adb shell de com.sprd.engineermode a été conservée, sur le ZTE Blade V70 Vita le même problème que pour CVE-2025-67264 se produit, mais ZTE l'a ensuite patché en verrouillant l'activité sur userdebug/eng (pas de CVE car ils l'ont remarqué eux-mêmes) au lieu de la supprimer, en conséquence l'activité apparaît dans l'interface de l'application mais signale qu'elle ne peut pas être ouverte sur les builds user, l'appareil est vulnérable sur (probablement avant ce changement) :ZTE/EEA_P606F17/P606F17:14/UP1A.231005.007/20241231.044538:user/release-keys et a été patché sur ZTE/EEA_P606F17/P606F17:14/UP1A.231005.007/20250527.224618:user/release-keys, une chose similaire se produit sur le ZTE Blade A55, ces modèles tournent sous Android 14, là cmd_services a été réécrit et son nom changé en tool_service (et les services pouvant y accéder ont été réduits : com.sprd.engineermode, com.sprd.autoslt, com.sprd.runtime, com.spreadtrum.sgps, com.sprd.validationtools), cette nouvelle version est toujours active et ne nécessite aucun setprop, le troisième, qui est une vulnérabilité similaire à celle de ce repo affectant les anciens modèles unisoc, a été couvert ici.
Voici fournis divers scripts pour unisoc-su, un sans tutoriel : unisoc-su.sh, un qui guide pour entrer dans le shell root avec uniquement le shell système (cette méthode est plus facile, fonctionne hors ligne et sans shizuku/adb) : unisoc-su-syshell-only-tut.sh, un qui guide pour entrer dans le shell root en utilisant shizuku/adb, utilisé uniquement pour exécuter la partie setprop : unisoc-su-adb-shizuku-tut.sh, ainsi qu'une version pour se connecter à diverses sockets, sourcez celle que vous voulez depuis votre terminal, seuls unisoc-su.sh et cette dernière nécessitent d'être sourcées depuis le shell système. Un script tools.sh est également disponible dans le dossier ghostroot pour ajouter divers répertoires au PATH, compatible avec adb/système et root, ainsi qu'un script multi pour exécuter le shell système si vous ne savez pas quel nc vous avez sur votre système, qui essaiera de nc depuis divers binaires possibles jusqu'à ce que la connexion soit réussie.
J'ai également ajouté une petite app poc, c'est juste une application avec quatre boutons : un pour se connecter au shell root cmd_services, un autre pour se connecter au shell système, un bouton d'aide, un bouton pour effacer la sortie et un mini terminal. La préparation doit être faite manuellement, elle est donc sûre à utiliser.
À propos de GhostRoot (canal root post-exploitation) Un canal de commande post-exploitation furtif qui persiste en RAM et accepte les entrées de toute application non privilégiée via des E/S basées sur des fichiers.
L'exploit fonctionne jusqu'à Android 13 car sur les versions ultérieures, unisoc a retiré la balise sharedUserId de l'application EngineerMode qui est donc maintenant une application utilisateur normale, ce qui fait que selinux refuse l'exécution du cli-pie sur Android 14 et plus.
Image fournie par TomKing062
Une capture d'écran du shell système et du shell root

Voici des tutoriels vidéo pour entrer dans le shell root cmd_services
https://github.com/user-attachments/assets/225165d9-fd8b-4558-849a-7b00895ce894
https://github.com/user-attachments/assets/953ed696-f3a1-4556-8756-07bbe555b3ae
Un moyen encore plus facile d'entrer dans le shell root (cela nécessite que com.sprd.engineermode soit ouvert en arrière-plan)
https://github.com/user-attachments/assets/d3eb19db-befa-4136-9bd4-b6bdf9bb8bc7
Merci de ne pas republier ceci ailleurs si possible.
L'icône de l'application a été prise ici : icon-link, et voici la licence : license-link