Version imprimable      Envoyer     
Cliquez pour évaluer et commenter
MSDN
MSDN Library
Articles Techniques
Développement .NET
Articles et Vue d'ensemble
Windows Vista
 Migrer une application vers Windows...
Migrer une application vers Windows Vista
Paru le 12 mars 2006
Par Jacques Massa, Consultant Sénior en développement d’application. Microsoft France

Avant propos

Windows Vista est le nouveau système d’exploitation développé par Microsoft. Cette dernière version du système d’exploitation offre un grand nombre de nouveautés et d’améliorations dans les domaines tels que l’interface utilisateur, la sécurité, la connectivité et bien d’autres encore que vous pourrez découvrir à l’adresse :

http://www.microsoft.com/france/windowsvista/businesses/default.mspx

Toutes ces nouveautés et améliorations, parce qu’elles modifient ou changent le comportement de certaines tâches, ont un impact sur l’utilisation et le développement des applications existantes.

Cet impact peut-être soit visuel, soit de nature à modifier la fonctionnalité de l’application. L’un des premiers impacts que les éditeurs de logiciels devront aborder concerne le contrôle de compte utilisateur (UAC).

Comme cela affecte le comportement des applications sous Windows Vista, cet article aborde le contrôle de compte utilisateur et la migration d’applications existantes.

Le contrôle de compte utilisateur(UAC)

Pourquoi le contrôle de compte utilisateur ?

Ces dernières années, un nombre important de virus et de vers a été dirigé contre les plateformes Windows. Ces attaques ont eu un impact financier pour nos clients aussi bien pour les entreprises que pour les particuliers. La confiance dans les systèmes d’exploitation Windows a été ébranlée. Il était de la responsabilité de Microsoft de répondre aux attentes légitimes de nos clients et de rétablir une informatique digne de confiance (Trustworthy Computing).

Toutes ces nouveautés et améliorations, parce qu’elles modifient ou changent le comportement de certaines tâches, ont un impact sur l’utilisation et le développement des applications existantes.

Durant le développement de Windows Vista l’amélioration de la sécurité a été omniprésente à toutes les différentes étapes de l’élaboration de la plateforme.

Il existe principalement deux types de comptes sous Windows :

  • Le compte administrateur qui possède tous les droits et privilèges pour administrer la plateforme.

  • Le compte utilisateur standard qui possède des droits et des privilèges limités.

Les administrateurs de l’informatique d’entreprise sont très intéressés par l’utilisation du compte utilisateur standard car il permet d’accroitre la sécurité et le contrôle de leur parc machine et réduit le coût total de possession(TC0) (cf étude du Gartner Security Holes Increase Windows Client).

Il est alors légitime de se poser la question : « Pourquoi ne sommes-nous pas tous utilisateurs standards sous Windows XP ? »

La majorité des applications développées requiert des droits et des privilèges excessifs. Il est très difficile, même si cela reste faisable, de ne pas être administrateur de son poste de travail !

Certaines fonctionnalités courantes de Windows nécessitent des droits administrateur pour des fonctions usuelles comme par exemple :

  • Changer le fuseau horaire

  • Se connecter à un réseau sans fil sécurisé

Les droits et les privilèges des fonctions courantes ont été complètement revus sous Windows VISTA.

D’autre part, la façon dont les éditeurs de logiciels contribuent à la sécurisation de leurs applications pour la plateforme Windows est l’un des facteurs clés. Sous Windows VISTA, le contrôle de compte utilisateur a été développé pour les aider dans cette tâche.

Le contrôle de compte utilisateur réduit la surface d’attaque contre les logiciels malveillants. Tous les utilisateurs, y compris les administrateurs, s’exécutent avec un compte limité par défaut. Ils peuvent élever sélectivement leurs privilèges lorsqu’il est nécessaire d’exécuter des tâches d’administration ou d’installation.

L’UAC dans Windows Vista.

Objectifs

Le contrôle de compte utilisateur fournit une méthode pour séparer les tâches et les privilèges de l’utilisateur standard de ceux nécessitant un accès Administrateur.

Par défaut, les administrateurs exécutent la plupart des tâches avec un privilège d’utilisateur standard. Lorsqu’ils doivent effectuer une tâche administrative, ils doivent d’abord donner leur consentement dans la fenêtre qui s’affiche alors :

Figure 1: Windows a besoin de votre autorisation pour continuer

Ils n’obtiendront des privilèges élevés que pendant la durée de vie de ce processus. Toutes les autres tâches continueront de s’exécuter en mode utilisateur standard.

