Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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
GhostLock-GOT-W29 — Recherche sur CVE-2026-43499 (GhostLock) concernant HUAWEI MatePad Pro 11 GOT-W29 | Kitploit
Outils/GitHubGitHub/zzzxxxxxxxxxx/ghostlock-got-w29
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationRétro-ingénierieSécurité MobileExploitation de Binaires
GitHubzzzxxxxxxxxxx/ghostlock-got-w29

GhostLock-GOT-W29

Recherche sur CVE-2026-43499 (GhostLock) concernant HUAWEI MatePad Pro 11 GOT-W29

Voir le dépôt
41il y a 11 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

CVE-2026-43499 (GhostLock) — HUAWEI MatePad Pro 11 GOT-W29

Recherche d'élévation de privilèges pour CVE-2026-43499 (rtmutex/futex-PI UAF, « GhostLock ») sur GOT-W29 (HarmonyOS 4.0, kernel 4.19.157-perf+).

Conclusion principale :

  • La primitive d'écriture de la vulnérabilité a été validée avec succès sur le matériel réel (réécriture du sysctl_bootid du kernel avec l'aide de KPM, dérivation du slide KASLR).
  • Mais l'élévation de privilèges réelle (shell sans KPM ni RT) n'est pas réalisable : sur le kernel 4.19, le chemin de retour de pselect écrase de manière déterministe le mot lock de l'overlay, et il n'existe aucun vecteur alternatif. C'est une impasse dictée par la géométrie de la pile du kernel, et non un défaut d'implémentation (en comparaison, les appareils smt878u/popsicle peuvent être entièrement compromis, car leur géométrie de pile est différente).

Appareil

ÉlémentValeur
ModèleHUAWEI MatePad Pro 11 GOT-W29
SoCQualcomm kona (SM8250, Snapdragon 870)
SystèmeHarmonyOS 4.0 (104.0.0.136)
Kernel4.19.157-perf+
VA39-bit, pages 4K, KASLR activé

Vulnérabilité

remove_waiter() dans kernel/locking/rtmutex.c utilise current au lieu de waiter->task lors du nettoyage dans le chemin de rollback de rt_mutex_start_proxy_lock(), ce qui laisse un pi_blocked_on pendant (UAF de pile). Impacte 2.6.39 ~ 7.1 (ce kernel est dans la plage). Correctif en amont : commit 3bfdc63936dd.

Confirmé sur cet appareil : source rtmutex.c:1110-1112, désassemblage de boot.elf, et déclenchement sur le matériel réel, tous vérifiés.

Déclenchement

Mécanisme de déclenchement de la vulnérabilité

Créer un cycle PI pour que FUTEX_CMP_REQUEUE_PI retourne -EDEADLK ; le rollback déclenche le bug de remove_waiter, laissant un pi_blocked_on pendant (pointant vers le rt_waiter sur la pile du kernel du thread waiter).

Pourquoi l'ancien déclenchement échouait

L'ancien déclenchement faisait que le waiter possédait lui-même le futex cible du requeue (self-own), ce qui déclenchait précisément la vérification anticipée owner==task de task_blocks_on_rt_mutex de ce kernel (boot.elf 0x3808-0x3868), retournant avant l'écriture de pi_blocked_on → aucun pointeur pendant n'est jamais créé → le placement de l'overlay était un diagnostic erroné (pas de crash + boot_id inchangé).

Déclenchement correct (cycle PI, implémenté)

Cycle PI : l'owner FUTEX_LOCK_PI(target) détient la cible du requeue ; le waiter détient le futex de chaîne ; l'owner se bloque ensuite sur la chaîne (cycle : waiter→target→owner→chain→waiter). Lors du requeue, la traversée de chaîne détecte rt_mutex_owner(chain)==top_task → -EDEADLK → le rollback nettoie le pi_blocked_on de la mauvaise personne → le pi_blocked_on du waiter est pendant. L'owner doit réduire sa priorité (nice=10) pour que la prio après boost diffère de owner_waiter->prio, sinon rt_mutex_waiter_equal sort prématurément.

Résultats

Fuite KASLR (perf_event_open)

Sous shell (uid 2000) avec perf_event_paranoid=-1, perf_event_open(PERF_SAMPLE_IP, exclude_user=1) échantillonne des clusters d'adresses du texte du kernel ; l'alignement sur les offsets de symboles connus donne le slide.

root@kitploit:~
samples=27651 kernel_ips=1685 lo=0xffffff948728176c hi=0xffffff9488ebfc7c
KASLR slide=0x147f200000    (40/40 IP mappées dans la zone texte du kernel, vérifié)
runtime _stext=0xffffff9487280800

Outil : tools/perf_kaslr.c. Prérequis d'exécution : shell (Shizuku rish), pas d'interception seccomp.

Déclenchement EDEADLK

