
Exploit racine par démarrage CVE-2026-43499 — logique centrale (arm64 Android GKI 6.6)
Le code du cœur logique de l'exploit d'écriture arbitraire en noyau pour CVE-2026-43499 (Futex PI UAF), utilisé pour contourner SELinux et obtenir root.
Ce dépôt ne contient que le code source du cœur de l'exploit (
src/) et le packager monobinaire (wrapper/).src/target.hest un modèle : vous devez y renseigner les paramètres de votre propre appareil pour qu'il fonctionne (voir « Adaptation à l'appareil » ci-dessous).
# Prérequis : Android NDK r29+ (API 35, aarch64)
export ANDROID_NDK_ROOT=/path/to/android-ndk
# Compilation des artefacts logiques purs
make
# → build/unplus (binaire de l'exploit)
# → build/unplus_preload.so (bibliothèque preload)
Les artefacts sont deux ELF, sans intégration de binaire externe.
Pour empaqueter l'exploit avec les charges utiles externes (magiskpolicy / ksud / kernelsu.ko) en un seul binaire exécutable en une commande, vous devez fournir ces charges utiles, puis les empaqueter avec wrapper/ :
# 1. Compiler d'abord les artefacts de src/ (voir ci-dessus)
# 2. Générer les données de payload (payload_data.h n'est pas dans le dépôt, il est généré par l'utilisateur et contient le flux d'octets des binaires externes)
cd wrapper
python3 embed_payloads.py \
--unplus ../build/unplus \
--preload ../build/unplus_preload.so \
--magiskpolicy <path> \
--ksud <path> \
--kernelsu <path> \
--out payload/
# 3. Compiler le binaire unique
make # → wrapper/build/unplus
src/
├── target.h Modèle de paramètres de l'appareil (◆ les endroits marqués FILL IN doivent être remplis avec les valeurs de votre appareil)
├── offset.h Colle de routage pour target.h (injecté via -DTARGET_CONFIG_H)
├── unplus.h En-tête d'orchestration + déclarations partagées (y compris les macros dérivées P0 alias / data_addr, etc.)
├── main.c Orchestration d'entrée
├── stage1.c Écriture 1/2 : désactivation de SELinux + réécriture de cred
├── root.c Mise en place de root Android (correction golden SELinux + sepolicy + allowlist KSU)
├── slide.c Fuite KASLR
├── fops.c Routage configfs/fops + dérivation de l'adresse de base du noyau
├── route.c Thread de routage PI futex
├── direct_write.c Primitives de lecture directe
├── pipe_direct.c Écriture directe pselect
├── pipe_physrw.c Primitives physrw via pipe
├── util.c Fonctions utilitaires
├── utils.h Outils génériques (journalisation, chemins procfs)
├── kernelsnitch.h Couche d'architecture (identity-map ARM64/x86)
├── futex_hash.h Port noyau de jhash (générique)
└── timeutils.h Chronométrage spécifique à l'architecture (ARM/x86/AMD)
src/target.h contient deux catégories de constantes :
◆ FILL IN : liées à l'appareil/noyau, vous devez obligatoirement les renseigner avec vos propres valeurs. Le modèle utilise des placeholders 0xDEADBEEF... qui compilent mais planteront à l'exécution.Changer d'appareil = remplir la partie ◆ FILL IN. La signification de chaque champ et la façon de l'obtenir sont détaillées dans l'annexe : description des champs.
Les champs ◆ FILL IN de target.h sont regroupés par usage :
Retour d'expérience général : tous les offsets *_OFF peuvent être obtenus sur un appareil rooté via kallsyms_lookup_name en retranchant KIMAGE_TEXT_BASE de l'adresse du symbole. TARGET_PCPU_* et TARGET_SELINUX_GOLDEN sont des valeurs runtime/dump, non dérivables depuis une image statique.
WTFPL — Do What The Fuck You Want To Public License.
| Groupe | Champs (exemple) | Signification / méthode d'obtention |
|---|
| Build identity | BUILD_VARIANT_LABEL、BUILD_FINGERPRINT | Chaînes d'identification arbitraires pour les journaux. Renseignez le build fingerprint de votre appareil |
| Memory layout | KIMAGE_TEXT_BASE、P0_PHYS_OFFSET、VMEMMAP_START, etc. | Disposition des adresses virtuelles/physiques du noyau. Des valeurs par défaut sont généralement fournies pour arm64 VA39 ; à confirmer via IKCONFIG / kallsyms / /proc/iomem |
| ASHMEM | ASHMEM_IOCTL_OFF ... ASHMEM_MISC_FOPS_OFF | Offsets des membres fops et du misc du driver ashmem. kallsyms_lookup_name("ashmem_fops"), etc. |
| CONFIGFS / PIPE / VFS | CONFIGFS_READ_ITER_OFF、ANON_PIPE_BUF_OPS_OFF、KMALLOC_CACHES_OFF, etc. | Offsets configfs lecture/écriture, splice, pipe_buf_ops, kmalloc_caches. À chercher via kallsyms |
| SELinux | SELINUX_ENFORCING_OFF、SELINUX_BLOB_SIZES_OFF、SECURITY_HOOK_HEADS_OFF | Offsets de selinux_state / selinux_blob_sizes / security_hook_heads. SELINUX_ENFORCING_OFF est le point d'ancrage de correspondance du build noyau : il doit être exact |
| Core kernel symbols | INIT_TASK_OFF、INIT_CRED_OFF、ENTRY_TASK_PERCPU_OFF, etc. | Offsets init_task / init_cred / entry_task / __per_cpu_offset / root_task_group. À chercher via kallsyms ; ENTRY_TASK_PERCPU_OFF est l'offset de __entry_task dans la section percpu |
| Per-CPU runtime | TARGET_PCPU_BASE_ADDR、TARGET_PCPU_UNIT_SIZE | Adresse runtime du chunk per-CPU (après KASLR), change à chaque démarrage. Nécessite un dump à l'exécution ; UNIT_SIZE dépend du nombre de CPU |
| SLIDE (fuite KASLR) | SLIDE_NFULNL_LOGGER_OFF、SLIDE_RANDOM_BOOT_ID_DATA_OFF, etc. | Offsets des symboles de données noyau utilisés pour la fuite KASLR (nfulnl_logger / boot_id data, etc.). À chercher via kallsyms |
| SELinux golden | TARGET_SELINUX_GOLDEN | Modèle booléen des 16 premiers octets de selinux_state, stable entre redémarrages mais unique à chaque appareil. À extraire du dump de selinux_state de votre appareil. byte0 est le bit enforcing ; l'appelant écrit 0x00 pour permissive |
| pipe inode info | PIPE_INODE_INFO_*、PIPE_HEAD_OFF, etc. | Disposition de la structure pipe_inode_info, généralement stable au sein d'une même famille GKI ; à vérifier si le build noyau change |