
(CVE-2026-43499)Exploit noyau pour OnePlus 15T avec Bootloader non débloqué.
Exploit noyau ciblant les appareils OnePlus 15T à bootloader verrouillé. Utilise CVE-2026-43499 pour obtenir un accès root sans déverrouiller le bootloader ni modifier boot.img.
Uniquement à des fins de recherche en sécurité autorisée et d'éducation.
Modifié à partir du dépôt GhostLock-for-OnePlus d'origine, adapté à la disposition mémoire physique et au timing CPU de l'OnePlus 15T (PLZ110 / SM8850 / Snapdragon 8 Elite).
| Élément | Détail |
|---|---|
| CVE | CVE-2026-43499 |
| Type | Futex PI (héritage de priorité) Use-After-Free |
| Périmètre | 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 de waiter futex PI, une trame de pile libérée peut être réallouée en tant que structure rt_mutex_waiter. Lors de la traversée de la chaîne PI, le rééquilibrage de l'arbre rb écrit des données contrôlées à des adresses noyau arbitraires.
futex PI UAF (CVE-2026-43499)
├─ Forge rt_mutex_waiter object
├─ Control kernel stack via pselect/select fd_set layout
├─ Trigger rt_mutex PI operation for arbitrary write
├─ Write 1: selinux_state.enforcing = 0
└─ Write 2: cred → init_cred (uid=0, full capabilities)
| Appareil | Nom de code | SoC | Noyau | Firmware | Statut |
|---|---|---|---|---|---|
| OnePlus 15T | PLZ110 | SM8850 (Snapdragon 8 Elite) | 6.12.38-android16-5-g844001fb8721-ab14552068-4k | ColorOS 16.0.9.400 | ✅ Vérifié |
Pour l'Ace 6T et l'OnePlus 15, consultez le dépôt d'origine.
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 | Remarques |
|---|---|
| APK ReSukiSU (recommandé) | Installez ReSukiSU ; l'APK intègre |
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# Default (API 35)
make
# Specify API level
make API=34
# Specify NDK path
NDK=/path/to/android-ndk make
ghostlock — exécutable ELF ARM64 lié statiquement.
# 1. Enable ADB TCP mode
adb tcpip 5555
# 2. Push ADB key (required for bootstrap mode)
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# 3. Push the 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, ce qui permet des exécutions entièrement automatiques lors des redémarrages suivants.
/data/local/tmp/a/e
task_struct enfant/data/local/tmp/a/e --bootstrap
setprop127.0.0.1:5555/data/local/tmp/a/e --write1
Les offsets sont stockés dans la table de consultation src/devices/offsets.h, 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 } /* sentinel */
};
Lorsque les pointeurs noyau sont restreints (kptr_restrict), fuitez l'adresse de base via boot_id écrasé avec une adresse noyau :
Read /proc/sys/kernel/random/boot_id
└─ UUID contains nfulnl_logger address
└─ KASLR slide = leaked_addr - image_offset
└─ kaslr_base
Lorsque le périphérique ashmem est accessible, utilisez les primitives de lecture/écriture configfs pour lire les pointeurs de fonction de la table fops ashmem et calculer l'offset KASLR.
Falsifiez des objets noyau sur des pages d'ordre 3 (32 Ko) :
file_operations — détournement du pointeur fops du miscdevice ashmemrt_mutex_waiter — simulation d'un nœud waiter de la chaîne PItask_struct — référence de tâche lors de la traversée PIrt_mutex (verrou) — informations waiter/propriétaire correctesImplémenté via SKB (socket buffer) + KernelSnitch :
mm_structsendmsg pour remplir le tas noyauAprès avoir obtenu la base KASLR, utilisez les tampons de pipe pour un accès mémoire au niveau physique :
1. Locate pipe buffer in physmap
2. Forge pipe_buffer ops table pointing to known pipe_buf_ops
3. Hijack pipe_buffer.page to target physical address
4. Arbitrary physical read/write via normal pipe operations
Pris en charge : pipe_read64, pipe_write64, pipe_phys_read_data, pipe_phys_write_data
Target: selinux_state.enforcing (offset 0x00)
Method: child-node PI write → forge waiter __rb_parent_color
pointing to selinux_enforcing - 8
rb-tree rebalance writes 0x00
Target: child process cred pointer
Method: 1. fork child → perf_find_task() locate task_struct
2. calculate cred field offset
3. child-node PI write → cred = init_cred (uid=0, full caps)
4. clear seccomp (TIF_SECCOMP + seccomp struct zeroed)
Une vérification de relecture des capabilities est effectuée après l'écrasement de cred.
src/core/miniadb.c — client léger du protocole ADB pour le mode bootstrap :
1. TCP connect 127.0.0.1:5555
2. A_CNXN → connection request
3. A_AUTH → RSA token challenge
4. dlopen("libcrypto.so") → PEM_read_bio_RSAPrivateKey → RSA_sign
5. A_AUTH (AUTH_SIGNATURE) → signed response
6. A_CNXN → connection established
7. A_OPEN "shell:/data/local/tmp/a/e" → full exploit
Prend en charge les algorithmes de signature SHA-1 et SHA-256.
ghostlock-oneplus/
├── Makefile # Build configuration (NDK cross-compile)
├── README.md # Documentation
├── src/
│ ├── core/ # Core exploit code
│ │ ├── main.c # Entry point: two-stage write + root shell
│ │ ├── fops.c # FOPS/CFI mode: pselect route, PI write, KASLR leak
│ │ ├── util.c # Utilities: heap spray, KASLR, kernel R/W primitives
│ │ ├── slide.c # SLIDE mode: boot_id KASLR leak + pselect route
│ │ ├── pipe.c # Pipe buffer physical memory R/W (physrw)
│ │ ├── root.c # Cred overwrite, seccomp clear, root child mgmt
│ │ ├── miniadb.c # Built-in ADB client (TCP + RSA auth)
│ │ ├── common.h # Global macros, structs, declarations, constants
│ │ ├── target.h # Target memory layout / struct offsets / KASLR params
│ │ ├── offset.h # Compile-time target config bridge (#include TARGET_CONFIG_H)
│ │ └── kernelsnitch/ # KernelSnitch — mm_struct address leak
│ │ ├── kernelsnitch.h # Core algorithm: futex hash collision + brute-force
│ │ ├── futex_hash.h # Futex hash function
│ │ ├── timeutils.h # CPU timestamp measurement (RDTSC)
│ │ └── utils.h # Helper macros (pr_info / SYSCHK / ASSERT etc.)
│ └── devices/ # Device offset tables
│ ├── offsets.h # Aggregate all device offsets (lookup table + sentinel)
│ ├── ace6t/offsets.h # OnePlus Ace 6T offsets (2 kernel versions)
│ └── op15/offsets.h # OnePlus 15 offsets (1 kernel version)
└── tools/ # Offset extraction toolchain
├── extract_target.py # Extract kallsyms global symbol offsets (28 items)
└── extract_btf.py # Extract BTF struct field offsets (57 items)
Ce dépôt a été modifié ; consultez le dépôt d'origine pour plus de détails.
Assurez-vous d'exécuter dans un shell ADB. Le contexte applicatif nécessite --bootstrap.
Votre version du noyau n'est pas encore prise en charge. Suivez Ajout de nouveaux appareils pour extraire les offsets et recompiler.
CORE)PSELECT_ENTER_DELAY_USECperf_event_open (utilisez --bootstrap en contexte applicatif)kaslr_base valide)ksud existe et est exécutableload_policy)Uniquement à des fins de recherche en sécurité autorisée et d'éducation.
libksud.so| Version CI | Téléchargez depuis les versions ReSukiSU CI (ksud-aarch64-linux-android.zip) |
| Type | Nombre | Extraction |
|---|
| Symboles globaux kallsyms | 28 | tools/extract_target.py |
| Champs de structures BTF | 57 | tools/extract_btf.py |
| Valeurs dérivées | 9 | Calculées automatiquement |
| Constantes fixes | 12 | Codées en dur |
| Structure | Champs | Rôle |
|---|
task_struct | 17 | Descripteur de processus, cred, seccomp |
rt_mutex_waiter | 6 | Cible de falsification UAF |
cred | 4 | Identifiants, capabilities |
seccomp | 3 | État du filtre seccomp |
pipe_inode_info | 11 | Opérations sur les tampons de pipe |
file_operations | 13 | Table fops factice |
mm_struct | 1 | Propriétaire du descripteur mémoire |
| Module | Fichier(s) | Responsabilité |
|---|
| Entrée | main.c | Analyse de la CLI, répartition W1/W2, flux bootstrap |
| Route PI | fops.c / slide.c | Disposition de la pile pselect/select, manipulation de la chaîne futex PI |
| KASLR | util.c / fops.c / slide.c | Contournement double mode : fuite de boot_id + fuite de la table fops |
| Heap Spray | util.c | Allocation de pages d'ordre 3, spray SKB, disposition des objets falsifiés |
| Phys R/W | pipe.c | Détournement de tampons de pipe, accès mémoire physique arbitraire |
| Priv Esc | root.c | Écrasement de cred, vérification des capabilities, effacement de seccomp |
| ADB | miniadb.c | Client léger du protocole ADB, authentification RSA |
| Moteur de fuite | kernelsnitch/ | Collision de hachage futex pour la localisation de mm_struct |