Protection des services anti-programme malveillant

Windows 8.1 a introduit un nouveau concept de services protégés pour protéger les services anti-programme malveillant, qui sont souvent la cible d’attaques par des programmes malveillants.

Découvrez comment protéger les services anti-programme malveillant en mode utilisateur et comment choisir d’inclure cette fonctionnalité dans votre service anti-programme malveillant.

Ces informations s’appliquent aux systèmes d’exploitation suivants et à leurs successeurs :

  • Windows 8.1
  • Windows Server 2012 R2

Les références et les ressources présentées ici sont répertoriées à la fin de cette rubrique.

Introduction

La plupart des solutions anti-programme malveillant comprennent un service en mode utilisateur qui procède à des opérations spéciales pour détecter et supprimer des programmes malveillants du système. Ce service en mode utilisateur est également souvent responsable du téléchargement des dernières définitions et signatures de virus. Ce service en mode utilisateur devient une cible fréquente des programmes malveillants, car il s’agit du point de défaillance unique pour désactiver la protection sur un système. Pour se défendre contre les attaques visant le service en mode utilisateur, les éditeurs de logiciels anti-programme malveillant doivent ajouter un grand nombre de fonctionnalités et d’heuristiques à leurs logiciels. Toutefois, ces techniques ne sont pas totalement infaillibles et ont tendance à être sujettes à des erreurs, car elles doivent identifier les fonctions que Windows effectue sur leur service et les activer individuellement.

Dans Windows 8.1, un nouveau concept de service protégé a été introduit pour permettre aux services en mode utilisateur anti-programme malveillant d’être lancés en tant que service protégé. Une fois que le service est lancé en tant que service protégé, Windows utilise l’intégrité du code pour autoriser uniquement le chargement du code approuvé dans le service protégé. Windows protège également ces processus contre l’injection de code et autres attaques contre les processus d’administration.

Ce document décrit comment un éditeur de logiciels anti-programme malveillant avec un pilote de démarrage à lancement anticipé (ELAM, Early Launch Anti-Malware) peut opter pour cette fonctionnalité et lancer son service anti-programme malveillant en tant que service protégé.

Processus protégés par le système

À compter de Windows 8.1, un nouveau modèle de sécurité a été mis en place dans le noyau pour mieux se défendre contre les attaques malveillantes sur les composants critiques du système. Ce nouveau modèle de sécurité englobe les précédentes versions de l’infrastructure de processus protégés de Windows utilisées pour des scénarios spécifiques, tels que la lecture de contenu DRM, dans un modèle à usage général qui peut être utilisé par les éditeurs de logiciels anti-programmes malveillants tiers. L’infrastructure de processus protégés autorise uniquement le chargement de code approuvé et signé et offre une défense intégrée contre les attaques par injection de code.

Remarque

Les DLL de script suivantes sont interdites par CodeIntegrity à l’intérieur d’un processus protégé (qu’elles soient directement ou indirectement chargées) tel que via WinVerifyTrust ou WinVerifyTrustEx pour la vérification de signatures de script via AuthentiCode : scrobj.dll, scrrun.dll, jscript.dll, jscript9.dll et vbscript.dll.

Pour plus d’informations sur les processus protégés, consultez Processus protégés dans Windows Vista.

Le nouveau modèle de sécurité utilise une variante légèrement différente de l’infrastructure de processus de protection appelée processus protégés par le système, qui est plus adaptée à cette fonctionnalité parce qu’elle permet de garder le contenu DRM séparé. Chaque processus protégé par le système a un niveau ou un attribut associé, qui indique la stratégie de signature du code signé autorisé à se charger dans le processus. Une fois que les services anti-programme malveillant ont choisi le mode de service protégé, seul le code signé par Windows ou le code signé avec les certificats de l’éditeur de logiciels anti-programme malveillant sont autorisés à se charger dans ce processus. De même, les autres niveaux de processus protégés ont des stratégies de code différentes appliquées par Windows.

Spécifications

Pour qu’un service anti-programme malveillant en mode utilisateur s’exécute en tant que service protégé, l’éditeur de logiciels anti-programme malveillant doit disposer d’un pilote de démarrage à lancement anticipé installé sur l’ordinateur Windows. En plus des exigences de certification existantes des pilotes de démarrage à lancement anticipé, le pilote doit avoir une section de ressource incorporée contenant les informations des certificats utilisés pour signer les binaires du service en mode utilisateur.

Important

Dans Windows 8.1, la chaîne de certification doit être une racine connue, telle que déterminée par la vérification du pilote, ou le certificat racine doit être inclus.

