Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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
win32k-callback-detouring — Abusando del mecanismo de callback del kernel win32k.sys para la ejecución arbitraria de código | Kitploit
Herramientas/GitHubGitHub/n0qword/win32k-callback-detouring
ExplotaciónShellcodePost-ExplotaciónAprendizaje y EducaciónRed TeamingDesarrollo de Payloads
GitHubn0qword/win32k-callback-detouring

win32k-callback-detouring

Abusando del mecanismo de callback del kernel win32k.sys para la ejecución arbitraria de código

Ver RepositorioSitio web
1081219hace 5 mesesRevisado por Kitploit

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

Descargo de responsabilidad

Este repositorio se proporciona estrictamente con fines educativos y de investigación defensiva.

Demuestra los mecanismos internos de despacho de callbacks de Windows y conceptos de flujo de control relacionados con KernelCallbackTable en un contexto de prueba de concepto.

  • No está destinado a uso no autorizado
  • No está diseñado para despliegue operativo
  • Sin consideraciones de sigilo/opsec
  • Úselo únicamente en entornos de laboratorio controlados que le pertenezcan o para los que esté autorizado a realizar pruebas

El autor no asume ninguna responsabilidad por el mal uso.


Desvío de Callbacks de Win32k: Abuso del Despacho Legítimo de Callbacks de Kernel a Usuario para Ejecución de Código

Resumen

Esta técnica de inyección abusa de la ruta de despacho de callbacks de kernel a usuario utilizada por el subsistema gráfico de Windows (win32k.sys) para obtener ejecución de código dentro de un proceso remoto. Al localizar el KernelCallbackTablea través delBloque de Entorno de Proceso (PEB), un operador puede enumerar las entradas de callback e identificar rutinas legítimas de modo usuario invocadas durante transiciones del kernel relacionadas con la GUI.

En lugar de realizar la tradicional inyección de KernelCallbackTable, donde una entrada de callback se sobrescribe directamente con la dirección del shellcode, esta variante intercepta el destino de callback legítimo referenciado por la tabla y redirige la ejecución al shellcode controlado por el atacante al momento de la invocación. Debido a que la ejecución se secuestra a través de una ruta de callback existente y esperada, la técnica puede proporcionar una alternativa más sigilosa que primitivas más convencionales como la creación de hilos remotos o la inyección basada en APC.


Comprendiendo el mecanismo

Flujo de despacho de callbacks de Windows

El subsistema gráfico de Windows delega partes del procesamiento relacionado con la GUI al modo usuario a través de un mecanismo de callback iniciado desde el modo kernel. Cuando win32k.sys necesita ejecutar lógica dentro del contexto de un proceso GUI, invoca KeUserModeCallback para realizar una transición controlada del modo kernel al modo usuario preservando el límite de aislamiento entre ambos contextos de ejecución.

Esta transición establece la ruta de ejecución legítima a través de la cual el kernel despacha callbacks del subsistema gráfico hacia el modo usuario—la misma ruta de la que luego abusa la técnica presentada.


KiUserCallbackDispatcher

Una vez completada la transición, la ejecución entra en KiUserCallbackDispatcher, una rutina de ntdll.dll responsable de recibir el índice de callback suministrado por el kernel y despachar la ejecución al manejador de callback correspondiente en modo usuario. Esta rutina sirve como punto de entrada obligatorio para todos los callbacks iniciados a través de KeUserModeCallback.

Debido a que toda la resolución de callbacks converge en este despachador, KiUserCallbackDispatcher actúa como el pivote central entre las solicitudes de callback del kernel y su eventual ejecución en modo usuario.


Ruta de resolución de KernelCallbackTable

Para resolver el destino de un callback solicitado, KiUserCallbackDispatcher consulta la KernelCallbackTable almacenada en el PEB del proceso objetivo. Cada entrada de la tabla contiene un puntero a una rutina de callback en modo usuario asociada con una operación específica del subsistema gráfico, típicamente implementada en user32.dll.

