Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-43499-pmg110-root — Exploit de LPE para Android CVE-2026-43499 direcionado ao OPPO PMG110 (kernel 6.6). Usa futex PI UAF para obter root e instalar um daemon su via LD_PRELOAD. | Kitploit
Ferramentas/GitHubGitHub/soralis0912/cve-2026-43499-pmg110-root
Segurança AndroidEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoPós-ExploraçãoTestes de PenetraçãoSegurança MóvelRed TeamingDesenvolvimento de Payloads

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Exploração de Binários
GitHubsoralis0912/cve-2026-43499-pmg110-root

CVE-2026-43499-pmg110-root

Exploit de LPE para Android CVE-2026-43499 direcionado ao OPPO PMG110 (kernel 6.6). Usa futex PI UAF para obter root e instalar um daemon su via LD_PRELOAD.

Ver Repositório
213há 1 mêsAinda não revisado

pmg110-root

CVE-2026-43499 (uso após liberação do rt_mutex_waiter do futex PI) escalonamento de privilégios local, portado para o OPPO PMG110 / K15 Pro+ — MediaTek MT6991, ColorOS 16.

Um único arquivo enviado, executado via LD_PRELOAD:

root@kitploit:~
adb push out/preload-pmg110-16.0.9.400.so /data/local/tmp/preload.so
adb shell chmod 644 /data/local/tmp/preload.so
adb shell LD_PRELOAD=/data/local/tmp/preload.so /system/bin/true

Em caso de sucesso, um su persistente fica disponível:

root@kitploit:~
adb shell /data/local/tmp/su -c id      # uid=0(root)

Verificado no dispositivo (2026-07-27): uid=0 em cerca de 35 segundos em execução pura, sem sobrescrever variáveis de ambiente, e su respondendo em seguida a partir de um adb shell comum sem privilégios:

root@kitploit:~
$ adb shell "/data/local/tmp/su -c 'echo 0 > /proc/sys/kernel/kptr_restrict'"
$ adb shell "/data/local/tmp/su -c 'grep -w init_task /proc/kallsyms'"
ffffffe89033e780 D init_task

O exploit e a instalação do su foram ambos verificados neste dispositivo. O que esse shell com root leu em seguida também confirma P0_KERNEL_PHYS_LOAD, os offsets de símbolos e KS_MTE_TAGGED=0 de forma independente do exploit — consulte targets/pmg110-16.0.9.400/NOTES.md.

O que faz e o que não faz

Ele executa a Escrita 1 (SELinux permissivo) e a Escrita 2 (cred → init_cred), leva um processo filho a uid=0 e, a partir daí, instala o daemon su embutido.

  • continua sendo um único arquivo enviado. su não é um segundo artefato: su_daemon.c é compilado como um PIE aarch64 autônomo e embutido via .incbin no .rodata da biblioteca, de modo que viaja dentro de preload.so e é gravado de volta em tempo de execução. É o caminho do warhol-root, inalterado.
  • sem script de root, sem ksud, sem KernelSU
  • o processo chamador permanece sem privilégios — ele obtém root pedindo ao daemon, que é exatamente o que você fará a partir do shell depois
  • o SELinux é deixado permissivo, como o warhol-root deixa: o daemon precisa atender clientes sem privilégios via socket. Reinicie para restaurar o modo enforcing.

O su é instalado em três lugares, porque um deles é o que você realmente alcançará:

O daemon escuta em /data/local/tmp/temp_su.sock e registra logs em /data/local/tmp/su_daemon.log. O root não persiste entre reinicializações — execute novamente a linha com LD_PRELOAD após cada boot.

Para instalação do KernelSU, use o caminho /data/local/tmp/a/e no ghostlock-oneplus.

Relação com o warhol-root

Tudo, exceto o núcleo do exploit, é do warhol-root, aproveitado em vez de reinventado:

  • o layout — cabeçalhos por dispositivo em targets/<device>/, preparados em source/src/ no momento da compilação, de modo que alternar DEVICE nunca deixa para trás os cabeçalhos do dispositivo anterior
  • o build — a seleção de toolchain do source/Makefile (NDK se houver, clang do host contra o sysroot do NDK se não houver) e a regra de incorporação em duas etapas que produz build/embed/su_daemon_aarch64_pie antes de linkar o .so
  • a rota do su — su_daemon.c e su_blob.S são byte-idênticos aos do warhol-root, e su_install.c é o instalador preload.c dele

