Cómo eludir el sistema antitrampas XignCode3 (CVE-2026-3609)
Introducción
XignCode3 es un sistema antitrampas de nivel de kernel desarrollado por la empresa surcoreana Wellbia. Es utilizado por numerosos juegos online, como Trove, CrossFire PH, MapleStory y muchos otros. Su componente principal es un driver de kernel llamado xhunter1.sys (en versiones recientes, xhunter2.sys), que se comunica con el juego para proteger su proceso y bloquear herramientas externas como ReadProcessMemory o OpenProcess.
El problema es que, si intentas abrir el proceso del juego con OpenProcess, el driver de XignCode3 intercepta la llamada y la deniega. Esto hace que los cheats externos tradicionales fallen sin siquiera poder leer la memoria del juego.
Sin embargo, existe una vulnerabilidad crítica en las versiones antiguas del driver que permite a cualquier proceso de usuario obtener un handle con PROCESS_ALL_ACCESS sobre cualquier otro proceso, incluidos los protegidos por PPL (como lsass.exe). Esta vulnerabilidad está catalogada como CVE-2026-3609 y afecta a las versiones de xhunter1.sys desde la 10.0.10011.16384 hasta la 2023.12.7.78.
¿Cómo funciona la vulnerabilidad?
El driver xhunter1.sys expone una interfaz de comandos a través de IRP_MJ_WRITE. Cualquier proceso puede abrir el dispositivo \\.\xhunter1 y enviar comandos. El driver no verifica adecuadamente quién envía estos comandos, lo que permite explotar la vulnerabilidad.
La explotación se realiza en tres pasos:
Auto-autorización (Comandos 777 y 775):
Se envía el comando 777 para registrar el PID del proceso llamante y establecer el bit 31 de una tabla de flags interna del driver.
Se envía el comando 775 con el PID propio para establecer el bit 3 (0x8) de esa misma tabla. Esto marca al proceso como "confiable" ante el driver.
Solicitud del handle (Comando 785):
Una vez que el driver considera que el proceso es confiable, se envía el comando 785 con el PID del proceso objetivo (por ejemplo, Trove_x64.exe) y la máscara de acceso 0x1FFFFF (PROCESS_ALL_ACCESS).
El driver, al recibir este comando, llama internamente a ObOpenObjectByPointer con AccessMode = KernelMode, lo que omite todas las comprobaciones de seguridad y crea un handle con todos los permisos que se deposita directamente en la tabla de handles del proceso llamante.
Uso del handle:
El handle obtenido se puede utilizar con ReadProcessMemory y WriteProcessMemory sin que XignCode3 bloquee las operaciones, porque el handle ya ha sido "bendecido" por el propio driver.