root@kitploit:~
[M] CMP_REQUEUE_PI ret=-1 errno=35 (EDEADLK!)
[W] WAIT_REQUEUE_PI ret=-1 errno=110 (ETIMEDOUT)  ← retour du waiter
[M] waiter_returned=1                              ← laisse un pi_blocked_on pendant

Outil : tools/edeadlk_probe.c (variante 8+2+1 = 11, ou 27).

Mécanisme de la primitive d'écriture

rt_mutex_adjust_prio_chain step[7] effectue un rb_erase sur le fake waiter (chemin enfant gauche unique) : *(tree_left) = tree_pc + écriture incrémentale __rb_change_child. Tous les offsets dans target.h sont mesurés par désassemblage de boot.elf.

Offsets complets

Voir exploit/ghostlock-source/src/target.h. Points clés :

  • task_struct: cred=0x988, prio=0x184, pi_blocked_on=0xa90, usage=0x68, mm=0x728
  • rt_mutex_waiter (HW_FUTEX_PI): tree@0x0, pi_tree@0x18, task@0x30, lock@0x38, major@0x40, prio@0x48, deadline@0x50
  • PAGE_OFFSET=0xffffffc000000000, PHYS_OFFSET=0x80000000 (kona), KIMAGE_TEXT_BASE=0xffffff8008080000

Validation de la primitive d'écriture sur matériel réel

Un KPM auto-écrit (tools/kpm-debug/rtmutex-dbg.c, KernelPatch 0.13.5 inline-hook) reconstruit l'overlay (tree/task/lock) lors du fake walk et réécrit le paramètre next_lock en empty_zero_page (KernelPatch _transit8 appelle la fonction d'origine avec les fargs modifiés), ce qui fait passer [3] next_lock==waiter->lock de rt_mutex_adjust_prio_chain, réussir le trylock zéro-verrou de [5], [6] sans owner, et exécuter [7] rt_mutex_dequeue (rb_erase enfant gauche unique) — sysctl_bootid est réécrit en &loggers[0][1], slide-kaslr-ok.

root@kitploit:~
REPAIR3 waiter=0xffffff801ecdbc00 lock=0xffffffa7c4950000
slide boot_id_leaked_nfulnl_logger value=ffffffa7c4612320
slide-kaslr-ok base=ffffffa7c1280000 slide=00000027b9200000

Conception de l'overlay

La géométrie de la pile est confirmée par les tailles de frames de boot.elf : dans __arm64_sys_futex(0x70) + do_futex(0x60+0x1a0), rt_waiter est à sp+0xc0 → profondeur 0x1b0 ; stack_fds[0] du chemin pselect est à la profondeur 0x210, soit une différence de 0x60 = 12 mots. Ainsi, word_i tombe dans stack_fds[12+i] : les mots 0-2 sont dans la zone d'entrée ex[2..4] (directement contrôlables), les mots 6-7 (task/lock) dans res_in[3..4] (encodés avec in[3..4] + fd prêt pour POLLIN), les mots 3-5/8-10 restent à 0. pselect retourne immédiatement en raison du fd prêt → le waiter tourne en attente active en espace utilisateur (signaux désactivés, zéro syscall) jusqu'à ce que le consumer déclenche la fin.

Pourquoi l'élévation de privilèges réelle n'est pas réalisable

1. Le mot lock du vecteur pselect est écrasé par le chemin de retour

Les mots task/lock de l'overlay tombent dans res_in[3]/[4] (encodés par fd prêts). Mesuré : res_in[4] (lock) est écrasé de manière déterministe sur le chemin de retour de pselect (résidu de frame rt_sigreturn), n'étant jamais égal au fake_lock du payload ; res_in[3] (task) est parfois intact. La contournement en espace utilisateur (opérations FP + sched_yield) ne peut réduire le taux de déclenchement de do_notify_resume qu'à ~21 %, mais l'écrasement du lock est quasi certain.

Deux autres faits connexes :

  • Le chemin sans owner est bloqué par 4.19 : rt_mutex_adjust_pi() a if (!owner) return 0;, donc sans owner dans fake_lock, adjust_prio_chain n'est pas appelé. popsicle (6.12) n'a pas cette vérification. Un payload avec owner a été porté (fake_lock owner=fake_task|1), mais il ne peut pas être déclenché de manière fiable car le mot lock est toujours écrasé.
  • empty_zero_page ne peut pas être une cible d'écriture forcée : l'écrire corrompt la page zéro partagée du système → tempête d'oops après le test.

2. Le vecteur alternatif (ppoll) est impossible au niveau de l'encodage

Après désassemblage de __arm64_sys_ppoll / do_sys_poll de boot.elf, il est confirmé : pollfd est une structure de 16 octets (fd 4B + events 4B + revents 4B + pad 4B), incapable de porter les mots task/lock 64 bits du fake waiter — la valeur fd est limitée (doit être un vrai fd), events ne fait que 4 octets et n'est pas contigu, revents est écrit par le kernel (non contrôlable).

3. Différence avec les autres appareils

