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.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-42046 — Exploit de prueba de concepto para CVE-2022-42046 que demuestra la escalada de privilegios local mediante la manipulación directa de objetos del kernel de los indicadores EPROCESS Protection y SignatureLevel en el controlador wfshbr64.sys. | Kitploit
Herramientas/GitHubGitHub/kkent030315/cve-2022-42046
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónExplotación de Binarios
GitHubkkent030315/cve-2022-42046

CVE-2022-42046

Exploit de prueba de concepto para CVE-2022-42046 que demuestra la escalada de privilegios local mediante la manipulación directa de objetos del kernel de los indicadores EPROCESS Protection y SignatureLevel en el controlador wfshbr64.sys.

Ver Repositorio

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
161263hace 3 añosRevisado por Kitploit

EvilWfshbr

CVE-2022-42046 Prueba de concepto de escalada de privilegios local de wfshbr64.sys

wfshbr64.sys y wfshbr32.sys permiten que un usuario arbitrario realice operaciones bit a bit con un desplazamiento EPROCESS arbitrario y un valor de banderas para elevar intencionadamente el proceso del juego a la protección completa de CodeGen manipulando las banderas EPROCESS.Protection y EPROCESS.SignatureLevel (agujero de seguridad como característica).

El controlador está firmado por el editor de compatibilidad de hardware de Microsoft que se envía a través del Programa de Hardware de Microsoft.

Este proyecto fue co-investigado con @DoranekoSystems

Hay una versión CLI en Rust disponible aquí

  • https://www.virustotal.com/gui/file/b8807e365be2813b7eccd2e4c49afb0d1e131086715638b7a6307cd7d7e9556c
  • https://www.virustotal.com/gui/file/89698cad598a56f9e45efffd15d1841e494a2409cc12279150a03842cd6bb7f3

Licencia

MIT. Ver LICENCIA

Sugerencia (Para Desarrolladores)

  1. Usa ObRegisterCallbacks en lugar de elevar forzosamente la protección del proceso mediante manipulación directa de objetos del núcleo. Hay un buen ejemplo aquí.

2. IRP

No hagas referencia a IRP después de su finalización. Si tienes el verificador de controladores habilitado, serás atrapado.

IofCompleteRequest(Irp, IO_NO_INCREMENT); // IRP is freed here
return Irp->IoStatus.Status;

En su lugar, debes usar una variable local.

NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
IofCompleteRequest(Irp, IO_NO_INCREMENT); // IRP is freed here
return status;

3. Proceso de Contexto

Parece que estás verificando un puntero nulo contra el valor de retorno de IoGetCurrentProcess, pero nunca devuelve un puntero nulo por diseño, por lo que no es necesario verificarlo.

PEPROCESS CurrentProcess = IoGetCurrentProcess();
  if ( !CurrentProcess ) // no need to check for null pointer
    break;

El Truco

Un tiempo después del informe, el desarrollador implementó una "verificación adicional" sigilosa para derrotar nuestra primera PoC en lugar de renunciar a hacer agujeros de seguridad como característica.

Verificaciones añadidas a:

  • IOCTL_WFSHBR_REMOVE_FLAG
  • IOCTL_WFSHBR_ADD_FLAG
  • IOCTL_WFSHBR_AND_FLAG
case IOCTL_WFSHBR_ADD_FLAG: // 0xAA013884
      if ( !KwfsVerifyCaller(Buffer) ) // verify caller
        break;
-     if ( Buffer->ArbitraryEProcessOffset >= 0x1000 ) // offset limitation check
+     if ( !KwfsVerifyOffsetAndFlags(Buffer->ArbitraryEProcessOffset,
+                                    Buffer->DesiredFlags) ) // verify the offset and flags
        break;
      *(ULONG*)(IoGetCurrentProcess() + Buffer->ArbitraryEProcessOffset) |= Buffer->DesiredFlags;

KwfsVerifyOffsetAndFlags

Esta rutina está diseñada para ser llamada cada vez que el cliente solicita la modificación de EPROCESS, y realiza la verificación del Offset proporcionado por el campo ArbitraryEProcessOffset en esta PoC ― y también de las Flags proporcionadas por el campo DesiredFlags en esta PoC.

La verificación es bastante simple: cuenta los bits 1 en cada campo de bits de las banderas proporcionadas y si el recuento es mayor a ocho, fallará.

El mapa de patrones de banderas posibles es solo cuatro:

  • 22 00 00 00
  • 00 22 00 00
  • 00 00 22 00
  • 00 00 00 22

Dicho esto, realizar las siguientes operaciones 4 veces puede garantizar que al menos uno de los intentos sea exitoso:

  • Resta el campo ArbitraryEProcessOffset por índice: offset - index,
  • Y ajusta los bits en el campo DesiredFlags por índice: flag << (index * 8).

El desplazamiento se decrementa, por lo que el ajuste de bits causaría que el desplazamiento se ajuste en los operadores bit a bit.

*(ULONG*)(IoGetCurrentProcess() + offset) |= flags;
*(ULONG*)(IoGetCurrentProcess() + offset) &= ~flags;

Hemos añadido las funciones WfsProtectProcessSupreme y WfsUnprotectProcessSupreme que realizan el intento y derrotan el nuevo truco.

enum KwfsState {
  KwfsStateOnceCall = 0,
  KwfsStateNeedsValueEquality = 1,
  KwfsStateValueHasBeenSet = 2,
};

bool KwfsVerifyOffsetAndFlags(_In_ ULONG offset, _In_ ULONG offset flags)
{
  if (KwfsState::KwfsState == KwfsState::KwfsStateOnceCall) {
    g_KwfsVerifyState = KwfsState::KwfsStateValueHasBeenSet;
    g_KwfsVerifyStateOffset = offset;
    g_KwfsVerifyStateFlags = flags;
    if (offset < 0x1000) { // offset limitation check moved here
      auto bitcount = 0;
      for (auto i = 0; i < 32; ++i) { // count `1` bits in flags
        if (flags & (1 << i)) {
          ++bitcount;
        }
      }
      if (bitcount <= 8) { // count must less than nine
        g_KwfsVerifyState = 1;
        return true;
      }
    }
  }
  else
  {
    if (g_KwfsVerifyState != KwfsState::KwfsStateValueHasBeenSet
     || offset != g_KwfsVerifyStateOffset
     || flags != g_KwfsVerifyStateFlags) {
      return false;
    }
  }
  return false;
}
Descargar herramienta