# comi-audit-hardeningkitty Paquet source WAPT d’audit **en lecture seule** des paramètres de sécurité Windows avec [HardeningKitty](https://github.com/0x6d69636b/windows_hardening). Le nom du paquet WAPT reste `comi-audit-hardeningkitty` (voir `WAPT/control`) ; `comi-audit-secu` est le nom du dépôt. Le paquet lance le mode `Invoke-HardeningKitty -Mode Audit`, compare le rapport CSV avec la liste de contrôles sélectionnée, conserve des rapports locaux et publie un résumé ainsi que les écarts dans les données d’audit WAPT Enterprise. Il ne lance ni le mode `HailMary`, ni un mode GPO ou Config, et ne télécharge aucun code sur les postes. Les scripts et listes nécessaires sont préparés et intégrés au paquet signé avant l’installation. ## Compatibilité et sélection du benchmark `WAPT/control` exige WAPT 2.4 ou ultérieur. Le code Python évite les syntaxes postérieures à Python 3.8; les tests locaux ont été exécutés avec Python 3.9. La compatibilité réelle doit être confirmée avec l’agent et la console WAPT de l’environnement cible. Avec `profile: auto`, le runner choisit une liste machine disponible dans la révision HardeningKitty épinglée : | Système | Benchmark sélectionné | | --- | --- | | Windows 10 20H2/21H1, 21H2 ou 22H2 | Microsoft Security Baseline machine correspondante | | Windows 11 21H2 à 25H2 | Microsoft Security Baseline machine correspondante | | Windows Server 2012 R2, 2016 ou 2019 | CIS machine, version référencée dans le nom du fichier | | Windows Server 2022 | Microsoft Security Baseline machine 21H2, contrôleur de domaine ou membre | | Windows Server 2025 | Microsoft Security Baseline machine 24H2, contrôleur de domaine ou membre | Windows 11 26H2 et toute combinaison OS/build/rôle non reconnue échouent explicitement : aucun benchmark voisin n’est choisi automatiquement. La liste communautaire `finding_list_0x6d69636b_machine.csv` est disponible avec `profile: community`. Une liste précise peut être sélectionnée en indiquant son nom de fichier `finding_list_*_machine.csv`. Les listes `*_user.csv` sont refusées : un audit lancé par WAPT sous SYSTEM ne représente pas la session interactive d’un utilisateur. Les fichiers de benchmark sont épinglés avec HardeningKitty au commit `acf9ecee3d044a9337df7aad80e730cbd746e8de`. `tools/vendor_assets.py` exige les listes utilisées par le runner. Si une liste manque dans l’archive de cette révision, la préparation échoue au lieu d’annoncer une prise en charge fictive. ## Préparer les sources Cloner le dépôt dans le répertoire de développement WAPT habituel : ```powershell cd C:\waptdev git clone https://git.comitari.fr/paquets-publiques/comi-audit-secu.git cd .\comi-audit-secu ``` Dans WAPT Console / VS Code, lancer **Update Package**. Le point d’entrée unique est `update_package.py`; il localise le paquet à partir de son propre chemin, quel que soit le répertoire courant. Il récupère l’archive HTTPS du commit fixé, vérifie la structure et prépare `vendor/`, ses empreintes SHA-256 et `package-manifest.json`. Il n’incrémente pas la version, ne construit pas le `.wapt`, ne le signe pas et ne le publie pas. Pour une préparation hors ligne, fournissez une archive ZIP exacte du commit et son empreinte obtenue par un canal de confiance distinct : ```powershell $env:HARDENINGKITTY_ARCHIVE = 'C:\staging\windows_hardening-acf9ece.zip' $env:HARDENINGKITTY_ARCHIVE_SHA256 = '' ``` Puis lancer **Update Package**. L’empreinte locale calculée à partir du même fichier ne constitue pas une vérification indépendante de son authenticité. Le proxy système configuré pour Python/urllib est utilisé; la validation TLS par défaut n’est pas désactivée. Une erreur réseau ou d’intégrité arrête la préparation et garde le `vendor/` précédent. Le répertoire `vendor/` et `package-manifest.json` sont versionnés avec le paquet. Ainsi, un clone propre contient directement les composants épinglés et peut être construit sans téléchargement préalable. **Update Package** permet de reproduire leur préparation ou de régénérer les manifestes après une évolution contrôlée de la révision upstream. La règle `.gitignore` est une règle Git; elle ne sert pas de filtre de contenu WAPT. WAPT applique ses propres exclusions de construction (notamment `.git`, `.gitignore`, `setup.pyc` et `__pycache__` dans les versions documentées). Ne configurez pas `vendor/` comme exclusion de construction. ## Contrôler, construire, signer et publier Avant toute construction, exécuter le contrôle bloquant des sources : ```powershell waptpython tools\package_verify.py --source . ``` Il refuse les assets absents, une révision upstream différente, un manifeste invalide ou des fichiers PowerShell/listes dont les hashes ne correspondent pas. Le contrôle lit réellement les fichiers sous `vendor/`. Après toute modification voulue de `setup.py`, `runner.ps1`, `audit_config.json`, `WAPT/control` ou du contenu vendor, relancer **Update Package** pour actualiser les manifestes, puis ce précontrôle. Ensuite, dans WAPT Console, utiliser **Build** pour construire et signer le paquet selon le certificat et le workflow standards de l’organisation. Ne pas utiliser **Build and upload** avant la vérification du fichier construit. Inspecter le `.wapt` réellement généré : ```powershell waptpython tools\package_verify.py --wapt .\comi-audit-hardeningkitty_0.9.9-0_all.wapt ``` Cette vérification ouvre l’archive ZIP `.wapt` et contrôle les scripts, `vendor/HardeningKitty.psm1`, `vendor/HardeningKitty.psd1`, le manifeste vendor, les listes CSV et toutes les empreintes référencées. Si elle réussit, publier ensuite depuis WAPT Console selon le workflow habituel. La réussite d’Update Package ou du précontrôle ne signifie jamais que la construction, la signature ou la publication ont réussi. La vérification locale contrôle les hashes de contenu; elle ne remplace pas la validation cryptographique de la signature WAPT, qui reste au workflow Console/agent. Le builder WAPT documenté peut également être lancé par CLI avec `wapt-get build-package .`, puis le `.wapt` doit passer le même contrôle d’archive. Éviter `build-upload` avant ce contrôle post-build. ## Installation et audit poste L’installation ne contacte ni GitHub, ni la PowerShell Gallery. Elle vérifie le manifeste de paquet et chaque fichier vendor avant la copie, copie vers un répertoire temporaire, vérifie à nouveau les hashes, applique une ACL limitée à SYSTEM et Administrateurs locaux, puis remplace atomiquement l’installation précédente avec restauration en cas d’échec. Les rapports sont conservés lors d’une mise à jour. Emplacements par défaut : ```text C:\ProgramData\Comitari\Audit-HardeningKitty\ C:\ProgramData\Comitari\Audit-HardeningKitty-Reports\ ``` `audit()` choisit Windows PowerShell 5.1 64 bits, vérifie la bitness du processus, lance le runner avec timeout (`timeout_seconds`, défaut 900 s) et refuse un rapport absent, vide, incomplet, mal formé ou corrompu. Un contrôle manquant/ignoré/non évaluable est distinct d’un contrôle conforme. Les exclusions conditionnelles ne sont acceptées que si elles sont explicitement documentées dans `intentional_exclusions`, par nom exact de benchmark et ID, avec une raison non vide. Elles sont comptées comme exclues et jamais comme conformes. Les résultats `Not Applicable` explicites sont également séparés du dénominateur de conformité. Le rapport attendu est le CSV HardeningKitty à colonnes `ID,Category,Name,Severity,Result,Recommended,TestResult,SeverityFinding`. Une ligne n’est conforme que si `Severity=Passed` et `TestResult=Passed`; un écart Low/Medium/High exige `TestResult=Failed` et une sévérité concordante. Les autres combinaisons sont inconnues et produisent `ERROR`. Le parseur accepte les rapports UTF-8/BOM, UTF-16 et l’encodage local Windows strictement, car Windows PowerShell 5.1 n’a pas un encodage par défaut uniforme pour les fichiers CSV. La couverture est jointe par `ID`, pas par les noms/catégories qui peuvent être localisés; les IDs doivent être uniques dans le benchmark et le rapport. La classification est : | Résultat | Statut WAPT par défaut | | --- | --- | | Tous les contrôles applicables conformes | `OK` | | Écart Medium ou Low | `WARNING` | | Écart High | `ERROR` | | Erreur technique, timeout, résultat manquant/ignoré/inconnu ou aucune population évaluable | `ERROR` | `error_on_high` et `warn_on_low` configurent les seuils métier. Désactiver l’alerte High ou Low ne transforme jamais une collecte incomplète en résultat conforme. Le statut retourné par `audit()` est le résultat courant; une erreur de publication WAPT provoque elle-même un `ERROR`. ## Données et Reporting WAPT Le paquet utilise les API d’audit documentées pour WAPT 2.4+ : `WAPT.write_audit_data_if_changed(section, key, value, ..., max_count=5, keep_days=120)` pour les mesures stables, et `WAPT.write_audit_data()` pour l’observation horodatée `last_run_utc`. Une erreur d’écriture ne reste pas silencieusement cachée : l’audit retourne `ERROR` et tente de publier ce statut. Dans la section `HardeningKitty`, les clés publiées comprennent : - `status`, `benchmark`, `os_caption`, `os_build`, `display_version`, `source`, `upstream_commit`, `last_run_utc`, `last_error` ; - `expected`, `executed`, `passed`, `high`, `medium`, `low`, `ignored`, `not_applicable`, `excluded`, `unknown`, `skipped`, `total` et `compliant_percent` ; - `findings_00` à `findings_15`, des fragments JSON stables avec ID, catégorie, nom, sévérité du contrôle et résultat. Les valeurs actuelles/recommandées ne sont pas dupliquées dans ces fragments lorsque `publish_current_values` est faux. Les valeurs actuelles et recommandations issues du poste ne sont pas envoyées par défaut (`publish_current_values: false`). Les écarts détaillés restent dans le CSV local, protégé par ACL; les journaux locaux peuvent inclure les erreurs techniques. Huit exécutions locales sont conservées par défaut. WAPT limite les mesures stables à cinq changements pendant 120 jours, les fragments à trois changements pendant 120 jours, et les horodatages à cinq observations pendant 120 jours. Ces valeurs suivent les paramètres documentés des API d’audit WAPT. La suite mesure aussi la taille série des écarts sur des CSV synthétiques. Pour 10/100/500 lignes d’écart, le CSV brut local faisait 3 562/35 062/175 462 octets; les fragments JSON WAPT par défaut faisaient 1 125/11 106/55 906 octets. Le mode qui ajoute les valeurs et recommandations synthétiques faisait 4 305/42 906/214 906 octets. Ce sont des tailles de sérialisation, sans surcoût PostgreSQL/WAPT, et non une mesure sur un parc réel. Les métriques de résumé et les détails restent séparés; les valeurs de contrôle ne sont pas copiées dans Reporting par défaut. ## Configuration Dans `audit_config.json` : - `source`: `GPO` ou `Intune` (source de comparaison HardeningKitty, pas un changement de stratégie) ; - `profile`: `auto`, `community` ou nom exact d’une liste machine embarquée ; - `timeout_seconds`: délai d’exécution entre 30 et 7200 secondes ; - `error_on_high`, `warn_on_low`: seuils de statut ; - `publish_to_wapt`: publication structurée dans les données d’audit ; - `publish_current_values`: autorise explicitement la transmission des valeurs observées et recommandées ; désactivé par défaut ; - `intentional_exclusions`: dictionnaire benchmark → ID → raison pour les contrôles omis par une condition explicitement revue ; vide par défaut ; - `retain_audit_runs`, `max_findings_in_log`: rétention locale et volume de sortie console. Les exclusions doivent être fondées sur une revue du benchmark et ne doivent pas être ajoutées uniquement pour faire passer un audit. L’ID exclu reste visible et comptabilisé dans `excluded`. ## Désinstallation et limites `uninstall()` supprime uniquement les fichiers répertoriés dans le manifeste du paquet et conserve les éventuels fichiers étrangers présents dans le répertoire d’installation. Les rapports locaux ne sont pas supprimés. Pour effacer ces rapports, appliquer séparément la politique de conservation de l’organisation. HardeningKitty peut ne pas évaluer certains contrôles faute d’outil, droits ou prérequis; ces résultats ne sont jamais assimilés à des succès. Les vérifications utilisant des libellés localisés peuvent varier selon la langue Windows. Les résultats sur Windows français, les différents rôles serveur, les GPO/Intune réels et les performances parc doivent être validés sur des machines de test représentatives. Une conformité au benchmark n’est pas une preuve d’absence de vulnérabilité; un écart n’est pas une recommandation automatique de remédiation. Cette version n’a pas été validée par un audit PowerShell réel sur Windows ni par une installation signée avec un agent WAPT 2.6. Les tests du dépôt sont synthétiques et ne modifient pas la configuration Windows. ## Tests synthétiques Depuis la racine du dépôt, avec le `waptpython` de l’environnement WAPT : ```powershell waptpython tests\test_package.py -v waptpython -m py_compile setup.py update_package.py tools\vendor_assets.py tools\package_verify.py waptpython tools\package_verify.py --source . ``` Les tests utilisent des listes, rapports et archives synthétiques. Ils couvrent la préparation offline, hashes, intégrité et répétition, parseur CSV, contrôles manquants/doublons/ignorés, confidentialité, statut et API WAPT simulés, installation/désinstallation, et inspection d’un `.wapt` synthétique. Ils ne remplacent pas une validation sur poste Windows. ## Références - [HardeningKitty — dépôt upstream](https://github.com/0x6d69636b/windows_hardening) - [Microsoft — Export-Csv pour Windows PowerShell 5.1](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv?view=powershell-5.1) - [Microsoft — encodages PowerShell](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-5.1) - [WAPT 2.6 — ligne de commande et exclusions de build](https://www.wapt.fr/fr/doc-2.6/wapt-command-line-interface.html) - [WAPT — API et données d’audit](https://www.wapt.fr/fr/doc-2.7/wapt-create-packages-code.html)