Le contrôle de compte utilisateur assure:

  • Que tous les utilisateurs s’exécutent avec des privilèges standards par défaut.

  • Qu’un consentement explicite est obligatoirement requis pour une élévation de privilège.

  • Qu’un haut niveau de compatibilité est assuré pour les applications existantes.


Architecture

Figure 2 : architecture

Lorsque un administrateur se logue, Windows Vista reconnait s’il possède des privilèges élevés, et découpe alors le jeton d’accès (Token) en deux jetons :

  • Un jeton contenant les privilèges spécifiques (jeton filtré)

  • Un jeton contenant tous les privilèges (jeton complet)

Le jeton filtré est utilisé par défaut. Lorsqu’une tâche requiert des privilèges d’administrateur, Windows affiche la boite de dialogue de consentement. L’aspect de cette boite de dialogue dépendra de la présence ou non d’une signature digitale pour l’exécutable:

Figure 3 : Executable non signé Figure 4 : Executable signé

Description d’exécution d’une application pour un utilisateur standard

  • ShellExecute appelle CreateProcess().

  • CreateProcess() vérifie si l’application nécessite ou non une élévation de privilège. Si oui, l’exécutable est alors inspecté pour déterminer son requestedExecutionLevel, qui est fourni par le manifeste de l’application s’il existe.

  • CreateProcess retourne une erreur Win32 : ERROR_ELEVATION_REQUIRED

  • ShellExecute vérifie ce retour d’erreur et passe l’appel vers le service d’information des applications (AIS) qui est en charge de demander l’élévation de privilège

Description d’élévation de privilège

  • AIS reçoit l’appel de ShellExecute et réévalue le niveau d’exécution requis ainsi que les stratégies de groupes pour déterminer si l’élévation est permise.

  • Si le niveau d’exécution requiert une élévation, AIS affiche la fenêtre de consentement.

  • Dès que l’utilisateur donne son consentement, AIS retrouve le jeton complet associé au jeton filtré.

  • AIS appelle CreateProcessAsUser avec le jeton complet et crée un processus avec un niveau de privilège élevé.

Figure 5 : schéma

Le seul moyen d’élever un privilège consiste à créer un nouveau processus avec un jeton complet. Un processus existant ne peut être élevé !


Taxonomie du jeton de l’utilisateur standard

Lorsqu’un utilisateur se logue sous Windows VISTA, Windows examine les privilèges et l’appartenance aux différents groupes (RIDs) auxquels appartient l’utilisateur. Il détermine alors, s’il faut ou non créer un jeton d’accès filtré et un jeton d’accès complet.

Windows créera 2 jetons d’accès pour l’utilisateur si l’une des deux conditions est vérifiée :

1. Si le compte utilisateur contient au moins l’un des RIDs suivants :

  • DOMAIN_GROUP_RID_ADMINS

  • DOMAIN_GROUP_RID_CONTROLLERS

  • DOMAIN_GROUP_RID_CERT_ADMINS

  • DOMAIN_GROUP_RID_SCHEMA_ADMINS

  • DOMAIN_GROUP_RID_ENTERPRISE_ADMINS

  • DOMAIN_GROUP_RID_ENTERPRISE_ADMINS

  • DOMAIN_GROUP_RID_POLICY_ADMINS

  • DOMAIN_ALIAS_RID_ADMINS

  • DOMAIN_ALIAS_RID_POWER_USERS

  • DOMAIN_ALIAS_RID_ACCOUNT_OPS

  • DOMAIN_ALIAS_RID_SYSTEM_OPS

  • DOMAIN_ALIAS_RID_PRINT_OPS

  • DOMAIN_ALIAS_RID_BACKUP_OPS

  • DOMAIN_ALIAS_RID_RAS_SERVERS

  • DOMAIN_ALIAS_RID_PREW2KCOMPACCESS

  • DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS

  • DOMAIN_ALIAS_RID_CRYPTO_OPERATORS

2. Si le compte utilisateur contient n’importe quel privilège autre que ceux de l’utilisateur standard.

Les privilèges du jeton d’accès filtré dépendront de la condition qui a été vérifiée.


Si la première condition a été vérifiée, tous les privilèges Windows sont supprimés à l’exception des privilèges :

  • SeChangeNotifyPrivilege

  • SeShutdownPrivilege

  • SeUndockPrivilege

  • SeReserveProcessorPrivilege

  • SeTimeZonePrivilege


