Skip to content
KitploitKITPLOIT
HerramientasBlog
Log in
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-43499-pmg110-root — Exploit de escalada local de privilegios (LPE) para Android de CVE-2026-43499 dirigido al OPPO PMG110 (kernel 6.6). Utiliza UAF de futex PI para obtener root e instalar un daemon su mediante LD_PRELOAD. | Kitploit
Herramientas/GitHubGitHub/soralis0912/cve-2026-43499-pmg110-root
Seguridad AndroidEscalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPost-ExplotaciónPruebas de PenetraciónSeguridad MóvilRed TeamingDesarrollo de Payloads

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Explotación de Binarios
GitHubsoralis0912/cve-2026-43499-pmg110-root

CVE-2026-43499-pmg110-root

Exploit de escalada local de privilegios (LPE) para Android de CVE-2026-43499 dirigido al OPPO PMG110 (kernel 6.6). Utiliza UAF de futex PI para obtener root e instalar un daemon su mediante LD_PRELOAD.

Ver Repositorio
231hace 2 mesesAún no revisado

pmg110-root

CVE-2026-43499 (use-after-free de rt_mutex_waiter en futex PI), escalada de privilegios local, portada al OPPO PMG110 / K15 Pro+ — MediaTek MT6991, ColorOS 16.

Un solo archivo enviado, ejecutado mediante LD_PRELOAD:

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

En caso de éxito, queda un su persistente:

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

Verificado en el dispositivo (2026-07-27): uid=0 en unos 35 segundos desde una ejecución simple sin anular variables de entorno, y su respondiendo después desde una adb shell normal y sin privilegios:

$ 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

El exploit y la instalación de su están verificados en este dispositivo. Lo que esa shell con root leyó después también confirma P0_KERNEL_PHYS_LOAD, los offsets de símbolos y KS_MTE_TAGGED=0 independientemente del exploit — ver targets/pmg110-16.0.9.400/NOTES.md.

DispositivoOPPO PMG110 / K15 Pro+ / OP61E5L1
SoCMediaTek MT6991 (Dimensity 9500s)
Kernel6.6.118-android15-8-g93e223c276e7-abogki500782043-4k (GKI, páginas de 4K)
CompilaciónColorOS 16 / PMG110_16.0.9.400(CN01) — mismos bytes de kernel que 16.0.8.300
BugCVE-2026-43499, sin corregir en esta imagen (demostrado por desensamblado, no por versión)

Qué hace y qué no hace

Ejecuta Write 1 (SELinux permisivo) y Write 2 (cred → init_cred), consigue que un proceso hijo tenga uid=0 y desde ahí instala el demonio su integrado.

  • sigue siendo un solo archivo enviado. su no es un segundo artefacto: su_daemon.c se compila como un PIE aarch64 independiente y se incrusta con .incbin en el .rodata de la librería, de modo que viaja dentro de preload.so y se vuelve a escribir en tiempo de ejecución. La vía de warhol-root, sin cambios.
  • sin script de root, sin ksud, sin KernelSU
  • el proceso que llama sigue sin privilegios — obtiene root preguntándole al demonio, que es lo mismo que harás después desde la shell
  • SELinux queda en modo permisivo, igual que lo deja warhol-root: el demonio tiene que atender a clientes sin privilegios a través de su socket. Reinicia para restaurar el modo enforcing.

su se instala en tres lugares, porque uno de ellos es al que llegarás realmente:

RutaPor qué
/apex/com.android.virt/bin/suen un tmpfs montado sobre ese directorio; en el PATH de una shell con root
/data/local/tmp/suaccesible desde un adb shell normal sin juegos de PATH
/apex/com.android.virt/bin/su en el mount namespace de adbdinstalado mediante setns, de modo que una nueva adb shell lo ve

El demonio escucha en /data/local/tmp/temp_su.sock y registra en /data/local/tmp/su_daemon.log. El root no persiste entre reinicios: vuelve a ejecutar la línea de LD_PRELOAD después de cada arranque.

Para instalar KernelSU, usa en su lugar la vía /data/local/tmp/a/e de ghostlock-oneplus.

