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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-43805-analysis — Analyse en une journée + PoC de désinfection de CVE-2026-43805 (course RPC DriverKit IODMACommand IOKit, CWE-362) | Kitploit
Outils/GitHubGitHub/wtcyj/cve-2026-43805-analysis
Analyse StatiqueCriminalistique MémoireAnalyse des VulnérabilitésExploitationRétro-ingénierieArticles et RechercheApprentissage et Éducation
GitHubwtcyj/cve-2026-43805-analysis

CVE-2026-43805-analysis

Analyse en une journée + PoC de désinfection de CVE-2026-43805 (course RPC DriverKit IODMACommand IOKit, CWE-362)

Voir le dépôt
il y a 1 moisPas encore vérifié

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

CVE-2026-43805 — Course de RPC DriverKit dans le pilote IOKit IODMACommand

Une analyse one-day de la condition de course dans Apple IOKit corrigée dans iOS/iPadOS 26.6, macOS Tahoe 26.6, Sequoia 15.7.8, Sonoma 14.8.8 et watchOS 26.6. Aucun proof-of-concept public n'existait au moment de la rédaction, le travail ici consiste donc à : localiser le code corrigé en lisant les sources primaires de XNU, expliquer la cause racine jusqu'à l'objet libéré, et reproduire le défaut sous forme d'un modèle fidèle vérifié par sanitizer.

L'avis d'Apple est laconique :

Une condition de course a été corrigée par une meilleure gestion de l'état. Une app peut être en mesure de provoquer une terminaison inattendue du système ou d'écrire dans la mémoire du noyau.

Classifié CWE-362 (exécution concurrente avec synchronisation incorrecte), CVSS 9.8. Avis : 128066 · 128067 · 128068 · 128071 · 128072.

Où se trouve le bug

IODMACommand est exposé aux extensions DriverKit (dexts) via RPC. Les implémentations côté noyau de ces points d'entrée RPC sont les méthodes _Impl dans iokit/Kernel/IOUserServer.cpp. Un dext pilote un tampon DMA à travers trois d'entre elles :

Méthode RPCligne (xnu-12377.121.6)détient fInternalState->fDextLock ?
PrepareForDMA_Impl1009oui — IOLockLock @1033, unlock @1078
CompleteDMA_Impl1084oui — IOLockLock @1096, unlock @1118
PerformOperation_Impl1154non — lit fActive et fMemory sans verrou

Le verrou existe. IODMACommand::init l'alloue (iokit/Kernel/IODMACommand.cpp ligne 342). Deux des trois méthodes sœurs l'acquièrent. La troisième ne le fait pas — et c'est elle qui déréférence le descripteur de mémoire partagé. Cette asymétrie constitue la vulnérabilité.

xnu-12377.121.6 (macOS 26.x, le dernier tag pour lequel Apple a publié les sources) montre encore le PerformOperation_Impl sans verrou, c'est donc l'arbre vulnérable ; la publication des sources 26.6 qui contient le correctif n'est pas encore publique. La source pertinente est reproduite dans analysis/IOUserServer_excerpt.cpp.

Cause racine

PerformOperation_Impl effectue une vérification temporelle sur fActive, puis utilise fMemory :

    if (!fActive) {                        // time-of-check  (no lock held)
        return kIOReturnNotReady;
    }
    ...
    if (length > fMemory->getLength()) {   // time-of-use   (fMemory may be gone)
        return kIOReturnBadArgument;
    }
    ...
    copiedDMA = writeBytes(dmaOffset, buffer.data(), length);   // write into the mapping

CompleteDMA_Impl exécute le démontage sous le verrou :

    IOLockLock(fInternalState->fDextLock);
    ...
    ret = clearMemoryDescriptor(true);     // see below
    ...
    IOLockUnlock(fInternalState->fDextLock);

et clearMemoryDescriptor(true) (IODMACommand.cpp ligne 455) est ce qui libère réellement l'objet que PerformOperation est sur le point de toucher :

    if (fMemory) {
        while (fActive) {
            complete();                    // drains fActive to 0
        }
        ...
        fMemory.reset();                   // releases the IOMemoryDescriptor
    }