Si la deuxième condition a été vérifiée, uniquement les privilèges suivants sont supprimés :

  • SeCreateTokenPrivilege

  • SeTcbPrivilege

  • SeBackupPrivilege

  • SeDebugPrivilege

  • SeImpersonatePrivilege

  • SeRelabelPrivilege

Windows marque tous les précédents RIDs du jeton filtré comme USE_FOR_DENY_ONLY.

Le jeton filtré sera utilisé par défaut pour démarrer les applications. Le jeton complet ou non modifié sera utilisé lorsqu’une élévation de privilège sera demandée.

Le compte standard contient seulement les privilèges suivants :

  • SeChangeNotifyPrivilege

  • SeShutdownPrivilege

  • SeUndockPrivilege

  • SeIncreaseWorkingSetPrivilege

  • SeTimeZonePrivilege


La redirection

Windows VISTA apporte une nouvelle fonctionnalité afin d’améliorer la compatibilité des applications existantes. Il redirige les écritures/lectures vers certains objets systèmes. Cette redirection s’effectue par utilisateur.

La redirection ou « virtualization » comporte deux composantes :

  • la redirection de fichiers

  • la redirection de la base de registre


La redirection de fichiers

Dans le cas où une application écrit sous un des répertoires systèmes (Windows, Programmes Files\ …), cela fonctionne correctement si un administrateur avec son jeton complet exécute l’application. Par contre, cela échoue si l’utilisateur est un utilisateur standard ou protégé par le contrôle de compte utilisateur.

Windows redirige l’écriture vers un répertoire propre à l’utilisateur qui exécute l’application :

Figure 6 : Arborescence


La redirection de la base de registre

La redirection de la base de registre est identique à la redirection des fichiers sauf qu’elle s’applique à la clé HKEY_LOCAL_MACHINE\SOFTWARE.

Les écritures sont alors redirigées vers la clé HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE

Figure 7 : Editeur de registre

Les redirections de fichiers et de la base de registre ont pour seule intention d’assurer la compatibilité des applications existantes. Une application conçue pour VISTA ne devrait pas écrire de données dans ces lieux systèmes.


Comment élever le privilège

Il nous reste à comprendre comment concrètement l’utilisateur ou Windows peut effectuer une élévation de privilège.

L’utilisateur peut effectuer une élévation de privilège par l’une des opérations suivantes :

  • Un clic droit sur le nom de l’exécutable de l’application et le choix Exécuter en tant qu’administrateur:

Figure 8

  • En utilisant la propriété de compatibilité Niveau de Privilège:

Figure 9

  • L’ajout d’un fichier manifeste contenant les informations :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name="monapplication" 
                    version="1.0.0.0" 
                    processorArchitecture="X86" 
                   type="win32"/>
  <description>Mon Application</description> 
  <!-- Identify the app's security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Le fichier manifeste peut accompagner l’exécutable ou bien être hébergé dans l’exécutable. Les valeurs possibles pour requestedExecutionLevel sont :

Figure 10

Windows peut élever automatiquement le privilège au démarrage d’une application s’il détecte une application d’installation. L’icône de l’exécutable est alors décoré de la métaphore du bouclier :

Figure 11 : Bouclier

Chaque fois, que ce bouclier apparait sous VISTA, cela signifie qu’une élévation de privilège sera demandée.


Stratégies de groupe

L’activation du contrôle de compte utilisateur se gère depuis les stratégies de sécurité locale :

Figure 12

L’impact pour les applications

L’impact du contrôle de compte utilisateur pour une application existante s’évalue de la façon suivante :

  • Si une application s’exécute correctement sous Windows XP en tant qu’utilisateur standard, alors il n’y a aucun impact.

  • Si une application nécessite des privilèges administrateur, il faudra ajouter un fichier manifeste avec le niveau requis : Administrateur.

  • Si une application est soumise à la redirection et que celle-ci change le comportement de l’application, alors il faudra :

    • Soit modifier le code afin d’écrire les données au bon endroit ! (par exemple le répertoire c:\users\public)

    • Soit ajouter un fichier manifeste avec le niveau requis : Administrateur.


Dans certain cas, une application ne requiert que ponctuellement des privilèges administrateur. On dispose alors, des choix suivants :

  • Relancer l’application avec un niveau de privilège administrateur.

  • Séparer le code nécessitant les privilèges administrateur du reste de l’application et l’exécuter dans un processus séparer.