Pendant le processus de démarrage, cette section de ressource est extraite du pilote de démarrage à lancement anticipé pour valider les informations de certificat et inscrire le service anti-programme malveillant. Le service anti-programme malveillant peut également être inscrit pendant le processus d’installation du logiciel anti-programme malveillant en appelant une API spéciale, comme décrit plus loin dans ce document.

Une fois que la section de ressource est extraite du pilote de démarrage à lancement anticipé et que le service en mode utilisateur est inscrit, le service est autorisé à démarrer en tant que service protégé. Une fois que le service est lancé en tant que service protégé, les autres processus non protégés sur le système ne peuvent pas injecter de threads et ne sont pas autorisés à écrire dans la mémoire virtuelle du processus protégé.

De plus, les DLL non-Windows qui sont chargées dans le processus protégé doivent être signées avec un certificat approprié.

Pour plus d’informations sur les pilotes de démarrage à lancement anticipé, consultez Logiciel anti-programme malveillant à lancement anticipé.

Exigences de signature du service anti-programme malveillant

Le service en mode utilisateur qui doit être lancé en tant que service protégé doit être signé avec des certificats valides. L’EXE du service doit être signé par hachage de page, et les DLL non-Windows chargées dans le service doivent également être signées avec les mêmes certificats. Le hachage de ces certificats doit être ajouté dans le fichier de ressources, qui sera lié au pilote de démarrage à lancement anticipé.

Remarque

Les hachages de fichier/page SHA256 doivent être utilisés, même si les certificats continuent d’être SHA1.

Nous recommandons aux éditeurs de logiciels anti-programme malveillant d’utiliser leur certificat Authenticode existant pour signer leurs binaires de service anti-programme malveillant et d’inclure le hachage de ce certificat Authenticode dans la section de ressource pour indiquer le certificat qui est utilisé pour signer les binaires du service. Si vous mettez à jour ce certificat, une version plus récente du pilote de démarrage à lancement anticipé doit être publiée avec les hachages de certificat mis à jour.

Signature secondaire (facultative)

Les éditeurs de logiciels anti-programme malveillant ont la possibilité de configurer une autorité de certification privée et d’utiliser des certificats de cette autorité de certification pour signer les binaires du service anti-programme malveillant en tant que signature secondaire. Le principal avantage de l’utilisation d’une autorité de certification privée est qu’elle permet aux éditeurs de créer des certificats avec une propriété EKU spéciale, qui peut être utilisée pour différencier plusieurs produits du même éditeur. Elle réduit également le besoin de mettre à jour votre pilote de démarrage à lancement anticipé à cause de l’expiration des certificats, car les certificats d’une autorité de certification privée ont généralement des dates d’expiration plus lointaines.

Notez que si les binaires du service sont signés avec les certificats d’une autorité de certification privée, ils doivent aussi être doublement signés avec les certificats Authenticode existants. Si les binaires ne sont pas signés par une autorité de certification approuvée connue (par exemple VeriSign), l’utilisateur de l’ordinateur n’accorde aucune confiance aux binaires parce qu’il ne peut pas approuver l’autorité de certification privée. La double signature des binaires avec le certificat Authenticode existant permet également aux binaires de s’exécuter sur des systèmes d’exploitation de bas niveau.

Pour plus d’informations sur la configuration et l’installation de l’autorité de certification, consultez Configuration d’une autorité de certification et Installer l’autorité de certification.

Remarque

Pour la compatibilité avec Windows Vista ou Windows XP (ou Windows 7 sans le correctif SHA2), vous pouvez utiliser le commutateur « /as » lors de la signature de vos binaires avec SignTool.exe en utilisant les hachages de fichier/page SHA256. Cette opération ajoute la signature en tant que signature secondaire au fichier. SHA1 signe le fichier en premier, car Windows XP, Windows Vista et Windows 7 ne verront que la première signature.

Exigences de signature pour les DLL

Comme mentionné précédemment, les DLL non-Windows chargées dans le service protégé doivent être signées avec le même certificat que celui utilisé pour signer le service anti-programme malveillant.

Signature de catalogue

Les éditeurs de logiciels anti-programme malveillant peuvent inclure des packages développés par d’autres entreprises sans mettre à jour les signatures binaires. Ils peuvent le faire en incluant les binaires dans un catalogue signé avec leur certificat Authenticode en suivant ces étapes :

  1. Générer un catalogue à l’aide de MakeCat
  2. Ajouter tous les binaires sans signature appropriée dans le catalogue
  3. Signer le catalogue avec le certificat Authenticode, comme vous le feriez pour n’importe quel autre binaire
  4. Utiliser la fonction add catalog pour inclure le catalogue avec l’application.