Las técnicas tradicionales de inyección de KernelCallbackTable sobrescriben directamente una o más de estas entradas para redirigir la ejecución. Si bien son efectivas, modificar la tabla en sí introduce anomalías estructurales que pueden detectarse trivialmente mediante la validación de integridad del PEB o del contenido de la tabla de callbacks. La técnica presentada evita esto preservando la estructura de la tabla y, en su lugar, desviando el destino de callback referenciado por la entrada.


Uso de __fnCOPYDATA como primitiva de ejecución

Entre las entradas disponibles de KernelCallbackTable, __fnCOPYDATA proporciona una primitiva de activación particularmente conveniente porque puede invocarse externamente mediante el envío de un mensaje WM_COPYDATA a través de SendMessage(). Esto permite activar el callback de forma determinista sin requerir un estado inusual del proceso ni una interacción compleja.

Al aprovechar un destino de callback naturalmente accesible y de uso frecuente, la técnica obtiene una primitiva de ejecución fiable mientras permanece completamente dentro de la cadena esperada de despacho de callbacks antes de la redirección.


kcallbackflow


Cómo funciona

La técnica comienza localizando el proceso objetivo y leyendo su PEB para recuperar la dirección de la KernelCallbackTable, desde la cual se resuelve el puntero de callback para __fnCOPYDATA. A continuación, se asigna memoria ejecutable dentro del proceso remoto y se escribe el shellcode controlado por el atacante en la región asignada. Antes de la modificación, los bytes originales de la rutina de callback legítima se conservan para permitir su restauración posterior.

Posteriormente, se instala un hook inline al inicio de la rutina resuelta __fnCOPYDATA, reemplazando su prólogo con un salto absoluto al shellcode inyectado. Para desencadenar la ejecución, se envía un mensaje WM_COPYDATA a la ventana objetivo, lo que hace que el subsistema gráfico de Windows despache __fnCOPYDATA a través de la cadena estándar de callbacks de kernel a usuario. Una vez completada la ejecución, los bytes originales del callback se restauran para preservar la estabilidad del proceso y reducir los artefactos de modificación residuales.


Implementación

Paso 1: Obtener el PEB del proceso remoto y KernelCallbackTable

La KernelCallbackTable se encuentra en el desplazamiento 0x58 dentro del PEB:

dt_peb

La siguiente lógica se utiliza para obtenerla:

PROCESS_BASIC_INFORMATION pbi;
PEB                       peb;
KERNELCALLBACKTABLE       kct;

if (NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL) != STATUS_SUCCESS)
{
    NtClose(hProcess);
    return 1;
}

/* Read remote PEB */
if (NtReadVirtualMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL) != STATUS_SUCCESS)
{
    NtClose(hProcess);
    return 1;
}

/* Ensure KernelCallbackTable is present */
if (!peb.KernelCallbackTable) {
    NtClose(hProcess);
    return 1;
}

/* Read KernelCallbackTable contents */
if (NtReadVirtualMemory(hProcess, peb.KernelCallbackTable, &kct, sizeof(kct), NULL) != STATUS_SUCCESS)
{
    NtClose(hProcess);
    return 1;
}

El código comienza llamando a NtQueryInformationProcess con la clase de información ProcessBasicInformation para rellenar una estructura PROCESS_BASIC_INFORMATION, que expone la dirección del PEB del proceso remoto a través del campo PebBaseAddress.

A continuación, se utiliza NtReadVirtualMemory para leer el PEB remoto en una estructura local PEB, lo que permite extraer el puntero a KernelCallbackTable almacenado dentro del entorno del proceso. Después de validar que la tabla de callbacks está presente, una segunda llamada a NtReadVirtualMemory copia la estructura remota KERNELCALLBACKTABLE en la memoria local, lo que permite la resolución directa de destinos de callback como __fnCOPYDATA para el posterior desvío.

Descargar herramienta