R&D, protection des processus Windows

Tristan Leiter
Blog cybersécurité

Cela fait partie des valeurs de Navixia de s’impliquer dans la recherche et développement de produits de sécurité et de promouvoir les formations universitaires dans le domaine de la cybersécurité en Suisse.

C’est pourquoi Jämes Ménétrey, étudiant en master à la HES-SO, nous a rejoints durant six mois afin de compléter sa thèse de master.

Son mémoire, intitulé “Software Supervisor: A Security Mechanism That Protects Executing Programs From Malicious Manipulation” consiste en la réalisation d’un état de l’art des méthodes de protection logicielles et le développement d’un outil isolant certains processus Windows critiques, dans le but d’empêcher qu'ils fassent l'objet de manipulations malveillantes.

De quoi s'agit-il?

Un processus est un programme en cours d’exécution sur un système d’exploitation. L'une des caractéristiques d’un processus est de garantir l’isolement du programme. Cette mesure permet notamment au système d’exploitation de déterminer les ressources qui lui sont allouées, par exemple la mémoire, et de les libérer lorsque le programme se termine ou rencontre une erreur provoquant la fin du processus.

Seulement, l’isolement d’un processus ne possède pas la caractéristique d’imperméabilité des informations qu’il contient. Cela signifie qu’un processus peut interagir avec un autre, par exemple pour en extraire des données sensibles présentes dans sa mémoire, et ce sans son consentement. Ainsi, la notion de processus assure un rôle important dans la gestion des programmes au sein du système d’exploitation, mais ne garantit pas de notions de confidentialité des données.

Le but de ce travail de master est de déterminer comment Windows peut être étendu afin d’élargir la notion de processus pour que ceux-ci offrent cette composante de sécurité supplémentaire et ainsi limiter voire interdire l’accès à des processus qui contiennent des données critiques pour une entreprise.

Un cas concret d’accès à un processus critique

Pour comprendre l’impact que peut avoir la perméabilité d’un processus en termes d’accès à sa mémoire, prenons le cas d’un outil de gestionnaire de mot de passe: KeePass. Ce programme crée un conteneur de mots de passe cryptographiquement sécurisé sur un support de stockage de l’ordinateur. Lorsque le processus de KeePass est exécuté et ouvre un conteneur, l’utilisateur est invité à introduire un mot de passe ou à fournir un moyen similaire afin de déchiffrer son contenu. Une fois cette action effectuée, l’utilisateur a la possibilité de consulter son contenu, sans réintroduire le mot de passe du conteneur pour déchiffrer à nouveau le contenu, car ce dernier est stocké en mémoire. Évidemment, KeePass ne stocke pas ce moyen de déchiffrement sous sa forme originale, mais conserve un équivalent lui donnant la possibilité de récupérer les mots de passe du conteneur.

Ce moyen de fonctionnement rend le processus de KeePass critique, car un autre processus a la possibilité de lire la mémoire de KeePass afin d’en extraire les informations qu’il souhaite, comme le mot de passe principal du conteneur (ou sa représentation cryptographique), que KeePass conserve tant que le conteneur est ouvert. En pratique, un processus malveillant infecte le processus de KeePass et appelle les fonctions d’accès aux mots de passe que KeePass utilise lui-même pour récupérer ces derniers lorsque l’utilisateur les demande. C’est notamment cette technique qui est utilisée par des démonstrateurs de récupération d’informations sensibles dans KeePass (KeeThief, KeeFarce).

De plus, la documentation officielle de KeePass informe ses utilisateurs des dispositions utilisées pour protéger la mémoire de KeePass (voir la section Process Memory Protection). Cette dernière indique notamment que pour certaines opérations, KeePass est contraint d’exposer des données sensibles de manière non chiffrée dans la mémoire du processus. Par exemple, c’est le cas lorsque l’utilisateur souhaite afficher un mot de passe en clair dans l’interface de KeePass. Cela facilite d’autant plus l’extraction de données sensibles lorsque la mémoire du processus est copiée afin d’en analyser son contenu dans un deuxième temps (analyse forensique).

Comment lutter contre l’exposition de ces données sensibles?

