I. Introduction▲
Le système Microsoft Windows est doté d'un sous-système d'audit puissant, mais ce sous-système est rarement utilisé par méconnaissance de son existence et aussi par ignorance des fonctionnalités qu'il peut offrir. Le sous-système d'audit permet de mettre en place une véritable politique d'audit et en plus, il peut s'avérer une aide inestimable pour le débogage et le suivi de certaines applications orientées « système ».
Cet article est organisé comme suit :
- le paragraphe 2 présente la mise en place d'une politique d'audit et les différents paramètres d'audit dans les environnements Microsoft Windows ;
- le paragraphe 3 présente la mise en place des paramètres d'audit en ce qui concerne les répertoires, les fichiers et les clés de la base de registre ;
- le paragraphe 4 présente les journaux générés par les événements d'audit et les outils disponibles pour lire ces événements ;
- le paragraphe 5 présente l'API de programmation pour tout ce qui concerne la gestion de l'audit ;
- le paragraphe 6 présente un programme d'exemple écrit en C manipulant les fonctions de l'API de programmation de gestion de l'audit ;
- et enfin, le paragraphe 7 se propose de conclure cet article.
II. La mise en place d'une politique d'audit▲
II-A. Définition de la politique d'audit▲
La mise en place d'une politique d'audit doit commencer obligatoirement par la spécification de cette politique.
Cette spécification consiste à définir en termes simples, dans un langage courant, le besoin, c'est-à-dire ce que l'on veut auditer, et surtout pourquoi on veut l'auditer. Si le « pourquoi » est flou, c'est que le « besoin » n'est pas clair et qu'il convient de l'affiner.
Un deuxième besoin consiste à spécifier le périmètre de la politique d'audit. Il y a probablement des serveurs ou des services qui auront une politique différente. En effet, le serveur de gestion de la paye n'a pas du tout les mêmes contraintes que le serveur de sauvegarde de l'équipe de développement.
Ce besoin peut être par exemple :
- je veux savoir si des personnes se connectent la nuit sur mon système d'informations alors que normalement, les locaux sont fermés ;
- ce fichier est stratégique pour mon entreprise, car il contient la liste de mes clients et je veux savoir qui y accède en lecture et qui le modifie ;
- je développe une application et je voudrai savoir pourquoi elle n'arrive pas à modifier l'heure du système alors que tout semble correct au niveau du code.
Une fois que la politique d'audit est définie, il convient de l'implémenter avec les moyens mis à disposition par le système d'exploitation.
II-B. Les paramètres d'audit▲
Les 9 paramètres d'audit connus par Windows sont identifiés dans le tableau suivant. Ce tableau contient 3 colonnes :
- la colonne 1 « Description » est une description rapide du paramètre d'audit ;
- la colonne 2 « Explication » contient des informations plus détaillées sur ce paramètre d'audit ;
- la colonne 3 « Valeur par défaut » enfin donne les valeurs par défaut du paramètre d'audit (« Réussite », « Échec » ou « Aucune »). Certaines valeurs peuvent être différentes suivant que la machine est une station de travail (identifiées par WKS), un serveur (identifiées par SRV) ou un contrôleur de domaine (identifiées par DC).
Description |
Explication |
Valeur par défaut |
---|---|---|
Auditer la gestion des comptes |
Ce paramètre de sécurité détermine s'il convient d'auditer chaque événement de gestion des comptes sur un ordinateur. Exemples d'événements de gestion des comptes : |
DC : Réussite. |
Auditer l'accès au service d'annuaire |
Ce paramètre de stratégie détermine s'il convient d'auditer l'événement d'un accès utilisateur à un objet Active Directory dont la propre liste de contrôle d'accès système (SACL) est spécifiée. |
DC : Réussite. |
Auditer l'accès aux objets |
Ce paramètre de sécurité détermine s'il convient d'auditer l'événement d'accès à un objet par un utilisateur, par exemple, un fichier, un dossier, une clé de Registre, une imprimante, etc., dont la propre liste de contrôle d'accès système (SACL) est spécifiée. |
Aucune. |
Auditer le suivi des processus |
Ce paramètre de sécurité détermine s'il convient d'auditer les informations de suivi détaillé pour des événements tels que l'activation d'un programme, la fin d'un processus, la duplication d'un descripteur et l'accès indirect à un objet. |
Aucune. |
Auditer les événements de connexion |
Ce paramètre de sécurité détermine s'il convient d'auditer chaque instance d'une ouverture ou d'une fermeture de session par un utilisateur sur un ordinateur. |
Réussite. |
Auditer les événements de connexion aux comptes |
Ce paramètre de stratégie détermine s'il convient d'auditer chaque instance d'ouverture ou de fermeture de session sur un autre ordinateur dans laquelle cet ordinateur est utilisé pour valider le compte. Des événements d'ouverture de session de compte sont générés lorsqu'un compte d'utilisateur de domaine est authentifié sur un contrôleur de domaine. L'événement est enregistré dans le journal de sécurité du contrôleur de domaine. Des événements d'ouverture de session sont générés lorsqu'un utilisateur local est authentifié sur un ordinateur local. L'événement est enregistré dans le journal de sécurité local. Aucun événement de fermeture de session de compte n'est généré. |
Réussite. |
Auditer les événements du système |
Ce paramètre de sécurité détermine s'il convient d'auditer lorsqu'un utilisateur redémarre ou arrête l'ordinateur ou lorsqu'un l'événement qui se produit affecte la sécurité du système ou le journal de sécurité. |
DC : Réussite. |
Auditer les modifications de stratégie |
Ce paramètre de stratégie détermine s'il convient d'auditer chaque incident d'une modification aux stratégies d'affectation de droits de l'utilisateur, aux stratégies d'audit ou aux stratégies d'approbation. |
DC : Réussite. |
Auditer l'utilisation des privilèges |
Ce paramètre de sécurité détermine s'il convient d'auditer chaque instance d'un utilisateur exerçant un droit de l'utilisateur. |
Aucune. |
Vous avez des précisions à apporter au sujet de ces paramètres, un lien ou une traduction concernant leurs descriptions, n'hésitez pas à les signaler dans la discussion dédiée (2 commentaires), cet article sera mis à jour.
II-C. La modification des paramètres d'audit▲
La gestion des paramètres d'audit se fait à l'aide d'un plug-in lancé par une MMC (Microsoft Management Console) se trouvant dans le panneau de configuration, dans les outils d'administration et qui s'appelle « Stratégie de sécurité locale » (du moins sur un système Windows Seven Professionnel français).
Ce plug-in peut aussi être lancé directement par la ligne de commande suivante : « %windir%\system32\secpol.msc /s ».
Cette copie d'écran montre clairement que certains paramètres d'audit (« Auditer la gestion des comptes » par exemple) ont été mis à jour par une stratégie de groupe du domaine (GPO ou Group Policy Object).
Il semble que ce plug-in n'existe pas par défaut sur les versions familiales de Microsoft Windows.
La gestion des paramètres de l'audit se trouve dans la section « Stratégies locales » / « Stratégie d'audit » de la partie gauche de l'arbre.
Il est possible de modifier les valeurs des différents paramètres d'audit. Pour cela, il suffit de sélectionner un des paramètres affichés et ensuite, de faire un clic droit et de sélectionner l'option « Propriétés ».
III. Le paramètre d'audit « Auditer l'accès aux objets »▲
Parmi les neuf paramètres de l'audit, il y en a huit qui sont binaires. Il ne nécessitent pas de réglages supplémentaires, ils sont activés ou désactivés.
Par contre, le paramètre d'audit « Auditer l'accès aux objets », nécessite des réglages supplémentaires, il faut spécifier sur quels objets portera cet audit.
Ceci se fait à l'aide de l'explorer Windows dans la fenêtre « Sécurité » en cliquant sur le bouton « Paramètres avancés ».
Ce bouton ouvre une fenêtre qui permet de spécifier les autorisations de ce fichier ou répertoire, mais il y a aussi un onglet qui permet de spécifier les paramètres d'audit de ce fichier ou répertoire.
Cette copie d'écran montre que l'audit du répertoire c:\temp et ses descendants pour tous les accès (« Contrôle total ») a été activé pour l'utilisateur « Guest » de la machine locale.
Le réglage de l'audit pour certaines valeurs ou branches de la base de registre se fait de la même manière avec l'outil « regedit.exe ».
Cette copie d'écran montre que l'audit de la clé HKEY_CURRENT_USER et ses descendants pour tous les accès (« Contrôle total ») a été activé pour l'utilisateur « Guest » de la machine locale.
IV. Le suivi de la politique d'audit▲
Une fois que la stratégie d'audit a été mise en place sur la machine, il ne reste plus qu'à analyser les journaux générés par cet audit.
Cette tâche est souvent sous-estimée. En effet, elle nécessite un travail récurrent d'analyse sinon, l'audit ne sert strictement à rien (mis à par remplir le disque).
IV-A. Le journal d'audit▲
Les journaux de l'audit sont gérés par le sous-système Microsoft « EventLog ». Je vous encourage à consulter ce tutoriel La journalisation dans le monde Microsoft, découvrez l'API EventLog pour plus d'informations au sujet de ce sous-système.
Les événements d'audit sont archivés dans le journal « Security ». Ce journal est consultable avec le programme « EventViewer » accessible à partir du panneau de configuration dans les outils systèmes ou bien en tapant la commande « eventvwr » dans le menu « Démarrer / Exécuter » de Windows.
IV-B. Les événements d'audit▲
Les textes des différents messages d'audit se trouvent dans la DLL MSAuditE.dll.
- Sur un système Windows XP Professional SP3, cette DLL définit 165 messages dont les identifiants varient entre 512 et 801.
- Sur un système Windows Seven Professional, cette DLL définit 309 messages dont les identifiants varient entre 512 et 1031.
Cette évolution du nombre de messages entre Windows XP et Windows Seven montre bien que Microsoft continue à travailler et à enrichir le sous-système d'audit.
La liste complète des messages peut être visualisée avec l'utilitaire EventLogDump (à lancer en tant qu'administrateur).
V. L'API de gestion de l'audit▲
La gestion de l'audit se fait avec les fonctions suivantes :
Computes the effective audit policy for one or more subcategories for the specified security principal. The function computes effective audit policy by combining system audit policy with per-user policy. |
|
---|---|
Computes the effective audit policy for one or more subcategories for the security principal associated with the specified token. The function computes effective audit policy by combining system audit policy with per-user policy. |
|
Enumerates the available audit-policy categories. |
|
Enumerates users for whom per-user auditing policy is specified. |
|
Enumerates the available audit-policy subcategories. |
|
Frees the memory allocated by audit functions for the specified buffer. |
|
Retrieves a GUID structure that represents the specified audit-policy category. |
|
Retrieves an element of the POLICY_AUDIT_EVENT_TYPE enumeration that represents the specified audit-policy category. |
|
Retrieves the display name of the specified audit-policy category. |
|
Retrieves the display name of the specified audit-policy subcategory. |
|
Retrieves per-user audit policy in one or more audit-policy subcategories for the specified principal. |
|
Retrieves system audit policy for one or more audit-policy subcategories. |
|
Sets per-user audit policy in one or more audit subcategories for the specified principal. |
|
Sets system audit policy for one or more audit-policy subcategories. |
|
The following constants represent categories of audit-policy events. These constants are defined as GUID (Global Unique IDentifier) structures in Ntsecapi.h. |
Toutes ces fonctions sont disponibles uniquement à partir de la version Windows Vista pour les stations de travail et de la version Windows 2008 pour les serveurs.
VI. Programme d'exemple▲
VI-A. But du programme▲
Le programme présenté dans cet article est relativement simple, il se propose :
- d'afficher les différentes catégories d'audit ;
- pour chacune des catégories trouvées, il affiche les sous-catégories d'audit ;
- pour chacune des sous-catégories, il affiche son état de configuration (Success ou Failure).
Comme ce programme utilise la fonction AuditQuerySystemPolicy(), il est nécessaire que l'utilisateur dispose du privilège SE_SECURITY_NAME. Ce privilège n'est pas attribué par défaut aux utilisateurs standards, il faut donc exécuter ce programme avec les privilèges d'administrateur (Exécuter en tant que Administrateur). Pour plus d'informations au sujet des privilèges, consulter l'article Présentation des privilèges d'exécution dans l'environnement Microsoft Windows.
Afin de montrer autre chose que la configuration par défaut, l'audit (Success et Failure) a été activé sur les éléments d'audit « Auditer les événements de connexion aux comptes » et « Audit la gestion des comptes ».
VI-B. Environnement de développement▲
Le programme de test a été développé avec l'environnement suivant :
- Microsoft Windows Seven Profesionnel avec tous les correctifs de sécurité appliqués au jour de la rédaction de l'article (15 septembre 2009) ;
- Visual Studio 2005 ;
- programme en mode console compilé en Unicode ;
- la gestion des erreurs est ultrasimpliste ;
- le programme est écrit volontairement en C afin que d'autres langages puissent utiliser les idées développées dans ce code.
Pour les plus impatients, le binaire peut être téléchargé ici et le projet complet (au format Visual Studio 2005) peut être téléchargé ici.
Si une erreur se produit lors du lancement du programme Audit.exe, il faut installer les redistribuables VS 2005. Ce setup peut être téléchargé ici.
VI-C. Les fonctions utilisées▲
Ce paragraphe liste les fonctions spécifiques à la gestion de l'audit Microsoft et utilisées par le programme de démonstration :
- la fonction AuditEnumerateCategories() permet d'obtenir la liste des GUID (Global Unique IDentifier) des catégories principales d'audit ;
- la fonction AuditLookupCategoryName() permet d'obtenir le nom d'une catégorie principale d'audit dont on fournit le GUID ;
- la fonction AuditFree() permet de libérer un bloc de mémoire alloué par les différentes fonctions de gestion de l'audit. Il est impératif d'utiliser cette fonction et pas une autre ;
- la fonction AuditEnumerateSubCategories() permet d'obtenir la liste des GUID des sous-catégories d'audit dont la catégorie principale est donnée en paramètre ;
- la fonction AuditLookupSubCategoryName() permet d'obtenir le nom d'une sous-catégorie d'audit dont on fournit le GUID ;
- la fonction AuditQuerySystemPolicy() permet d'obtenir la configuration de l'audit pour une sous-catégorie d'audit dont on fournit le GUID.
VI-D. Le résultat généré▲
Le résultat de l'exécution de la version Release du programme de démonstration sur un poste Windows Seven professionnel produit le résultat suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
D:\Raymond\Developpement\Test\Audit\Release>Audit.exe
Catégorie = Système
Modification de l'état de la sécurité (Success)
Extension système de sécurité
Intégrité du système (Success, Failure)
Pilote IPSEC
Autres événements système (Success, Failure)
Catégorie = Ouverture/Fermeture de session
Ouvrir la session (Success)
Fermer la session (Success)
Verrouillage du compte (Success)
Mode principal IPsec
Mode rapide IPsec
Mode étendu IPsec
Ouverture de session spéciale (Success)
Autres événements d'ouverture/fermeture de session
Serveur NPS (Success, Failure)
Catégorie = Accès aux objets
Système de fichiers
Registre
Objet de noyau
SAM
Services de certification
Généré par application
Manipulation de handle
Partage de fichiers
Rejet de paquet par la plateforme de filtrage
Connexion de la plateforme de filtrage
Autres événements d'accès à l'objet
Partage de fichiers détaillé
Catégorie = Utilisation de privilège
Utilisation de privilèges sensibles
Utilisation de privilèges non sensibles
Autres événements d'utilisation de privilèges
Catégorie = Suivi détaillé
Création du processus
Fin du processus
Activité DPAPI
Événements RPC
Catégorie = Changement de stratégie
Modification de la stratégie d'audit (Success)
Modification de la stratégie d'authentification (Success)
Modification de la stratégie d'autorisation
Modification de la stratégie de niveau règle MPSSVC
Modification de la stratégie de plateforme de filtrage
Autres événements de modification de stratégie
Catégorie = Gestion des comptes
Gestion des comptes d'utilisateur (Success, Failure)
Gestion des comptes d'ordinateur (Success, Failure)
Gestion des groupes de sécurité (Success, Failure)
Gestion des groupes de distribution (Success, Failure)
Gestion des groupes d'applications (Success, Failure)
Autres événements de gestion des comptes (Success, Failure)
Catégorie = Accès DS
Accès au service d'annuaire
Modification du service d'annuaire
Réplication du service d'annuaire
Réplication du service d'annuaire détaillé
Catégorie = Connexion de compte
Validation des informations d'identification (Success, Failure)
Opérations de ticket du service Kerberos (Success, Failure)
Autres événements d'ouverture de session (Success, Failure)
Service d'authentification Kerberos (Success, Failure)
D:\Raymond\Developpement\Test\Audit\Release>
VI-E. Le code du programme▲
Le code du programme de démonstration est le suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <tchar.h>
#include <locale.h>
#include <stdio.h>
#include <windows.h>
#include <Ntsecapi.h>
static
void
DisplayError
(
LPCTSTR message);
static
void
EnumerateCategories
(
void
);
static
void
EnumerateSubCategories
(
const
GUID *
Guid);
static
void
PrintStatus
(
const
GUID *
SubCategoryGuid);
int
_tmain
(
)
{
_tsetlocale
(
LC_ALL, _T
(
""
));
EnumerateCategories
(
);
return
0
;
}
static
void
DisplayError
(
LPCTSTR message)
{
LPTSTR buffer =
NULL
;
if
(
message ==
NULL
)
message =
_T
(
"
Error
"
);
if
(
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL
, GetLastError
(
), 0
, (
LPTSTR)&
buffer, 0
, NULL
) ==
0
)
{
if
(
GetLastError
(
) ==
ERROR_NOT_ENOUGH_MEMORY)
_tprintf
(
_T
(
"
%s : not enough memory
\n
"
), message);
else
_tprintf
(
_T
(
"
FormatMessage() failed : %lu
\n
"
), GetLastError
(
));
}
else
{
_tprintf
(
_T
(
"
%s : %s
"
), message, buffer);
LocalFree
(
buffer);
buffer =
NULL
;
}
}
static
void
EnumerateCategories
(
void
)
{
GUID *
Tbl;
DWORD Size;
BOOL ret;
DWORD boucle;
ret =
AuditEnumerateCategories
(&
Tbl, &
Size);
if
(
ret ==
FALSE)
{
DisplayError
(
_T
(
"
Erreur AuditEnumerateCategories()
"
));
return
;
}
for
(
boucle =
0
; boucle !=
Size; boucle++
)
{
LPTSTR Str;
/* display category name */
ret =
AuditLookupCategoryName
(&
Tbl[boucle], &
Str);
if
(
ret ==
FALSE)
{
DisplayError
(
_T
(
"
Erreur AuditLookupCategoryName()
"
));
return
;
}
_tprintf
(
_T
(
"
Catégorie = %s
\n
"
), Str);
AuditFree
(
Str);
/* display sub categories */
EnumerateSubCategories
(&
Tbl[boucle]);
}
AuditFree
(
Tbl);
}
static
void
EnumerateSubCategories
(
const
GUID *
Guid)
{
GUID *
SubTbl;
DWORD SubSize;
DWORD boucle2;
BOOL ret;
LPTSTR Str;
/* get sub categories */
ret =
AuditEnumerateSubCategories
(
Guid, FALSE, &
SubTbl, &
SubSize);
if
(
ret ==
FALSE)
{
DisplayError
(
_T
(
"
Erreur AuditEnumerateSubCategories()
"
));
return
;
}
for
(
boucle2 =
0
; boucle2 !=
SubSize; boucle2++
)
{
ret =
AuditLookupSubCategoryName
(&
SubTbl[boucle2], &
Str);
if
(
ret ==
FALSE)
{
DisplayError
(
_T
(
"
Erreur AuditLookupSubCategoryName()
"
));
return
;
}
_tprintf
(
L"
\t
%s
"
, Str);
AuditFree
(
Str);
PrintStatus
(&
SubTbl[boucle2]);
}
AuditFree
(
SubTbl);
}
static
void
PrintStatus
(
const
GUID *
SubCategoryGuid)
{
BOOL ret;
AUDIT_POLICY_INFORMATION *
p_information;
BOOL at_least_one =
FALSE;
ret =
AuditQuerySystemPolicy
(
SubCategoryGuid, 1
, &
p_information);
if
(
ret ==
FALSE)
{
DisplayError
(
_T
(
"
Erreur AuditQuerySystemPolicy()
"
));
return
;
}
if
(
(
p_information->
AuditingInformation &
POLICY_AUDIT_EVENT_SUCCESS) ==
POLICY_AUDIT_EVENT_SUCCESS)
{
if
(
at_least_one ==
FALSE)
{
at_least_one =
TRUE;
_tprintf
(
_T
(
"
(
"
));
}
else
{
_tprintf
(
_T
(
"
,
"
));
}
_tprintf
(
_T
(
"
Success
"
));
}
if
(
(
p_information->
AuditingInformation &
POLICY_AUDIT_EVENT_FAILURE) ==
POLICY_AUDIT_EVENT_FAILURE)
{
if
(
at_least_one ==
FALSE)
{
at_least_one =
TRUE;
_tprintf
(
_T
(
"
(
"
));
}
else
{
_tprintf
(
_T
(
"
,
"
));
}
_tprintf
(
_T
(
"
Failure
"
));
}
if
(
(
p_information->
AuditingInformation &
POLICY_AUDIT_EVENT_NONE) ==
POLICY_AUDIT_EVENT_NONE)
{
if
(
at_least_one ==
FALSE)
{
at_least_one =
TRUE;
_tprintf
(
_T
(
"
(
"
));
}
else
{
_tprintf
(
_T
(
"
,
"
));
}
_tprintf
(
_T
(
"
None
"
));
}
if
(
at_least_one ==
TRUE)
{
_tprintf
(
_T
(
"
)
"
));
}
_tprintf
(
_T
(
"
\n
"
));
AuditFree
(
p_information);
}
VII. Conclusions▲
La rédaction de cet article a été, pour moi, l'occasion d'une double surprise :
- j'ai découvert l'existence des sous-catégories d'audit que je ne soupçonnais même pas (je connaissais uniquement les catégories d'audit). Il faut dire que l'outil Microsoft de gestion de l'audit (secpol.msc) ne semble pas non plus les gérer (du moins extérieurement) ;
- l'autre surprise a été de découvrir que l'API de gestion de l'audit n'est publique, officielle et documentée que depuis les versions Vista (pour les stations de travail) et 2008 (pour les serveurs) de Microsoft. Avant, cette API devait probablement exister, mais pas de manière « officielle » (j'ai souvenir de l'outil secpol.msc sur machine NT4).
Ce rapide tour d'horizon concernant les capacités d'audit dans l'environnement Microsoft est terminé. Maintenant, c'est à vous de jouer. N'hésitez pas à commenter cet article ou à apporter des précisions dans la discussion prévue à cet effet : 2 commentaires
VII-A. Remerciements▲
Je tiens à remercier Mahefasoa pour ses conseils avisés lors de la relecture de cet article.