Audit GPResult — Utilisateur actif

Paquet WAPT d'audit des GPO et des groupes de sécurité de l'utilisateur actif. Le résultat structuré est enregistré dans audit-gpresult.user-gpo.

Fonctionnement

  1. install() ne réalise aucune action.

  2. audit() appelle quser.exe avec un délai maximal de 30 secondes. Le script retient le premier utilisateur dont la ligne contient l'état Active ou Actif.

  3. Si aucun utilisateur n'est détecté, il enregistre NO_USER et retourne OK à WAPT.

  4. Sinon, il supprime un éventuel rapport précédent et lance GPResult avec un délai maximal de 120 secondes :

    gpresult.exe /USER "<utilisateur détecté>" /SCOPE USER /X "<rapport.xml>" /F
    
  5. Il analyse UserResults, extrait l'identité du compte, classe les GPO et les groupes de sécurité.

  6. Il transmet un dictionnaire à WAPT.write_audit_data_if_changed, avec keep_days=365 et max_count=1.

  7. La suppression du rapport temporaire est tentée dans finally, après succès comme après erreur.

Le chemin de GPResult est construit avec makepath(system32(), "gpresult.exe"). L'audit s'exécute dans le contexte de l'agent WAPT et cible explicitement le RSoP utilisateur. Il n'utilise pas session_setup(), ne lance pas de gpupdate et ne modifie pas les stratégies.

Prérequis et sélection de la session

  • Poste Windows disposant de quser.exe, de GPResult et de données RSoP accessibles pour l'utilisateur ciblé.
  • Agent WAPT fournissant setuphelpers et WAPT.write_audit_data_if_changed.
  • Droits suffisants pour consulter les sessions et les données RSoP, ainsi que pour écrire dans le répertoire temporaire.

La détection utilise la sortie texte de quser, et non les API WTS ou win32ts. Seuls les libellés Active et Actif sont reconnus. Les sessions déconnectées sont ignorées. Si plusieurs utilisateurs sont actifs, le premier reconnu dans la sortie est sélectionné ; aucun contrôle d'unicité n'est effectué.

Seul le nom d'utilisateur détecté est transmis à /USER. Le script lit ensuite le premier texte Name de UserResults comme identité RSoP, avec repli sur le nom détecté si ce champ est absent. Sur un poste comportant des comptes homonymes, vérifier l'identité effectivement remontée.

Une erreur de quser, une sortie vide ou un format non reconnu aboutit aussi à NO_USER. Consulter le journal pour distinguer une erreur de détection d'une absence réelle de session. Une session active, locale ou de domaine, ne garantit pas que ses données RSoP soient disponibles.

Données produites

Catégorie : audit-gpresult ; clé : user-gpo.

Exemple illustratif d'un résultat de succès :

{
  "status": "OK",
  "user": {
    "account": "EXEMPLE\\utilisateur",
    "username": "utilisateur",
    "account_domain": "EXEMPLE",
    "account_type": "domain"
  },
  "summary": {
    "applied_gpo_count": 1,
    "denied_gpo_count": 1,
    "total_gpo_count": 2,
    "domain_group_count": 1,
    "local_group_count": 1,
    "system_group_count": 1,
    "other_group_count": 0
  },
  "applied_gpos": ["GPO Utilisateurs"],
  "denied_gpos": ["GPO non appliquee"],
  "domain_groups": ["EXEMPLE\\Domain Users"],
  "security_groups": {
    "domain": ["EXEMPLE\\Domain Users"],
    "local": ["BUILTIN\\Users"],
    "system": ["NT AUTHORITY\\INTERACTIVE"],
    "other": []
  }
}
Champ Signification
status État de la collecte ; ce n'est pas un verdict de conformité.
user.account Identité lue dans le RSoP, ou nom détecté si elle est absente.
user.username Partie du compte après le premier \, ou compte entier sans préfixe.
user.account_domain Préfixe du compte, généralement NetBIOS pour un domaine ou nom du poste pour un compte local ; vide sans préfixe.
user.account_type local si le préfixe est vide ou égal au nom du poste ; domain sinon.
summary.applied_gpo_count / summary.denied_gpo_count Nombre de GPO retenues dans chaque liste.
summary.total_gpo_count Somme des deux compteurs de GPO.
summary.domain_group_count / summary.local_group_count / summary.system_group_count / summary.other_group_count Nombre de groupes retenus dans chaque catégorie.
applied_gpos / denied_gpos Noms des GPO, dans l'ordre de collecte.
domain_groups Même liste que security_groups.domain, pour faciliter le reporting.
security_groups Groupes répartis entre domain, local, system et other.

La recherche de texte est récursive et ignore les namespaces XML. Le type de compte est déduit du préfixe ; il n'est pas validé par une requête AD.

Évolution du schéma

Les consommateurs de l'ancien résultat doivent utiliser user.username à la place de user.name et user.account_domain à la place de user.domain. Le résultat actuel ne contient plus de bloc computer. user.account_type, les listes de groupes et leurs compteurs sont ajoutés.

