Gestion de l’emprunt d’identité client dans les pilotes UMDF
Cette rubrique décrit comment un pilote UMDF (User-Mode Driver Framework) accède aux ressources protégées, à partir de la version UMDF 2.
Les pilotes UMDF s’exécutent généralement sous le compte LocalService et ne peuvent pas accéder aux fichiers ou aux ressources qui nécessitent des informations d’identification utilisateur, telles que des fichiers protégés ou d’autres ressources protégées. Un pilote UMDF fonctionne généralement sur les commandes et les données qui circulent entre une application cliente et un appareil. Par conséquent, la plupart des pilotes UMDF n’accèdent pas aux ressources protégées.
Toutefois, certains pilotes peuvent nécessiter l’accès à une ressource protégée. Par exemple, un pilote UMDF peut charger le microprogramme dans un appareil à partir d’un fichier fourni par une application cliente. Le fichier peut avoir une liste de contrôle d’accès (ACL) qui empêche les utilisateurs non autorisés de modifier le fichier et de prendre le contrôle de l’appareil. Malheureusement, cette liste de contrôle d’accès empêche également le pilote UMDF d’accéder au fichier.
L’infrastructure fournit une fonctionnalité d’emprunt d’identité qui permet aux pilotes d’emprunter l’identité du client du pilote et d’obtenir les droits d’accès du client aux ressources protégées.
Activation de l'emprunt d'identité
Le package d’installation du pilote UMDF et l’application cliente doivent activer la fonctionnalité d’emprunt d’identité de l’infrastructure, comme suit :
Le fichier INF du package d’installation du pilote UMDF doit inclure la directive UmdfImpersonationLevel et définir le niveau d’emprunt d’identité maximal autorisé. L’emprunt d’identité est activé uniquement si le fichier INF inclut la directive UmdfImpersonationLevel . Pour plus d’informations sur la définition du niveau d’emprunt d’identité, consultez Spécification de directives WDF dans les fichiers INF.
L’application cliente doit définir le niveau d’emprunt d’identité autorisé pour chaque descripteur de fichier. L’application utilise les paramètres de qualité de service (QoS) dans la fonction Microsoft Win32 CreateFile pour définir le niveau d’emprunt d’identité autorisé. Pour plus d’informations sur ces paramètres, consultez le paramètre dwFlagsAndAttributes de CreateFile dans la documentation du Kit de développement logiciel (SDK) Windows.
Gestion de l’emprunt d’identité pour une demande d’E/S
Le pilote et l’infrastructure UMDF gèrent l’emprunt d’identité pour une demande d’E/S dans l’ordre suivant :
Le pilote appelle la méthode WdfRequestImpersonate pour spécifier le niveau d’emprunt d’identité requis et une fonction de rappel EvtRequestImpersonate .
L’infrastructure vérifie le niveau d’emprunt d’identité demandé. Si le niveau demandé est supérieur au niveau autorisé par le package d’installation du pilote UMDF et l’application cliente, la demande d’emprunt d’identité échoue. Sinon, le framework emprunte l’identité du client et appelle immédiatement la fonction de rappel EvtRequestImpersonate .
La fonction de rappel EvtRequestImpersonate doit effectuer uniquement les opérations qui nécessitent le niveau d’emprunt d’identité demandé, telles que l’ouverture d’un fichier protégé.
L’infrastructure n’autorise pas la fonction de rappel EvtRequestImpersonate d’un pilote à appeler l’une des méthodes d’objet de l’infrastructure. Cela garantit que le pilote n’expose pas le niveau d’emprunt d’identité à d’autres fonctions de rappel de pilote ou à d’autres pilotes.
En guise de bonne pratique, votre pilote ne doit pas activer l’annulation d’une demande d’E/S avant d’appeler WdfRequestImpersonate pour cette demande.
La méthode WdfRequestImpersonate accorde uniquement le niveau d’emprunt d’identité que le pilote demande.
Transmission des informations d’identification dans la pile des pilotes
Lorsque votre pilote reçoit une demande d’E/S de type WdfRequestTypeCreate, il peut transférer la requête d’E/S dans la pile des pilotes vers un pilote en mode noyau. Les pilotes en mode noyau n’ont pas la fonctionnalité d’emprunt d’identité que WdfRequestImpersonate fournit aux pilotes UMDF.
Par conséquent, si vous souhaitez qu’un pilote en mode noyau reçoive les informations d’identification utilisateur du client (plutôt que les informations d’identification du processus hôte du pilote), le pilote doit définir l’indicateur WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT lorsqu’il appelle WdfRequestSend pour envoyer la demande de création à la cible d’E/S. La méthode Send retourne un code d’erreur si la tentative d’emprunt d’identité échoue, sauf si le pilote définit également l’indicateur WDF_REQUEST_SEND_OPTION_IMPERSONATION_IGNORE_FAILURE .
L’exemple suivant montre comment un pilote UMDF peut utiliser l’indicateur WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT pour envoyer une demande de création de fichier à une cible d’E/S. Le fichier INF du pilote doit également inclure la directive UmdfImpersonationLevel , comme décrit ci-dessus.
WDFIOTARGET iotarget;
WDF_REQUEST_SEND_OPTIONS options;
NTSTATUS status;
WDF_REQUEST_PARAMETERS params;
ULONG sendFlags;
WDF_REQUEST_PARAMETERS_INIT(¶ms);
WdfRequestGetParameters(Request, ¶ms);
sendFlags = WDF_REQUEST_SEND_OPTION_SYNCHRONOUS;
if (params.Type == WdfRequestTypeCreate) {
sendFlags |= WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT;
}
WDF_REQUEST_SEND_OPTIONS_INIT(&options, sendFlags);
if (WdfRequestSend(Request,
iotarget,
&options
) == FALSE) {
status = WdfRequestGetStatus(Request);
}
Le pilote n’a pas besoin d’appeler WdfRequestImpersonate avant d’envoyer la demande à la cible d’E/S.
Si les pilotes de niveau inférieur transfèrent également la demande, le niveau d’emprunt d’identité du client descend dans la pile des pilotes.
Réduction des menaces de sécurité
Pour réduire le risque d’une attaque par « élévation de privilèges », vous devez :
Essayez d’éviter d’utiliser l’emprunt d’identité.
Par exemple, pour éviter d’utiliser l’emprunt d’identité pour ouvrir un fichier que le pilote doit utiliser, l’application cliente peut ouvrir le fichier et utiliser des opérations d’E/S pour envoyer le contenu du fichier au pilote.
Utilisez le niveau d’emprunt d’identité le plus bas requis par votre pilote.
Définissez le niveau d’emprunt d’identité dans le fichier INF de votre pilote aussi bas que possible. Si votre pilote ne nécessite pas d’emprunt d’identité, n’incluez pas la directive UmdfImpersonationLevel dans le fichier INF.
Réduisez les possibilités pour un attaquant d’exploiter votre pilote.
Votre fonction de rappel EvtRequestImpersonate doit contenir une petite section de code qui effectue uniquement l’opération qui nécessite l’emprunt d’identité. Par exemple, si votre pilote accède à un fichier protégé, il nécessite l’emprunt d’identité uniquement lorsqu’il ouvre le handle de fichier. Il n’est pas nécessaire d’emprunter l’identité pour lire ou écrire dans le fichier.