Lorsque l’intégrité du code tombe sur les packages sans signature appropriée, elle recherche un catalogue avec une signature approuvée. Elle trouvera ce catalogue si ces étapes sont suivies et qu’il est installé avec l’application.

Informations sur les fichiers de ressources

Un fichier de ressources doit être créé et lié au pilote de démarrage à lancement anticipé. Le hachage du certificat, ainsi que d’autres informations de certificat, doit être ajouté dans le fichier de ressources.

La section de ressource doit être sous la forme suivante pour que le système réussisse à extraire les ressources de l’image binaire et valide les informations de certificat incorporées.

MicrosoftElamCertificateInfo  MSElamCertInfoID
{
      3, // count of entries
      L”CertHash1\0”,
      Algorithm,
      L”EKU1\0”,
      L”CertHash2\0”,
      Algorithm,
      L”\0”, //No EKU for cert hash 2
      L”CertHash3\0”,
      Algorithm,
      L”EKU3a;EKU3b;EKU3c\0”,  //multiple EKU entries supported (max: 3)
}

Pour plus d’informations sur le fichier de ressources défini par l’utilisateur, consultez Ressource définie par l’utilisateur.

CertHash

Hachage du certificat utilisé pour signer le service anti-programme malveillant. L’outil CertUtil.exe, fourni dans le SDK Windows, peut être utilisé pour obtenir le hachage.

certutil.exe –v <path to the signed file>

Par exemple :

anti-malware protected service certificate hash (certhash)

Algorithme

La valeur de l’algorithme représente l’algorithme du certificat. Ces valeurs d’algorithme sont prises en charge :

0x8004 – SHA1 0x800c – SHA256 0X800d – SHA384 0x800e – SHA512

N’oubliez pas d’inclure la valeur de l’algorithme (comme indiqué ci-dessus), pas le nom réel de l’algorithme. Par exemple, si le certificat est basé sur l’algorithme SHA256, incluez 0x800c dans la section de ressource.

EKU

L’objet EKU représente une seule propriété d’utilisation améliorée de la clé (EKU) d’un certificat. C’est facultatif et “\0” doit être spécifié si aucune utilisation améliorée de la clé n’est associée au certificat. Dans un cas où il existe plusieurs produits et services d’un seul éditeur de logiciels anti-programme malveillant exécutés sur le même système, l’éditeur en question peut utiliser la propriété EKU du certificat de l’autorité de certification privée pour différencier un service d’un autre. Par exemple, s’il existe deux services exécutés sur le système provenant du même éditeur de logiciels anti-programme malveillant et signés par la même autorité de certification, le service qui doit être lancé comme service protégé peut être signé avec un certificat émis par l’autorité de certification qui contient une utilisation EKU spéciale. Cette utilisation EKU doit être ajoutée à la section de ressource. L’utilisation EKU est ensuite inscrite par le système et associée au hachage de certificat pour valider et lancer le service en tant que service protégé.

Notez que la chaîne de certificats doit inclure l’utilisation EKU Signature de code (1.3.6.1.5.5.7.3.3), mais cette utilisation EKU ne doit pas être incluse dans la section de ressource du pilote de démarrage à lancement anticipé.

Remarque

Si les informations EKU sont incluses dans les informations de certificat pour le pilote de démarrage à lancement anticipé, la même utilisation EKU doit être utilisée lors de la signature de vos binaires.

Remarque

La représentation sous forme de chaîne de l’intégrité du code Windows d’un OID dans une utilisation EKU a une longueur maximale de 64 caractères, zéro de fin compris.  

Remarque

Si vous spécifiez plusieurs utilisations EKU, celles-ci sont évaluées avec la logique AND. Le certificat d’entité de fin doit satisfaire toutes les utilisations EKU spécifiées dans la section de ressource ELAM pour l’entrée donnée.

Count

Si le binaire du service anti-programme malveillant est signé avec le certificat Authenticode et le certificat de l’autorité de certification privée, seules les informations du certificat de l’autorité de certification privée doivent être ajoutées dans la section de ressource.

Lancement des services anti-programme malveillant comme services protégés

Inscription du service

Le service anti-programme malveillant doit être inscrit auprès du système avant de pouvoir être démarré comme service protégé. Pendant l’installation du logiciel anti-programme malveillant, le programme d’installation peut installer le pilote de démarrage à lancement anticipé et redémarrer le système pour inscrire automatiquement le service. Le système inscrit le service au moment du démarrage en extrayant les informations de certificat du fichier de ressources susmentionné qui est lié au pilote de démarrage à lancement anticipé.