Relación con warhol-root

Todo excepto el núcleo del exploit es de warhol-root, tomado en lugar de reinventado:

  • la estructura — cabeceras por dispositivo en targets/<device>/, preparadas en source/src/ en tiempo de compilación, de modo que cambiar DEVICE nunca pueda dejar atrás las cabeceras del dispositivo anterior
  • la compilación — la selección de cadena de herramientas de source/Makefile (NDK si lo hay, clang del host contra el sysroot del NDK si no) y la regla de incrustación en dos etapas que produce build/embed/su_daemon_aarch64_pie antes de enlazar el .so
  • la vía de su — su_daemon.c y su_blob.S son byte-idénticos a los de warhol-root, y su_install.c es su instalador preload.c

El núcleo del exploit no es de warhol-root. warhol-root es popsicle, que está fijado a GKI 6.12 / android16 y cuyo generate_target.py rechaza cualquier otro banner. El PMG110 es 6.6 / android15, así que el núcleo aquí es el árbol 6.6 de ghostlock — descendiente a su vez del mismo código (kernelsnitch/utils.h y timeutils.h son byte-idénticos entre los dos repos), desarrollado más a fondo.

ArchivoRelación
util.c slide.c fops.c pipe.c root.c miniadb.c common.h offset.h kernelsnitch/*de ghostlock, byte-idénticos
su_daemon.c su_blob.Sde warhol-root, byte-idénticos (su_blob.S añade dos líneas .hidden — ver Compilación)
su_install.cel instalador preload.c de warhol-root, movido a su propio archivo porque el preload.c de este árbol ya tiene otra función
main.cde ghostlock, más la llamada a su en el hijo con root y el informe de resultados
preload.csolo aquí — el constructor y el registro de doble destino
offsets.hsolo la definición de la struct; la entrada se prepara desde targets/<device>/device_offsets.h

Cada línea del exploit en sí — Write 1, Write 2, KernelSnitch, la vía pselect — es el mismo código en ambos árboles.

Desde dónde se llama a la instalación de su

Esta es la única diferencia estructural, y viene impuesta porque los dos árboles obtienen root de formas distintas.

warhol-root obtiene root en el propio proceso del exploit y por eso llama a install_embedded_su() directamente desde run_direct_root(). Aquí Write 2 intercambia el puntero cred de un hijo bifurcado y el padre sigue siendo el llamador sin privilegios, así que el hijo en child_main() es el único contexto que puede hacer la instalación — ahí es donde se ejecuta.

Ambos árboles llevan el mismo stub débil install_embedded_su() en util.c que devuelve ENOSYS; proporcionar la definición fuerte es lo que activa la vía. Conviene saberlo porque una compilación que por lo que sea deje fuera su_install.c igualmente enlaza y se ejecuta — solo informa de su=0/38 y no instala nada.

Compilación

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

La cadena de herramientas se encuentra sola: primero ANDROID_NDK_HOME / ANDROID_NDK_ROOT, luego las ubicaciones habituales de instalación del NDK para Linux y macOS y, si todas fallan, clang del host apuntando al sysroot del NDK. Define ANDROID_NDK_HOME solo para anular la búsqueda. make info imprime lo que eligió.

La compilación es de dos etapas, que es la parte que conviene saber:

  1. su_daemon.c → build/embed/su_daemon_aarch64_pie, un PIE aarch64 independiente
  2. su_blob.S incrusta ese binario con .incbin en .rodata, y todo el conjunto se enlaza en el único preload.so

Así que make clean y una recompilación son la única forma de cambiar el su integrado — basta con editar su_daemon.c, la dependencia está declarada, pero el blob es un artefacto de compilación y no está bajo seguimiento.

targets/<device>/{target.h,device_offsets.h} se vuelven a preparar en source/src/ en cada compilación, de modo que una cabecera obsoleta de otro dispositivo no puede recogerse silenciosamente.

out/*.so no está bajo seguimiento (misma convención que warhol-root) — clona y ejecuta make.

Descargar herramienta