Classement des GPO

Une GPO est appliquée si Enabled, IsValid et FilterAllowed sont vrais et si AccessDenied est faux. Toutes les autres entrées retenues vont dans denied_gpos : cette liste couvre les GPO non appliquées, y compris les GPO filtrées, désactivées ou invalides.

Les valeurs true, 1, yes et oui, sans distinction de casse, sont vraies. Toute autre valeur ou un champ absent est faux. Un indicateur positif absent empêche donc le classement comme GPO appliquée ; un AccessDenied absent est considéré comme faux. Aucun état indéterminable ne déclenche d'erreur spécifique dans cette version.

La recherche des balises GPO est récursive. Les entrées sans nom sont ignorées, sans repli sur un identifiant XML. Les doublons sont éliminés selon (nom, VersionDirectory, VersionSysvol) ; un nom peut apparaître plusieurs fois si les versions diffèrent. Les listes de GPO ne sont pas triées. Les compteurs décrivent les entrées retenues, sans constituer un inventaire de toutes les GPO du domaine.

Classement des groupes de sécurité

Les groupes sont extraits des balises SecurityGroup du RSoP, sans requête LDAP supplémentaire. Le classement utilise les préfixes des noms, dans cet ordre :

Catégorie Règle
system Préfixe NT AUTHORITY\.
local Préfixe BUILTIN\ ou nom du poste suivi de \.
domain Préfixe du compte RSoP suivi de \, si ce préfixe est non vide et différent du nom du poste.
other Toutes les autres identités.

Un compte POSTE01\utilisateur ne fournit donc pas de préfixe AD pour classer les groupes de domaine. Les comparaisons et la déduplication ignorent la casse. Les entrées sans nom sont ignorées et chaque liste est triée alphabétiquement sans distinction de casse.

Ce classement repose sur les noms de l'export, sans validation par SID ou LDAP. Les noms localisés ou les groupes d'un autre domaine peuvent rester dans other. Les listes reflètent les données RSoP collectées ; elles ne constituent pas un inventaire exhaustif des groupes AD ou locaux.

Statuts et cas particuliers

Statut enregistré Retour WAPT Situation
OK OK Export, analyse et enregistrement terminés, même avec des GPO non appliquées ou des listes vides.
NO_USER OK Aucun utilisateur actif reconnu, y compris en cas d'échec de détection capturé.
ERROR ERROR Exception capturée par l'audit : GPResult en échec, fichier absent, XML invalide, section UserResults absente, etc.

Le résultat NO_USER contient message, user: null, des listes applied_gpos, denied_gpos et domain_groups vides, ainsi que les quatre catégories vides de security_groups. Il ne contient pas de bloc summary. Aucun statut WARNING n'est utilisé.

En cas d'erreur, la même clé reçoit uniquement status: ERROR et message. Les listes et compteurs du précédent succès ne sont pas recopiés. Les consommateurs doivent lire status avant d'accéder aux champs de succès.

La clé représente le dernier audit du poste, selon l'utilisateur sélectionné au moment de l'exécution ; aucune clé distincte par utilisateur n'est créée.

Déploiement et dépannage

  1. Mettre à jour setup.py dans les sources du paquet existant.
  2. Adapter si nécessaire la description de WAPT/control pour mentionner les groupes de sécurité, en conservant l'identité et les autres métadonnées du paquet ; incrémenter sa version selon les conventions du dépôt.
  3. Reconstruire, signer, téléverser et déployer le paquet.
  4. Lancer l'audit avec une session active et consulter audit-gpresult.user-gpo.

La fréquence des audits dépend de la configuration WAPT ; le script ne crée pas de planification. Le journal indique l'utilisateur détecté, le compte RSoP, son type, les compteurs de GPO et de groupes de domaine ou l'erreur rencontrée.

  • NO_USER inattendu : vérifier la sortie de quser.exe, les libellés reconnus et les éventuelles erreurs de détection dans le journal.
  • Compte inattendu : vérifier l'ordre des sessions actives et comparer le nom détecté avec user.account.
  • Erreur GPResult ou XML : vérifier les droits de l'agent, la disponibilité du RSoP pour ce compte, l'accès à GPResult et au répertoire temporaire.

Le rapport utilise le nom fixe wapt-gpresult-user.xml dans tempfile.gettempdir(). Éviter les audits simultanés partageant ce répertoire. Un échec de nettoyage est ignoré et peut laisser le fichier sur disque.

Contenu du dépôt

  • setup.py : détection de session, collecte et analyse des GPO et groupes de sécurité utilisateur.
  • README.md : fonctionnement, schéma de données et exploitation.
  • WAPT/description.txt : description fournie pour le contrôle existant ; elle décrit les GPO et ne mentionne pas encore les groupes de sécurité. Ce fichier ne remplace pas un WAPT/control complet.
S
Description
affiche le gpresult du user actif dans les données d'audit
Readme GPL-3.0
58 KiB
0 Stars 3 Watchers 0 Forks
Languages
Python 100%