Pendant la phase d’installation, il est vivement recommandé de redémarrer le système afin que le pilote de démarrage à lancement anticipé soit chargé et valide l’état du système. Toutefois, dans les cas où un redémarrage doit être évité, Windows expose également un mécanisme permettant au programme d’installation du logiciel anti-programme malveillant d’inscrire le service comme protégé à l’aide d’une API.

Inscription du service sans redémarrer le système

Pendant l’installation, le programme d’installation du logiciel anti-programme malveillant peut appeler l’API InstallELAMCertificateInfo et fournir un handle au fichier du pilote de démarrage à lancement anticipé. Le système ouvre le pilote de démarrage à lancement anticipé, appelle des routines internes pour vérifier qu’il est signé correctement et extrait les informations de certificat de la section de ressource qui lui est associée. Pour obtenir la syntaxe de la fonction, consultez InstallELAMCertificateInfo.

Exemple de code :

HANDLE FileHandle = NULL;

FileHandle = CreateFile(<Insert Elam driver file name>,
                        FILE_READ_DATA,
                        FILE_SHARE_READ,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL
                        );

if (InstallElamCertificateInfo(FileHandle) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

Démarrage du service en tant que service protégé

Le programme d’installation peut suivre ces étapes pour créer, configurer et démarrer le service en tant que service protégé :

  1. Appelez l’API CreateService pour créer un objet de service et l’ajouter à la base de données du Gestionnaire de contrôle des services (SCM).

  2. Appelez l’API SetServiceObjectSecurity pour définir le descripteur de sécurité de l’objet de service créé à l’étape 1.

  3. Appelez l’API ChangeServiceConfig2 pour marquer le service comme protégé, en spécifiant la nouvelle valeur d’énumération SERVICE_CONFIG_LAUNCH_PROTECTED, qui a été ajoutée dans Winsvc.h (à compter de Windows 8.1).

    Exemple de code :

    SERVICE_LAUNCH_PROTECTED_INFO Info;
    SC_HANDLE hService;
    
    Info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;
    
    hService = CreateService (/* ... */);
    
    if (ChangeServiceConfig2(hService,
                             SERVICE_CONFIG_LAUNCH_PROTECTED,
                             &Info) == FALSE)
    {
        Result = GetLastError();
    }
    
  4. Appelez l’API StartService pour démarrer le service. Lors du démarrage du service en tant que service protégé, SCM fait appel au sous-système Intégrité du code (CI) pour valider les informations de certificat. Une fois les informations de certificat validées par CI, SCM lance le service en tant que service protégé.

    1. Notez que cette étape échoue si vous n’avez pas inscrit le service en appelant l’API InstallELAMCertificateInfo.
    2. Si le service a été configuré pour démarrer automatiquement pendant la phase de démarrage du système, vous pouvez éviter cette étape et redémarrer simplement le système. Pendant un redémarrage, le système inscrit automatiquement le service (si le pilote de démarrage à lancement anticipé démarre correctement) et démarre le service en mode protégé.
    3. Si le service ne parvient pas à démarrer, consultez Journalisation des événements de l’intégrité du code et audit du système, ainsi que les rubriques suivantes. Vous y trouverez des messages d’erreur plus détaillés qui expliquent pourquoi le système de l’intégrité du code a empêché le service de démarrer. Ces journaux peuvent également vous aider à identifier les DLL que le service a essayé de charger sans y parvenir.

Lancement d’un processus enfant en mode protégé

Le nouveau modèle de sécurité permet également aux services protégés anti-programme malveillant de lancer des processus enfants en mode protégé. Ces processus enfants s’exécutent au même niveau de protection que le service parent et leurs binaires doivent être signés avec le même certificat qui a été inscrit via la section de ressource ELAM.

Pour permettre au service protégé anti-programme malveillant de lancer le processus enfant en mode protégé, une nouvelle clé d’attribut étendue, PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, a été exposée et doit être utilisée avec l’API UpdateProcThreadAttribute. Un pointeur vers la valeur d’attribut de PROTECTION_LEVEL_SAME doit être transmis à l’API UpdateProcThreadAttribute.

Remarques :

  • Pour utiliser ce nouvel attribut, le service doit également spécifier CREATE_PROTECTED_PROCESS dans le paramètre d’indicateurs de création de processus de l’appel CreateProcess.
  • Vous devez faire signer vos binaires de service à l’aide du commutateur /ac pour inclure le certificat croisé de façon à le chaîner à une autorité de certification connue. Un certificat auto-signé sans chaînage approprié à une autorité de certification racine connue ne fonctionnera pas.

Exemple de code :

DWORD ProtectionLevel = PROTECTION_LEVEL_SAME;
SIZE_T AttributeListSize;

STARTUPINFOEXW StartupInfoEx = { 0 };

StartupInfoEx.StartupInfo.cb = sizeof(StartupInfoEx);

if (InitializeProcThreadAttributeList(NULL,
                                      1,
                                      0,
                                      &AttributeListSize) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

StartupInfoEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(
    GetProcessHeap(),
    0,
    AttributeListSize
    );

if (InitializeProcThreadAttributeList(StartupInfoEx.lpAttributeList,
                                      1,
                                      0,
                                      &AttributeListSize) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

if (UpdateProcThreadAttribute(StartupInfoEx.lpAttributeList,
                              0,
                              PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL,
                              &ProtectionLevel,
                              sizeof(ProtectionLevel),
                              NULL,
                              NULL) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

PROCESS_INFORMATION ProcessInformation = { 0 };

if (CreateProcessW(ApplicationName,
                   CommandLine,
                   ProcessAttributes,
                   ThreadAttributes,
                   InheritHandles,
                   EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS,
                   Environment,
                   CurrentDirectory,
                   (LPSTARTUPINFOW)&StartupInfoEx,
                   &ProcessInformation) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

Mises à jour et maintenance

Une fois le service anti-programme malveillant lancé en tant que service protégé, les autres processus non protégés (et même les administrateurs) ne peuvent pas l’arrêter. Dans le cas de mises à jour des binaires du service, le service anti-programme malveillant doit recevoir un rappel du programme d’installation pour s’arrêter et ainsi faire l’objet d’une maintenance. Une fois le service arrêté, le programme d’installation du service anti-programme malveillant peut effectuer des mises à niveau, puis suivre les étapes décrites ci-dessus dans les sections Inscription du service et Démarrer le service en tant que service protégé pour inscrire le certificat et démarrer le service en tant que service protégé.

Notez que le service doit s’assurer que seuls les appelants approuvés peuvent arrêter le service. Si des appelants non approuvés sont autorisés à le faire, la protection du service est réduite à néant.

Désinscription du service

Lorsque vous désinstallez un service protégé, le service doit se marquer comme non protégé en appelant l’API ChangeServiceConfig2. Notez que, étant donné que le système n’autorise aucun processus non protégé à modifier la configuration d’un service protégé, l’appel à ChangeServiceConfig2 doit être effectué par le service protégé lui-même. Une fois le service reconfiguré pour s’exécuter en tant que service non protégé, le programme de désinstallation peut simplement prendre les mesures appropriées pour supprimer le logiciel anti-programme malveillant du système.

Débogage d’un service anti-programme malveillant protégé

Dans le cadre du modèle de sécurité des processus protégés, les autres processus non protégés ne peuvent pas injecter de threads ni écrire dans la mémoire virtuelle du processus protégé. Toutefois, un débogueur de noyau est autorisé à déboguer tous les processus protégés contre les programmes malveillants. Le débogueur du noyau peut également être utilisé pour vérifier si le service anti-programme malveillant s’exécute en tant que service protégé ou non :

dt –r1 nt!_EPROCESS <Process Address>
+0x67a Protection       : _PS_PROTECTION
      +0x000 Level            : 0x31 '1'
      +0x000 Type             : 0y0001
      +0x000 Signer           : 0y0011

Si la valeur du membre Type est 0y0001, le service s’exécute en tant que service protégé.

De plus, seules les commandes SC suivantes sont autorisées sur le service anti-programme malveillant protégé :

  • sc config start=Auto
  • sc qc
  • sc start
  • sc interrogate
  • sc sdshow

Si le débogueur est attaché, utilisez l’indicateur suivant dans le Registre pour l’arrêter lorsque des binaires non signés (ou incorrectement signés) sont chargés dans le service anti-programme malveillant protégé.

Key:   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CI
Value: DebugFlags      REG_DWORD

Définissez la valeur sur 00000400 pour arrêter le débogueur lorsque la validation de signature échoue.

Remarque

Limites des processus protégés :

  1. Les processus qui ont une interface utilisateur ou une interface graphique utilisateur ne peuvent pas être protégés en raison de la façon dont le noyau verrouille un processus en mémoire et parce qu’il n’y autorise pas les écritures.
  2. Avant Windows 10 version 1703 (la mise à jour Creators), les processus protégés ne peuvent pas utiliser les protocoles de communication TLS ou SSL en raison des limitations du partage de certificats entre l’autorité de sécurité locale (LSA) et un processus protégé.

Ressources

Pour plus d’informations, voir :

Ces fonctions d’API Windows sont référencées dans cet article :