
Utilitaire en ligne de commande Windows pour lire, écrire et exécuter du code en mode noyau depuis un contexte Administrateur en utilisant une technique de redirection d'exécution par validation de police, permettant un débogage avancé du noyau et le dépannage système.
r0ak est un utilitaire en ligne de commande Windows qui vous permet de lire, écrire et exécuter facilement du code en mode noyau (avec certaines limitations) depuis l'invite de commandes, sans nécessiter autre chose que des privilèges Administrateur.
r0ak v1.0.0 -- Ring 0 Army Knife
http://www.github.com/ionescu007/r0ak
Copyright (c) 2018 Alex Ionescu [@aionescu]
http://www.windows-internals.com
USAGE: r0ak.exe
[--execute <Address | module.ext!function> <Argument>]
[--write <Address | module.ext!function> <Value>]
[--read <Address | module.ext!function> <Size>]

Le noyau Windows est un environnement riche dans lequel des centaines de pilotes s'exécutent sur un système typique, et où des milliers de variables contenant l'état global sont présentes. Pour un dépannage avancé, les experts informatiques utilisent généralement des outils tels que le débogueur Windows (WinDbg), les outils SysInternals, ou écrivent les leurs. Malheureusement, l'utilisation de ces outils devient de plus en plus difficile, et ils sont eux-mêmes limités par leur propre accès aux API Windows et aux fonctionnalités exposées.
Certains des défis actuels incluent :
Dans un tel environnement, il était clair qu'un outil simple pouvant être utilisé comme un pansement/correctif d'urgence et pour dépanner rapidement les problèmes au niveau du noyau/système qui peuvent être apparents en analysant l'état du noyau pourrait être précieux pour la communauté.