O núcleo do exploit não é do warhol-root. warhol-root é popsicle, que está fixado no GKI 6.12 / android16 e cujo generate_target.py recusa qualquer outro banner. PMG110 é 6.6 / android15, então o núcleo aqui é a árvore ghostlock 6.6 — ela própria descendente do mesmo código (kernelsnitch/utils.h e timeutils.h são byte-idênticos entre os dois repositórios), com desenvolvimento adicional.

Cada linha do exploit em si — Escrita 1, Escrita 2, KernelSnitch, o caminho pselect — é o mesmo código nas duas árvores.

De onde a instalação do su é chamada

Esta é a única diferença estrutural, e ela é imposta pelo fato de as duas árvores obterem root de formas diferentes.

O warhol-root dá root ao próprio processo do exploit e por isso chama install_embedded_su() direto de run_direct_root(). Aqui, a Escrita 2 troca o ponteiro cred de um filho criado via fork e o pai permanece como o chamador sem privilégios; portanto, o filho em child_main() é o único contexto que pode fazer a instalação — é lá que ela roda.

As duas árvores carregam o mesmo stub fraco install_embedded_su() em util.c, que retorna ENOSYS; fornecer a definição forte é o que ativa o caminho. Isso é útil saber porque um build que, por algum motivo, deixe de incluir su_install.c ainda linka e ainda roda — ele apenas reporta su=0/38 e não instala nada.

Build

root@kitploit:~
make                      # = make preload -> out/preload-<DEVICE>.so
make DEVICE=<name>        # use targets/<name>/
make devices              # list available DEVICE values
make info                 # show the selected target and the resolved toolchain

A toolchain é encontrada sozinha: ANDROID_NDK_HOME / ANDROID_NDK_ROOT primeiro, depois os locais usuais de instalação do NDK para Linux e macOS e, se nenhum deles funcionar, o clang do host apontando para o sysroot do NDK. Defina ANDROID_NDK_HOME apenas para substituir a busca. make info mostra o que foi escolhido.

O build tem duas etapas, e é isso que vale a pena saber:

  1. su_daemon.c → build/embed/su_daemon_aarch64_pie, um PIE aarch64 autônomo
  2. su_blob.S incorpora esse binário via .incbin no .rodata, e tudo é linkado no único preload.so

Portanto, make clean e um rebuild são a única forma de alterar o su embutido — editar apenas su_daemon.c é suficiente, a dependência está declarada, mas o blob é um artefato de build e não é versionado.

targets/<device>/{target.h,device_offsets.h} são preparados novamente em source/src/ a cada build, para que um cabeçalho obsoleto de outro dispositivo não seja usado silenciosamente.