La séparation de code, implique une revue d’architecture et le choix du processus pour héberger le code administrateur. On dispose de 3 « Design Patterns » :

1. Service Broker

  • Communication interprocessus à base de Remote Procedure Call (RPC)

2. Side by Side processes

  • Communication interprocessus à base de RPC ou de SharedMemory

3. Administrator COM Object

  • Communication interprocessus à base de COM.

Migration d’une application existante

Cette section propose une méthode pour migrer une application impactée par la redirection et la nécessité d’un privilège élevé.

Elle met en œuvre la séparation du code administrateur et la signature digitale de l’application et de l’installation.


Présentation d’un exemple

Prenons une application qui écrit dans la base de registre sous la clé :

HKLM\Software\UACDEMO et donc implique la redirection.

// Try to open HKLM\Software in write access
HKEY hkey;
DWORD err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\UACDEMO"),0,0,0,KEY_SET_VALUE,0, &hkey,0);
if (err == ERROR_SUCCESS)
{
	SYSTEMTIME now;
	::GetLocalTime(&now);
	DWORD errSet = RegSetValueEx(hkey, _T("LastRun"), 0, REG_BINARY, (BYTE*)&now, sizeof now);
	*perr=errSet;
	RegCloseKey(hkey);
}
else
{
	*perr=err;
}
				  
				

De plus, cette application énumère la liste des tâches planifiées et donc implique des droits administrateur.

// Try to enum Schedule Jobs
const int MAX_JOBS = 10; // this sample app shows at most 10 jobs
AT_ENUM* jobInfo = new AT_ENUM[MAX_JOBS];
DWORD numRead, hint;
// This call requires admin privileges!
NET_API_STATUS status = NetScheduleJobEnum(0, (BYTE**)&jobInfo, MAX_PREFERRED_LENGTH, &numRead,&hint, 0);
*perr=status;
if (NERR_Success == status) 
{
	NetApiBufferFree(jobInfo);
}				  
				  

Pour éliminer l’effet de la redirection de la base de registre, on commence d’abord par ajouter un fichier manifeste hébergé dans l’exécutable. Pour cela, il suffit de l’ajouter au projet Visual Studio 2005 qui le reconnait automatiquement.

Figure 13

Figure 14

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly> 

On ne demande que le niveau asInvoker. Par conséquent, l’écriture dans la clé HKLM/Software échouera en mode standard.

Figure 15

On ne souhaite pas que toute l’application s’exécute avec un niveau de privilège élevé.

Le code qui accède à la base de registre pour la clé HKLM/Software et le code qui utilise la fonction NetScheduleJobEnum sera séparé et hébergé dans un composant COM DLL.


L’élévation de privilège.

Le simple fait de séparer le code dans un composant COM ne résout en rien le problème car le composant COM DLL sera dans le même processus que l’application.

Il doit donc s’exécuter dans un autre processus via le mécanisme, par exemple, de DLLSurrogate.

Pour cela on ajoute un APPID et une clé DLLSurrogate= ‘’ ‘’ dans le fichier rgs du composant :

'%APPID%' = s 'CanElevate'
{
  val DLLSurrogate = s ''
}				  
				  

Mais cela ne suffit toujours pas, car il faut que ce processus s’exécute avec des privilèges élevés. Pour résoudre ce problème, on doit utiliser le nouveau Moniker fourni avec Windows VISTA :
Elevation:Administrator

Au lieu d’utiliser la fonction CoCreateInstance, on utilise alors le code suivant :

HRESULT CoCreateInstanceAsAdmin( REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
    BIND_OPTS3 bo;
    WCHAR  wszCLSID[50];
    WCHAR  wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
	HRESULT hr = ::StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), 
		_T("Elevation:Administrator!new:%s"), wszCLSID);
    if (FAILED(hr))
        return hr;
    memset(&bo, 0, sizeof(bo));
    bo.cbStruct = sizeof(bo);
    bo.hwnd = NULL;
    bo.dwClassContext  = CLSCTX_LOCAL_SERVER;
    return CoGetObject(wszMonikerName, &bo, riid, ppv);
}
			

Et pour créer l’ instance de l’objet, il suffit d’utiliser l’appel:

hr=::CoCreateInstanceAsAdmin(CLSID_CanElevateWorker,
	__uuidof(pWorker),
	(LPVOID*)&pWorker);			
			

Cependant, ce moniker impose quelques règles :

  • Il faut ajouter une clé Elevation dans l’enregistrement de l’objet, cela s’effectue aisément depuis le fichier rgs correspondant à l’objet :