smt878u / popsicle peuvent être entièrement compromis : leur géométrie de pile permet aux mots de tomber dans les zones in/out/ex contrôlables par l'utilisateur (3 fd_set de pselect). La position du waiter de GOT-W29 (bits+0x60 → task/lock dans res_in[3]/[4]) n'a pas cette fenêtre. C'est une différence de géométrie de pile du kernel, pas un défaut d'implémentation.

4. Limites du domaine d'application normal

Le domaine app (untrusted_app) n'a pas de canal KASLR existant (perf/kallsyms/pagemap/dmesg tous refusés) ; CMP_REQUEUE_PI retourne 1 (requeue réussi) sans passer par le rollback EDEADLK ; le major_only du cpuset non-root court-circuite durement le step[6] de la traversée de chaîne. La seule entrée pour modifier QOS, /dev/iaware_qos_ctrl, est refusée par SELinux. Par conséquent, les permissions d'une application normale ne peuvent pas déclencher cette CVE.

Chaîne d'outils de débogage

Module KernelPatch auto-écrit (rtmutex-dbg) pour observer le fake waiter et la primitive d'écriture sur le matériel réel, compilé à partir des en-têtes LyraVoid/KernelPatch 0.13.5 (même source que FolkPatch).

Ensemble de hooks

Compilation

root@kitploit:~
cd <KernelPatch>/kpms/rtmutex-dbg
make TARGET_COMPILE=aarch64-linux-android- \
  CC=$PREFIX/bin/aarch64-linux-android-clang \
  LD=$PREFIX/bin/aarch64-linux-android-ld

Produit rtmutex_dbg.kpm. Les flags de compilation doivent inclure -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-unwind-tables (déjà intégrés dans le Makefile) : le PIC par défaut de clang produit des relocalisations GOT, et le .eh_frame par défaut (R_AARCH64_PREL32) n'est pas pris en charge par le chargeur KPM → échec de chargement -1.

Chargement

La superkey de FolkPatch est su (pas le KernelPatch par défaut d'APatch). Utiliser l'outil sc_kpm_load (source sc_kpm_load.c) :

root@kitploit:~
adb shell /data/local/tmp/sc_kpm_load su /sdcard/Download/rtmutex_dbg.kpm  # charger
adb shell /data/local/tmp/sc_kpm_load unload rtmutex-dbg su               # décharger
adb shell /data/local/tmp/sc_kpm_load ctl rtmutex-dbg counts su           # compteurs

Test en une commande

run_rtmdbg_test.sh (côté appareil /data/local/tmp/ghostlock-test/) : exécute GhostLock en identité shell (GOT_SLIDE_NO_RT=1 chemin réel), boucle de sync de 0,5 s pour éviter la perte de logs, dmesg -w écrit sur disque, collecte automatique après 90 s (SIGSTOP pour éviter le soft-lock et le redémarrage). Avant le test :

root@kitploit:~
adb shell 'su -c "sh /sdcard/ghostlock-test/set_debug_no_reboot.sh"'  # éviter le redémarrage

Points d'observation (dmesg [RTMDBG])

  • REPAIR3 : reconstruction de l'overlay et réécriture du paramètre next_lock lors de la validation de la primitive d'écriture
  • FAKEWALK skip : le fake walk écrasé est sauté (pas d'écriture, pas de crash)
  • prio_chain[N] / prio_chain_ret : appels de walk et valeurs de retour (0=terminé ; 4294967261=-EDEADLK)
  • do_select n=320 : res_in[3]/[4] côté kernel
  • futex op=13/14 : CMP_REQUEUE_PI / WAIT_REQUEUE_PI

Les piles complètes des oops/panic de HUAWEI sont enregistrées dans /data/log/bbox/history.log.

Répertoire

root@kitploit:~
tools/      Outils de validation (perf KASLR, sonde EDEADLK, chaîne d'outils KPM)
target/     Tous les offsets mesurés
exploit/    slide.c porté (avec modifications de déclenchement EDEADLK)

Remerciements

  • PoC en amont : x-spy/CVE-2026-43499-popsicle, soralis0912/CVE-2026-43499-aristotle, JoinChang/ghostlock-oneplus, Wtrwx/smt878u-ionstack-poc (GPL-3.0)
  • CVE : NVD, Red Hat RHSB-2026-010
Télécharger l’outil
hookRôle
rt_mutex_adjust_piEnregistre les ajustements PI ; skip lors de l'écrasement de l'overlay (efface pi_blocked_on)
rt_mutex_adjust_prio_chainSkip inconditionnel du fake walk ; dump complet du waiter
__arm64_sys_pselect6 / __arm64_sys_ppollEfface _TIF_WORK_MASK sur le chemin de retour ; observation fd_set
do_selectLecture côté kernel de res_in[3]/[4]
__arm64_sys_futexSuivi de WAIT_REQUEUE_PI / CMP_REQUEUE_PI
rt_mutex_dequeueConfirme l'exécution de la primitive d'écriture du step[7] et la forme de l'arbre