Le travail de master de Jämes Ménétrey introduit une nouvelle notion dans le système d’exploitation de Microsoft pour limiter l’interaction entre deux processus: le système d’enclaves. Une enclave est définie comme une bulle de protection enveloppant un ou plusieurs processus. Les processus se trouvant à l’intérieur d’une enclave ont la possibilité d'interagir avec les processus en dehors de cette zone protégée mais l'inverse n'est pas possible, à moins qu’ils aient ouverts explicitement un canal de communication. Grâce à cela, un processus ne peut plus lire la mémoire d’un autre processus contenu dans une enclave.

Les enclaves sont créées, gérées et détruites grâce à un pilote développé pour ce travail de master, qui s’exécute dans le noyau de Windows (appelé kernel en anglais). Ce pilote à la capacité de filtrer les interactions entre deux processus. De cette manière, il maintient un ensemble de structures de données dans le but de déterminer si un processus donné est situé dans une enclave et ainsi, bloquer l’interaction des autres processus. Le pilote étend également cette notion d’enclaves sur le système de fichiers du système d’exploitation, afin d’empêcher un processus de manipuler des fichiers sensibles, tels qu’un conteneur sécurisé de mots de passe. Ainsi, ce système assure qu’un conteneur sécurisé ne peut être atteint que par un programme bien défini, qui est lui aussi protégé.

Les droits d’accès aux enclaves

Ce travail définit deux types d’enclaves:

  1. les enclaves de protection, contenant les processus et données critiques (KeePass.exe par exemple) et
  2. les enclaves de dépendances, contenant les dépendances nécessaires au fonctionnement des processus critiques (kernel32.dll par exemple)

L’introduction de ces deux notions s’est révélée nécessaire, car les dépendances sont des vecteurs d’attaque pour les processus protégés et doivent donc être inclues dans la protection. Cependant, les dépendances ne constituent pas des données critiques en soi. Leur niveau de protection est alors amoindri comparé au niveau de protection d’une donnée critique. Les droits liés aux différentes interactions des processus sont illustrés dans l’image ci-dessous. Ces règles peuvent être résumées ainsi:

  • Un processus en dehors du système de protection peut lire le contenu d’une dépendance, mais pas le modifier. Il n’a aucun accès aux processus et données dans l’enclave de protection.
  • Un processus à l’intérieur du système de protection peut lire le contenu d’une dépendance, mais pas le modifier. Il a la possibilité d’accéder aux ressources contenues dans la même enclave. Il a de plus accès aux processus à l’extérieur du système de protection.

En outre, un processus peut appartenir à plusieurs enclaves, permettant ainsi de partager des données critiques entre plusieurs processus.

Les droits des processus envers les ressources protégées dans le système d’enclaves.

Une gestion centralisée des enclaves

Le système gérant les enclaves sur les ordinateurs a été centralisé sous la forme d’une application Web. Elle permet de gérer un parc de machines disposant d’enclaves. Une partie importante du projet est également la remontée d’informations provenant d’interactions qui ont été bloquées. En effet, un processus qui tente de manipuler un processus protégé est journalisé et cette information est remontée au serveur gérant les enclaves. Les administrateurs ont ensuite la possibilité de consulter ces alertes via l’interface Web. Grâce à cela, il est possible de détecter les activités malveillantes liées à l’interaction de processus, ainsi que l’accès aux fichiers protégés dans les enclaves. D’autres fonctionnalités sont également disponibles, comme la suspension d’une ou plusieurs enclaves lors d’une mise jour de programmes protégés.

Architecture et technologies utilisées

L’outil qui résulte de ce travail de master est nommé Navixia Shield. Il est composé de trois parties:

  • Une interface Web en ASP.NET Core
  • Un agent en .NET installé sur chaque serveur où sont localisées les enclaves. Il permet de propager la configuration des enclaves au pilote et de transmettre leurs journaux d’activité. Les agents interagissent avec le serveur en temps réel, grâce à un Web socket.
  • Un pilote en C, connecté à l’agent pour la gestion des enclaves ainsi que la récupération des informations sur les enclaves, comme les journaux d’activités des interactions bloquées.

