Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2022-42046 — Exploit de preuve de concept pour CVE-2022-42046 démontrant une escalade de privilèges locale via la manipulation directe d'objets noyau des drapeaux Protection et SignatureLevel de l'EPROCESS dans le pilote wfshbr64.sys. | Kitploit
Outils/GitHubGitHub/kkent030315/cve-2022-42046
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationExploitation de Binaires
GitHubkkent030315/cve-2022-42046

CVE-2022-42046

Exploit de preuve de concept pour CVE-2022-42046 démontrant une escalade de privilèges locale via la manipulation directe d'objets noyau des drapeaux Protection et SignatureLevel de l'EPROCESS dans le pilote wfshbr64.sys.

Voir le dépôt
161263il y a 3 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

EvilWfshbr

CVE-2022-42046 Preuve de concept de l'escalade de privilèges locaux via wfshbr64.sys

Les fichiers wfshbr64.sys et wfshbr32.sys, par le biais d'une charge utile spécialement conçue, permettent à un utilisateur arbitraire d'effectuer une opération bitwise avec un offset EPROCESS arbitraire et une valeur de flags pour élever délibérément le processus de jeu à la protection CodeGen Full en manipulant les flags EPROCESS.Protection et EPROCESS.SignatureLevel (une faille de sécurité considérée comme une fonctionnalité).

Le pilote est signé par l'éditeur de compatibilité matérielle de Microsoft et soumis via le programme Microsoft Hardware.

Ce projet a été co-recherché avec @DoranekoSystems

Une version CLI riche en Rust est disponible ici

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

Licence

MIT. Voir LICENSE

Suggestion (Pour les développeurs)

  1. Utilisez ObRegisterCallbacks au lieu d'élever de force la protection du processus en effectuant une manipulation directe des objets du noyau. Un bon exemple se trouve ici.

2. IRP

Ne référencez pas l'IRP après son achèvement. Si vous avez activé le vérificateur de pilotes, vous serez détecté.

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

Au lieu de cela, vous devriez utiliser une variable locale.

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

3. Contexte du processus

Il semble que vous vérifiez un pointeur nul par rapport à la valeur de retour de IoGetCurrentProcess, mais par conception, il ne renvoie jamais de pointeur nul, vous n'avez donc pas à le vérifier.

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

L'astuce

Quelque temps après le rapport, le développeur a mis en œuvre une "vérification supplémentaire" sournoise pour contrer notre premier PoC, plutôt que de renoncer à exploiter les failles de sécurité comme fonctionnalité.

Vérifications ajoutées à :

  • 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

Cette routine est conçue pour être appelée chaque fois que le client demande une modification de l'EPROCESS, et effectue une vérification de l'Offset fourni par le champ ArbitraryEProcessOffset dans ce PoC ― ainsi que des Flags fournis par le champ DesiredFlags dans ce PoC.

La vérification est assez simple : elle compte les bits 1 dans chaque champ de bits des flags fournis, et si le compte est supérieur à huit, elle échoue.

La carte des motifs de flags possibles est simplement de quatre :

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

Cela dit, effectuer les opérations suivantes 4 fois peut garantir qu'au moins une des tentatives devrait réussir :

  • Soustraire le champ ArbitraryEProcessOffset par index : offset - index,
  • Et ajuster les bits dans le champ DesiredFlags par index : flag << (index * 8).

L'offset est décrémenté, de sorte que l'ajustement du champ de bits entraînera un ajustement de l'offset dans les opérateurs bitwise.

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

Nous avons ajouté les fonctions WfsProtectProcessSupreme et WfsUnprotectProcessSupreme qui effectuent la tentative et ont vaincu la nouvelle astuce.

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;
}
Télécharger l’outil