r0ak fonctionne en redirigeant le flux d'exécution des vérifications de validation de police de confiance du gestionnaire de fenêtres lors de la tentative de chargement d'une nouvelle police, en remplaçant la routine de comparaison de la table des polices de confiance par une fonction alternative qui planifie un élément de travail exécutif (WORK_QUEUE_ITEM) stocké dans le nœud d'entrée. Ensuite, l'enfant droit de la table des polices de confiance (qui sert de nœud racine) est remplacé par un tampon d'écriture de pipe nommé (NP_DATA_ENTRY) dans lequel un élément de travail personnalisé est stocké. La fonction de travail sous-jacente de cet élément et son paramètre seront finalement exécutés par un ExpWorkerThread dédié à PASSIVE_LEVEL une fois qu'un chargement de police est tenté et que la routine de comparaison s'exécute, recevant le nœud parent basé sur un pipe nommé comme entrée. Un événement de trace Event Tracing for Windows (ETW) en temps réel est utilisé pour recevoir une notification asynchrone que l'élément de travail a terminé son exécution, ce qui permet de démanteler les structures, de libérer les tampons en mode noyau et de restaurer le fonctionnement normal en toute sécurité.
Lors de l'utilisation de l'option --execute, cette fonction et ce paramètre sont fournis par l'utilisateur.
Lors de l'utilisation de --write, un gadget personnalisé est utilisé pour modifier des valeurs 32 bits arbitraires n'importe où dans la mémoire du noyau.
Lors de l'utilisation de --read, le gadget d'écriture est utilisé pour modifier le pointeur et la taille du tampon HSTI du système (N.B. : Ce comportement est destructeur pour toute autre application qui demandera les données HSTI. Comme il s'agit d'un comportement facultatif de Windows et que cet outil est destiné au débogage/expérimentation d'urgence, cette perte de données a été considérée comme acceptable). Ensuite, l'API HSTI Query est utilisée pour copier les données dans l'espace d'adressage en mode utilisateur de l'outil, et un dump hexadécimal est affiché.
Étant donné que seules des fonctionnalités intégrées Windows, signées par Microsoft, sont utilisées, et que toutes les fonctions appelées font partie du bitmap KCFG, il n'y a aucune violation des contrôles de sécurité, et aucun indicateur de débogage n'est requis, ni l'utilisation de pilotes tiers mal écrits.
Non. Étant donné que cet outil — et la technique sous-jacente — nécessitent un jeton privilégié de niveau SYSTEM, qui ne peut être obtenu que par un utilisateur exécuté sous le compte Administrateur, aucune limite de sécurité n'est contournée pour obtenir l'effet. Le comportement et l'utilité de l'outil ne sont possibles que grâce au contexte de sécurité élevé/ privilégié du compte Administrateur sur Windows, et sont considérés comme un comportement de conception.
Bien sûr ! Il est important de toujours signaler les problèmes de sécurité à Microsoft, même si aucune violation des limites privilégiées ne semble s'être produite — leurs équipes de chercheurs et de développeurs pourraient trouver de nouveaux vecteurs et moyens d'atteindre certains chemins de code auxquels un chercheur externe n'aurait pas pensé.
Ainsi, en novembre 2014, un dossier de sécurité a été déposé auprès du Microsoft Security Research Centre (MSRC) qui a répondu : "[…] n'entre pas dans le cadre d'un problème de sécurité que nous traiterions via notre véhicule traditionnel de Bulletin de Sécurité. Il […] présuppose des privilèges administrateur — un endroit où, architecturalement, nous ne définissons actuellement pas de limite de sécurité défendable. Par conséquent, nous ne poursuivrons pas cette piste pour la corriger."
De plus, en avril 2015 lors de la conférence Infiltrate, une présentation intitulée Insection : AWEsomely Exploiting Shared Memory Objects a détaillé ce problème, y compris aux développeurs Microsoft présents, qui ont convenu que cela était actuellement hors du champ des limites de sécurité architecturales de Windows. En effet, il existe littéralement des dizaines — voire plus — d'autres moyens par lesquels un Administrateur peut lire/écrire/exécuter de la mémoire Ring 0. Cet outil permet simplement une commodification facile d'un de ces vecteurs, à des fins de débogage et de dépannage de problèmes système.
Conditionner ce code en tant que bibliothèque nécessiterait de supprimer soigneusement tout l'analyse interactif de la ligne de commande et la sortie standard, à ce stade, sans réécritures majeures, le 'kit' :
Les attaquants intéressés par cette approche particulière — par rapport à de nombreuses autres techniques plus compatibles et ne nécessitant pas de droits SYSTEM — ont probablement déjà adapté leur propre code basé sur la Preuve de Concept d'avril 2015 — il y a plus de 3 ans.
En raison de l'utilisation du moteur de symboles Windows, vous devez avoir installé soit le kit de développement logiciel (SDK) Windows, soit le kit de pilotes Windows (WDK) avec les outils de débogage pour Windows. L'outil recherchera automatiquement votre chemin d'installation et utilisera les DbgHelp.dll et SymSrv.dll présents dans ce répertoire. Comme ces fichiers ne sont pas redistribuables, ils ne peuvent pas être inclus avec la version de l'outil.
Alternativement, si vous obtenez ces bibliothèques par vous-même, vous pouvez modifier le code source pour les utiliser.
L'utilisation des symboles nécessite une connexion Internet, sauf si vous les avez préalablement mis en cache localement. De plus, vous devez configurer la variable _NT_SYMBOL_PATH pointant vers un serveur de symboles approprié et un emplacement de cache.
Il est supposé qu'un expert informatique ou autre dépanneur qui aurait apparemment besoin de lire/écrire/exécuter la mémoire du noyau (et qui connaît les variables du noyau appropriées à accéder) est déjà plus qu'intimement familier avec les exigences de configuration ci-dessus. Veuillez ne pas ouvrir de problèmes demandant ce qu'est le SDK ou comment définir une variable d'environnement.
Un pilote a fuité un pool noyau ? Pourquoi ne pas appeler ntoskrnl.exe!ExFreePool et passer l'adresse noyau qui fuit ? Et une référence d'objet ? Appelez ntoskrnl.exe!ObfDereferenceObject et faites le nettoyer.
Vous voulez vider le journal DbgPrint du noyau ? Pourquoi ne pas vider le tampon circulaire interne à ntoskrnl.exe!KdPrintCircularBuffer
Vous vous demandez quelle est la taille des piles noyau sur votre machine ? Essayez de regarder ntoskrnl.exe!KeKernelStackSize
Vous voulez vider la table des appels système pour rechercher des hooks ? Allez imprimer ntoskrnl.exe!KiServiceTable
Ce ne sont que quelques exemples — toutes les adresses Ring 0 sont acceptées, soit par la syntaxe module!symbol soit en passant directement le pointeur noyau s'il est connu. Le moteur de symboles Windows est utilisé pour les rechercher.
L'outil nécessite certaines variables et fonctions du noyau qui ne sont connues que pour exister dans les versions modernes de Windows 10, et n'était destiné à fonctionner que sur les systèmes 64 bits. Ces limitations sont dues au fait que sur les systèmes plus anciens (ou les systèmes x86), ces exigences de sécurité plus strictes n'existent pas, et par conséquent, des approches plus traditionnelles peuvent être utilisées à la place. C'est un outil personnel que je mets à disposition, et je n'avais pas besoin de ces systèmes plus anciens, où je pourrais utiliser un simple pilote à la place. Cela dit, ce dépôt accepte les pull requests, si quelqu'un est intéressé par le portage.
Deuxièmement, en raison des cas d'utilisation et de mes propres besoins, les restrictions suivantes s'appliquent :
Évidemment, ces limitations pourraient être corrigées en choisissant programmatiquement une approche différente, mais elles correspondent aux besoins d'un outil en ligne de commande et à mes cas d'utilisation. Encore une fois, les pull requests sont acceptées si d'autres souhaitent contribuer leurs propres ajouts.
Notez que toute exécution (y compris l'exécution des commandes --read et --write) se produit dans le contexte d'un thread de travail système à PASSIVE_LEVEL. Par conséquent, les adresses en mode utilisateur ne doivent pas être passées en paramètres/arguments.
Les pull requests sont les bienvenues. Pour les changements majeurs, veuillez d'abord ouvrir un problème pour discuter de ce que vous souhaitez modifier.
Copyright 2018 Alex Ionescu. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY ALEX IONESCU ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALEX IONESCU
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and
should not be interpreted as representing official policies, either expressed or implied, of Alex Ionescu.