L'entrelacement dangereux est donc le suivant :

  1. PerformOperation_Impl passe if (!fActive) alors que la commande est encore active.
  2. CompleteDMA_Impl prend le verrou, vide fActive et exécute fMemory.reset(), libérant le descripteur de mémoire et permettant à son support câblé d'être libéré/réutilisé.
  3. PerformOperation_Impl, toujours en cours d'exécution, déréférence le fMemory désormais obsolète dans getLength() puis writeBytes().

Comme PerformOperation n'a jamais pris le verrou, l'étape 2 peut se glisser dans l'intervalle entre les étapes 1 et 3. writeBytes copie les octets fournis par l'appelant dans un mapping DMA dont le support a été libéré — une fois cette page réutilisée pour une autre allocation du noyau, c'est l'« écriture en mémoire du noyau » contre laquelle l'avis met en garde. Si on l'atteint plutôt sur le chemin de lecture, on obtient une lecture use-after-free / un arrêt inattendu.

sequenceDiagram
    participant W as dext thread A — PerformOperation_Impl (no lock)
    participant O as dext thread B — CompleteDMA_Impl (holds fDextLock)
    W->>W: if (!fActive) → active, continue
    Note over W: passed the check, about to use fMemory
    O->>O: IOLockLock(fDextLock)
    O->>O: clearMemoryDescriptor(true): fActive=0, fMemory.reset()  ← FREE
    O->>O: IOLockUnlock(fDextLock)
    W->>W: fMemory->getLength() / writeBytes()  ← USE-AFTER-FREE

Reproduire le problème sans macOS vulnérable

Déclencher le chemin réel nécessite un dext DriverKit signé avec l' entitlement DriverKit d'Apple sur une version vulnérable, ce qui n'est pas accessible depuis un hôte Windows. À la place, poc/race_model.cpp réimplémente la logique exacte d'état partagé des trois méthodes — même discipline de verrouillage, même ordre vérification-puis-libération-puis-utilisation — afin que le défaut puisse être observé directement :

  • PrepareForDMA et CompleteDMA prennent le mutex ; PerformOperation ne le prend pas (sauf s'il est compilé avec -DFIXED, qui ajoute le verrou manquant).
  • CompleteDMA libère le descripteur, reproduisant fMemory.reset().
  • Un harnais de pilote exécute PerformOperation sur un thread et CompleteDMA sur un autre, plaçant le démontage à l'intérieur de la fenêtre de course avec un signal atomique (uniquement pour le timing — ce n'est jamais un verrou sur l'état partagé).
cd poc
bash run.sh

Build vulnérable :

  • ThreadSanitizer signale une data race — operator delete à l'intérieur de CompleteDMA en concurrence avec la lecture getLength() à l'intérieur de PerformOperation, le mutex n'étant détenu que par le deleter. Journal complet : evidence/tsan_vulnerable.txt.
  • AddressSanitizer signale un heap-use-after-free : l'objet libéré dans CompleteDMA est lu dans PerformOperation::getLength, alloué dans PrepareForDMA. Journal complet : evidence/asan_vulnerable.txt.
==ERROR: AddressSanitizer: heap-use-after-free ... in MemoryDescriptor::getLength()
freed by thread T0 here:   ... IODMACommand::CompleteDMA()  race_model.cpp:70
allocated by thread T0:    ... IODMACommand::PrepareForDMA() race_model.cpp:61

Le build corrigé (-DFIXED, le verrou ajouté à PerformOperation) : les deux sanitizers sont propres et chaque opération se sérialise correctement face au teardown. Journaux : evidence/tsan_fixed.txt, evidence/asan_fixed.txt.

Cela prouve que la course est réelle dans la logique et que le verrou est à la fois nécessaire et suffisant. Il ne s'agit pas d'un kernel panic réel — voir le périmètre ci-dessous.

Le correctif

Télécharger l’outil