out/*.so não é versionado (mesma convenção do warhol-root) — clone e rode make.

O .so é compilado com -fvisibility=hidden e exporta zero símbolos. Uma biblioteca LD_PRELOAD vence a busca de símbolos para o processo inteiro, então qualquer coisa que ela exportasse poderia sobrescrever um símbolo de mesmo nome no binário hospedeiro ou na libc. Essa flag rege apenas a geração de código C, por isso su_blob.S marca seus dois símbolos como .hidden manualmente — sem essas linhas, os limites do blob seriam a única coisa que a biblioteca ainda exportaria.

Variáveis de ambiente

Nenhuma delas foi necessária na execução verificada.

Lendo o log

root@kitploit:~
[*] futex_hashsize 2048 (8 possible CPUs)
[*] ks collisions=3/3 baseline=8 threshold=10x (80) accepted=[1244..1597] slowest_rejected=N
[+] child uid = 0
[+] embedded su wrote 15304 bytes to /apex/com.android.virt/bin/su
[+] embedded su daemon ready pid=NNNN socket=/data/local/tmp/temp_su.sock daemon=/apex/com.android.virt/bin/su
[+] embedded su install ok=1 errno=0 daemon=NNNN
[+] su ready: /data/local/tmp/su and /apex/com.android.virt/bin/su
[+] ghostlock preload verdict: EXPLOIT OK

child uid = 0 é o exploit tendo sucesso; tudo depois disso é a instalação. Os dois são reportados separadamente de propósito, e o veredito também:

O do meio é a distinção que vale a pena ter: ele diz que os offsets em target.h estão corretos para este build e que o problema está em algum ponto da instalação, o que é algo completamente diferente de depurar. O su=0/38 (ENOSYS) dentro dele significa especificamente que o stub fraco foi o que entrou no link.

mm_struct leak failed seguido por prepare_kernel_page retry N/24 não é uma falha. É o progresso do loop, e a execução bem-sucedida também mostra isso. Nada falhou até as 24 tentativas se esgotarem e prepare_kernel_page timeout aparecer. Da mesma forma, probing cfi ... expected=9 com child uid = 2000 é uma rodada perdida, de dez.

Não julgue uma execução por um log truncado — esse erro custou uma rodada inteira de diagnóstico errado aqui.

Uma execução completamente falha também é normal. A corrida (race) do pselect não é 100%: uma execução pode perdê-la cinco vezes seguidas e terminar em Write 1 failed, e a próxima acerta de primeira com ret=9. Observado neste dispositivo. ret=4 expected=9 é a cara de uma corrida perdida, não de um target.h errado — uma falha não é motivo para sair recalculando offsets. Execute novamente.

Arquivos

Licença

Apenas para pesquisa de segurança autorizada e fins educacionais.

Baixar ferramenta
DispositivoOPPO PMG110 / K15 Pro+ / OP61E5L1
SoCMediaTek MT6991 (Dimensity 9500s)
Kernel6.6.118-android15-8-g93e223c276e7-abogki500782043-4k (GKI, páginas de 4K)
BuildColorOS 16 / PMG110_16.0.9.400(CN01) — mesmos bytes de kernel de 16.0.8.300
BugCVE-2026-43499, não corrigido nesta imagem (comprovado por desmontagem, não pela versão)
CaminhoPorquê
/apex/com.android.virt/bin/suem um tmpfs montado sobre esse diretório; no PATH de um shell root
/data/local/tmp/suacessível a partir de um adb shell simples, sem jogos de PATH
/apex/com.android.virt/bin/su no namespace de mount do adbdinstalado via setns, de modo que um novo adb shell o veja
ArquivoRelação
util.c slide.c fops.c pipe.c root.c miniadb.c common.h offset.h kernelsnitch/*do ghostlock, byte-idênticos
su_daemon.c su_blob.Sdo warhol-root, byte-idênticos (su_blob.S adiciona duas linhas .hidden — veja Build)
su_install.cinstalador preload.c do warhol-root, movido para um arquivo próprio porque o preload.c desta árvore já tem outra função
main.cdo ghostlock, mais a chamada do su no filho com root e o relato do resultado
preload.cexiste apenas aqui — o construtor e o log com dois destinos
offsets.hapenas a definição da struct; a entrada é preparada a partir de targets/<device>/device_offsets.h
VariávelEfeito
GHOSTLOCK_LOGdestino do log (padrão /data/local/tmp/.ghostlock.log); a saída vai para o stdout e para o arquivo
GHOSTLOCK_KS_VERBOSE=1imprime os endereços de colisão e os intervalos de varredura do KernelSnitch
GHOSTLOCK_KS_THRESHOLD=<n>substitui o multiplicador do limite de colisão
GHOSTLOCK_MTE=1varre também as tags de ponteiro do kernel (15x mais lento)
GHOSTLOCK_PHYS_LOAD=0x...substitui o endereço de carga física do kernel
PSELECT_SHIFT=<n>substitui o deslocamento do overlay de pilha (substitui, não soma)
VereditoSignificado
EXPLOIT OKroot, e su responde
EXPLOIT OK, SU INSTALL FAILEDEscrita 1 e Escrita 2 acertaram; apenas a instalação deu errado
EXPLOIT FAILEDas escritas não acertaram
ABORTEDa execução morreu antes de conseguir reportar — leia a última linha [!]
CaminhoConteúdo
source/src/preload.cconstrutor: executa o exploit, reporta, para
source/src/main.co próprio exploit (Escrita 1 / Escrita 2)
source/src/su_daemon.co binário su — compilado de forma autônoma como um PIE aarch64, não linkado no .so
source/src/su_blob.Sincorpora esse PIE via .incbin no .rodata do .so
source/src/su_install.cgrava o blob de volta, inicia o daemon e o testa
source/src/target.hdestino do staging (ignorado pelo git)
targets/<device>/target.hlayout de tempo de compilação: offsets de structs, constantes do physmap, formas do slab e do futex
targets/<device>/device_offsets.hoffsets de símbolos globais do kallsyms
tools/extract_device.pyboot.img → offsets, campos de struct do BTF, resultado do overlay pselect
tools/preloader_memlayout.pypreloader da MediaTek → P0_KERNEL_PHYS_LOAD
tools/qemu_verify.pyinicializa o kernel sob QEMU: mede o overlay de pilha, verifica a estabilidade do mapa linear
tools/device_probe.shverificação preliminar a partir de um adb shell sem privilégios