Elevation
{
	val Enabled = d 1
}
  • Il faut aussi ajouter une clé définissant le message localisé à afficher dans la boite de dialogue de consentement :

val LocalizedString = s '@%MODULE%,-101'

La variable 101 est définie dans les ressources du composant COM :

Figure 16

En utilisant la fonction CoCreateInstanceAsAdmin () la fenêtre de consentement suivante s’affiche :

Figure 17

L’objet COM s’exécute dans le processus DLLSurrogate avec des privilèges élevés alors que l’application qui consomme l’objet COM utilise des privilèges limités.

Figure 18


Signature de l’application et de l’installation.

Lors de l’élévation de privilège, la fenêtre de consentement ne reconnait pas l’éditeur. Pour résoudre ce problème et parce que les stratégies de groupe peuvent interdire l’exécution de ce type d’application il faut que le composant COM soit signé.

La méthode à utiliser est Authenticode. (Voir http://www.microsoft.com/whdc/winlogo/drvsign/best_practices.mspx)

Un éditeur obtient son certificat et sa clé privée depuis une autorité de certification reconnue comme Verisign ou Thawte.

Pour l’exemple, on se contente d’un certificat de test produit à partir des outils de Windows VISTA SDK.

Création d’un certificat de test
Makecert -r -pe -sr localMachine -ss Test -n "CN=Jacques Massa – Microsoft France" democert.cer
Ajout du certificat sur la machine à la racine
Certmgr -add democert.cer -s -r localMachine Root
			

Pour signer automatiquement le composant COM depuis Visual Studio il suffit d’ajouter un événement après génération dans les propriétés du projet:

Signtool Sign /v /s Test /n "Jacques Massa - Microsoft France"  "$(TargetDir)$(TargetFileName)"
			

La fenêtre de consentement devient alors :

Figure 19

De la même façon, on signe aussi l’application (pour le cas où l’utilisateur déciderait de l’exécuter en tant qu’administrateur).

Figure 20

Pour l’installation, la signature est nécessaire afin d’identifier l’éditeur et assurer l’origine et l’intégrité des fichiers.

Il suffit d’ajouter au projet d’installation un événement après génération pour signer le fichier setup.exe et le fichier msi :

Figure 21

"C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\signtool.exe" Sign /v /s TEST /n 
"Jacques Massa - Microsoft France"  "$(BuiltOuputPath)" "$(ProjectDir)$(Configuration)\setup.exe"


En résumé

La méthode exposée permet de séparer le code nécessitant des privilèges administrateur du code de l’application. L’application peut continuer à s’exécuter avec des privilèges standards et ponctuellement demander des privilèges administrateur. Le nouveau mécanisme de moniker COM permet d’élever le processus hébergeant le composant. La surface d’attaque de l’application par les logiciels malveillants reste réduite. On participe ainsi à la sécurisation de Windows.

Conclusion

Avec pour objectif de réduire la surface d’attaque par les logiciels malveillants, Windows VISTA met en œuvre des mécanismes de sécurisation par défaut, à l’exécution et lors du déploiement. Le contrôle de compte utilisateur participe à rendre VISTA digne de confiance. Pour cela, des modifications ont été effectuées au niveau de VISTA et de l’interface utilisateur.

Dans certain cas, les éditeurs de logiciels pour Windows VISTA seront appelés à effectuer des changements plus ou moins importants dans leurs applications. La méthode exposée ici, permet de répondre à un scénario d’une application nécessitant ponctuellement des privilèges administrateur. L’application continue toutefois de s’exécuter avec des privilèges limités.

Afin d’assurer la compatibilité avec les applications existantes, la redirection de fichiers et de la base de registre est disponible par défaut. Il faut cependant être vigilant car elle réduit les fonctionnalités par utilisateur. Ce mécanisme, pourrait disparaitre dans les prochaines versions de Windows.

La signature digitale des applications et des fichiers d’installation permet d’identifier l’origine des fichiers et d’assurer leur intégrité pour l’utilisateur et les administrateurs. C’est une pratique que les éditeurs devraient adopter pour leurs applications VISTA.

Téléchargez

Sources

ElevatedPrivilege-AutoCodeSigning.zip
127 Ko
Dernière mise à jour le 06 mars 2007

© 2008 Microsoft Corporation. Tous droits réservés. Conditions d'utilisation  |  Marques  |  Confidentialité
Page view tracker