350 lines
18 KiB
Markdown
350 lines
18 KiB
Markdown
# 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 un agent WAPT 2.6 ou ultérieur pour le schéma d'audit
|
||
structuré. 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 incrémente le build WAPT uniquement si le contenu
|
||
vendor change. Il 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 = '<SHA256 obtenu indépendamment>'
|
||
```
|
||
|
||
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.10-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
|
||
|
||
## Données et Reporting WAPT
|
||
|
||
Chaque audit publie un unique objet Python sérialisable en JSON avec
|
||
`WAPT.write_audit_data_if_changed('hardeningkitty', 'hardeningkitty', document,
|
||
max_count=2, keep_days=120)`. Il n’y a plus de métriques WAPT dispersées ni de
|
||
clés `findings_00` à `findings_15`. Le document change uniquement si son contenu
|
||
change; sa date d’audit fait partie du document, afin de conserver un historique
|
||
des audits ayant réellement produit un nouvel état. L’[API de données d’audit
|
||
WAPT 2.6](https://www.wapt.fr/fr/doc-2.6/wapt-create-packages-code.html)
|
||
accepte un paramètre `value` générique; le round-trip natif d’un dictionnaire a
|
||
également été contrôlé dans le code local WAPT 2.7. La documentation des
|
||
[templates Mustache Console](https://www.wapt.fr/fr/doc-2.7/wapt-console-usage-advanced-audit-data-plugin.html)
|
||
est celle de WAPT 2.7; le rendu Console doit être qualifié avant diffusion,
|
||
notamment si la Console cible reste en version 2.6.
|
||
|
||
Les données sont limitées à 2 MiB avant publication. Si le jeu complet dépasse
|
||
la limite, l’audit échoue explicitement et publie un document `ERROR`; aucun
|
||
contrôle n’est tronqué. Les valeurs constatées restent exclues sauf opt-in
|
||
`publish_current_values: true`. Les recommandations viennent du benchmark et
|
||
peuvent être publiées. Chemins, arguments et descriptions ne sont inclus que
|
||
lorsqu’ils sont présents dans les données de référence. Le rapport CSV détaillé
|
||
reste local, sous les ACL de ProgramData. WAPT conserve au plus deux valeurs
|
||
différentes par clé et 120 jours; huit exécutions locales sont gardées par
|
||
défaut.
|
||
|
||
La mesure synthétique exécutée avec 500 contrôles donne 264 171 octets pour
|
||
le document structuré sans valeurs constatées et 335 670 octets avec l'opt-in
|
||
des valeurs. Le document structuré est plus riche qu'un CSV brut et n'est donc
|
||
pas présenté comme systématiquement plus petit. La rationalisation porte sur
|
||
une seule clé, l'absence de répétition du snapshot par métrique/fragment et
|
||
l'historisation uniquement lorsque le document change. Les contrôles détaillés
|
||
restent la source canonique; l'aperçu prioritaire ne répète que leurs ID,
|
||
catégorie, statut et sévérité. Les tailles sont celles
|
||
de sérialisation Python; elles n'incluent pas l'overhead PostgreSQL/WAPT.
|
||
|
||
Exemple anonymisé (forme abrégée; le paquet publie tous les contrôles, sans
|
||
tronquer le JSON) :
|
||
|
||
```json
|
||
{
|
||
"schema_version": 2,
|
||
"status": "WARNING",
|
||
"compliance": "non_compliant",
|
||
"scan": {
|
||
"date_utc": "2026-10-29T10:00:00+00:00",
|
||
"engine": "HardeningKitty",
|
||
"engine_commit": "acf9ecee3d044a9337df7aad80e730cbd746e8de",
|
||
"profile": "auto",
|
||
"source": "GPO"
|
||
},
|
||
"host": {"os_caption": "Windows 11", "build": "26100", "display_version": "24H2"},
|
||
"benchmark": {"name": "finding_list_example_machine.csv"},
|
||
"summary": {"expected": 407, "executed": 407, "passed": 390, "high": 2,
|
||
"medium": 10, "low": 5, "unknown": 0, "skipped": 0,
|
||
"compliant_percent": 95.82},
|
||
"categories": {"System": {"expected": 40, "passed": 38, "high": 1,
|
||
"medium": 1, "low": 0, "compliant_percent": 95.0}},
|
||
"controls": {"101": {"id": "101", "category": "System", "name": "Example",
|
||
"status": "failed", "severity": "high",
|
||
"recommended": "1"}}
|
||
}
|
||
```
|
||
|
||
La vue Console facultative se trouve dans
|
||
`console-templates/host_audit_hardeningkitty_hardeningkitty.html`. Elle est
|
||
destinée au poste **WAPT Console uniquement**, pas au paquet agent. L’installer
|
||
dans le répertoire de templates de la Console sous ce nom exact, puis choisir
|
||
la clé d’audit `hardeningkitty / hardeningkitty`. Elle exploite le helper
|
||
Mustache WAPT `Items` pour parcourir les dictionnaires de catégories et de
|
||
contrôles. WAPT expose le document JSON sous `value`; les informations de
|
||
machine, comme `computer_fqdn`, restent à la racine du contexte Mustache. Le
|
||
template suit cette structure et les collections sont parcourues avec
|
||
`Items value.categories` et `Items value.controls`.
|
||
|
||
Lors de l’installation du paquet sur Windows, `install()` copie automatiquement
|
||
le template avec les helpers WAPT vers
|
||
`makepath(programfiles32, "wapt", "templates")`, soit le répertoire standard
|
||
de templates de l’agent/console WAPT 32 bits. Le fichier porte le nom exact
|
||
`host_audit_hardeningkitty_hardeningkitty.html`.
|
||
|
||
Sur une console macOS/Linux dont le répertoire de templates est
|
||
`/opt/wapt/templates`, le paquet Windows ne peut pas effectuer cette copie.
|
||
Installer ou mettre à jour le fichier depuis la racine du paquet :
|
||
|
||
```sh
|
||
sudo install -m 0644 \
|
||
console-templates/host_audit_hardeningkitty_hardeningkitty.html \
|
||
/opt/wapt/templates/host_audit_hardeningkitty_hardeningkitty.html
|
||
```
|
||
|
||
Après copie, ouvrir le rapport d’audit et sélectionner la clé
|
||
`hardeningkitty / hardeningkitty`. Le template est une vue console; il ne
|
||
modifie ni la configuration Defender ni les données du rapport.
|
||
|
||
Les valeurs variables utilisent les tags Mustache échappés; aucun JavaScript
|
||
ni triple-brace non échappé n’est utilisé. Le template est une vue de synthèse
|
||
et d’analyse, pas une preuve de conformité indépendante. Son rendu a été testé
|
||
avec le moteur Mustache WAPT sur des données synthétiques, mais doit être
|
||
contrôlé dans la version réelle de WAPT Console avant diffusion.
|
||
|
||
Les anciennes clés fragmentées restent éventuellement visibles dans
|
||
l’historique antérieur à cette version; elles ne sont plus émises par le code
|
||
actuel. Les requêtes Reporting doivent lire la dernière valeur de
|
||
`value_section='hardeningkitty'` et `value_key='hardeningkitty'`, puis naviguer
|
||
dans le JSON (`summary`, `categories`, `controls`, `priority_findings`). Le
|
||
format et la limite de 2 MiB doivent être pris en compte par les consommateurs.
|
||
|
||
## 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)
|