Il a été constaté que l’utilisation d’un langage de programmation de niveau supérieur, dans ce cas le C#, a facilité le développement des plates-formes telles que l’interface Web ainsi que de l’agent, tout en offrant la flexibilité d’une excellente compatibilité avec des langages de plus bas niveau, dans ce cas le C pour le développement du pilote. Grâce à cela, un protocole de communication a pu être développé, permettant de transférer des données d’une technologie à une autre de manière aisée. Un aperçu de transmission de données est illustré dans la fonction suivante (C#), qui se trouve dans l’agent dialoguant avec le pilote:

// Sends a given buffer to the driver and receives a buffer in response.
public static unsafe TOutBuffer FilterSendMessage<TInBuffer, TOutBuffer>
  (SafeHandle handle, in TInBuffer buffer)
    where TInBuffer : unmanaged
    where TOutBuffer : unmanaged
{
    TOutBuffer outBuffer;

    // The input buffer is fixed in memory, so we can dereference it without the fear of being annoyed by the garbage collector
    fixed (void* inBufferPtr = &buffer)
    {
        // Send and receive the buffers to the driver
        var result = NativeApi.FilterSendMessage(
            handle,
            inBufferPtr,
            (uint) sizeof(TInBuffer),
            &outBuffer,
            (uint) sizeof(TOutBuffer),
            out _);

        if (result != (uint) HResult.SuccessOk)
        {
            throw new Win32Exception((int) result, "Cannot send a message [..].");
        }
    }

    return outBuffer;
}

Le code source ci-dessus est une fonction prenant une structure de données en C# et retournant une autre structure de données. Leurs types sont définis grâce aux paramètres de type TInBuffer et TOutBuffer, qui ont la caractéristique d’être unmanaged. Cela signifie que les structures passées en argument sont contiguës en mémoire et peuvent donc être copiées d’un bloc, sans la crainte d’avoir un pointeur sur un objet C#. Grâce à cela, les structures peuvent être envoyées et reçues vers le pilote. C’est ainsi que les informations sont communiquées entre l’agent et le pilote. Il s’agit ici d’un des nombreux exemples démontrant la maniabilité de ce langage et son interopérabilité avec d’autres systèmes.

Du côté du pilote, les interactions entre les processus sont notamment régulées grâce aux object callbacks, un filtre permettant l’ajout de restrictions lorsqu’un processus tente d’accéder à un autre. Le pilote est de type minifilter file system, ce qui lui permet également de filtrer l’accès au système de fichiers. C’est grâce à cette solution qu’il est possible d’interdire l’accès aux fichiers localisés dans une enclave.

Aperçu de l’interface d’administration

Les captures d’écran ci-dessous illustrent l’interface que les administrateurs utilisent pour gérer les enclaves sur plusieurs machines.

Gestion des machines


Gestion des enclaves


Détails d’une enclave.

Intéressé/e par cette solution de sécurité ?

Le prototype de ce travail de master a été suffisant pour démontrer que ce système de protection est fonctionnel et permet d’obtenir assez d’informations pour détecter et ralentir une attaque menée sur des processus critiques. Cependant, ce dernier n’est pas disponible en tant que produit proposé par Navixia car en raison de sa complexité il requiert encore passablement de développement et de vérification. Néanmoins, si vous êtes intéressé à travailler avec nous sur un tel projet, n’hésitez pas à prendre contact avec nous, par l’intermédiaire de notre formulaire de contact.

Informations complémentaires relatives au travail de master

Ce travail a été réalisé par Jämes Ménétrey dans le cadre de la formation en Master of Science en Engineering (MSE) à la Haute École Spécialisée de Suisse occidentale (HES-SO) durant le semestre d’hiver 2019-2020. Il a été supervisé par Tristan Leiter, Security Architect chez Navixia et par Prof. Dr. Sylvain Pasini à la HEIG-VD. Il a obtenu la note maximum de 6 pour sa conception, implémentation et soutenance.

Commentaires

Aucun commentaire pour l'instant. Soyez le premier!

Laissez votre commentaire