Windows Server 2022 sur Azure : fichier hosts qui s’efface — diagnostic, audit NTFS et événements 4663

Sur une VM Azure Windows Server 2022, un fichier hosts qui devient subitement vide est souvent le symptôme d’un processus tiers. Voici une méthode fiable, pas à pas, pour verrouiller les droits NTFS, tracer précisément l’accès (événements 4663) et rétablir rapidement le fichier.

Sommaire

Vue d’ensemble du problème

Une VM Windows Server 2022 (16 vCPU, 64 Gio) hébergée dans Azure, sans IP publique et placée dans un VNet privé, voit le fichier C:\Windows\System32\drivers\etc\hosts se vider de façon intermittente. Les recherches initiales (scripts, tâches planifiées, sécurité) et l’analyse des journaux d’événements autour des occurrences n’ont rien révélé.

La cause la plus fréquente n’est pas un « bug » du système mais un agent ou un compte de service qui réécrit ou tronque le fichier. Votre objectif : réduire la surface d’écriture (droits NTFS stricts) et attribuer une empreinte à chaque action (audit détaillé), afin d’identifier le compte ou le binaire qui vide le contenu.

Ce qui peut provoquer l’effacement du fichier hosts

  • Agents de configuration (DSC/Desired State Configuration, Custom Script Extension Azure, outils MDM/Intune, SCCM, Puppet/Chef/Ansible) qui « normalisent » le fichier.
  • EDR/antivirus qui neutralisent des entrées jugées malveillantes et réécrivent le fichier (rare mais possible).
  • GPO ou scripts de connexion/démarrage qui déploient un hosts standardisé.
  • Utilitaires réseau (installateurs, migration d’outils, vieilles routines de déploiement) qui modifient hosts puis échouent.
  • Erreurs humaines (édition manuelle en administrateur, déploiement d’un package incorrect, suppression involontaire).
  • Scénarios Azure spécifiques : VM extensions ou pipelines d’automatisation qui poussent un fichier hosts « par défaut ». (À noter : un disque système éphémère réinitialise l’OS lors d’une recréation, mais n’explique pas un effacement ponctuel isolé.)

Solution recommandée

Vérifier et durcir les autorisations NTFS

Objectif : seules les entités Administrators et SYSTEM doivent pouvoir modifier hosts. Les autres (dont Users) doivent avoir lecture seule. Procédez dossier etc puis fichier hosts.

REM — Arrêter l'héritage et définir des ACL minimales sur le dossier etc
icacls "C:\Windows\System32\drivers\etc" /inheritance:r
icacls "C:\Windows\System32\drivers\etc" /grant:r "SYSTEM:(OI)(CI)(F)" "Administrators:(OI)(CI)(M)" "Users:(OI)(CI)(R)"
icacls "C:\Windows\System32\drivers\etc" /remove:g "Authenticated Users" "CREATOR OWNER" 2>nul

REM — ACL encore plus stricte sur le fichier hosts
icacls "C:\Windows\System32\drivers\etc\hosts" /inheritance:r
icacls "C:\Windows\System32\drivers\etc\hosts" /grant:r "SYSTEM:(F)" "Administrators:(M)" "Users:(R)"

REM — Vérification
icacls "C:\Windows\System32\drivers\etc\hosts"

Conseils :

  • Si la VM est jointée au domaine, remplacez Administrators par BUILTIN\Administrators si nécessaire, et évitez d’ajouter des groupes AD tant que l’enquête n’est pas terminée.
  • L’attribut Lecture seule (attrib +R) ne suffit pas : un processus privilégié contournera cet attribut. Les ACL NTFS et l’audit sont indispensables.

Activer l’audit d’accès au fichier hosts

L’idée est de générer des événements 4656/4663 à chaque tentative d’écriture ou de suppression. Deux volets : activer la sous‑catégorie d’audit au niveau système (Audit File System) et poser une SACL sur le fichier/dossier.

Activer l’audit via l’interface

  1. Ouvrez secpol.mscAdvanced Audit Policy ConfigurationObject Access.
  2. Activez Audit File System (Success et Failure).
  3. (Option recommandé) Activez Audit Process Creation (Success) et la capture de la ligne de commande pour corréler l’accès fichier au processus (événement 4688).

Activer l’audit via commandes

REM — Sous-catégories d'audit
auditpol /set /subcategory:"File System" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable

REM — Inclure la ligne de commande dans 4688 (Process Creation)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ^
/v ProcessCreationIncludeCmdLine\_Enabled /t REG\_DWORD /d 1 /f 

Poser une SACL sur hosts et sur le dossier

Par l’interface : Propriétés → Sécurité → Avancé → Auditer, ajoutez une entrée pour Everyone, type All, portée « This folder, subfolders and files » (sur etc) et une entrée spécifique au fichier hosts pour Write/Append/Delete.

Par PowerShell :

$file   = "C:\Windows\System32\drivers\etc\hosts"
$folder = "C:\Windows\System32\drivers\etc"

# — SACL sur le fichier : écritures et suppressions

\$acl = Get-Acl \$file
\$rule = New-Object System.Security.AccessControl.FileSystemAuditRule(
"Everyone",
\[System.Security.AccessControl.FileSystemRights]::WriteData `    -bor [System.Security.AccessControl.FileSystemRights]::AppendData`
-bor \[System.Security.AccessControl.FileSystemRights]::WriteAttributes `    -bor [System.Security.AccessControl.FileSystemRights]::Delete`
-bor \[System.Security.AccessControl.FileSystemRights]::ChangePermissions `    -bor [System.Security.AccessControl.FileSystemRights]::TakeOwnership,     [System.Security.AccessControl.InheritanceFlags]::None,     [System.Security.AccessControl.PropagationFlags]::None,     [System.Security.AccessControl.AuditFlags]::Success`
-bor \[System.Security.AccessControl.AuditFlags]::Failure
)
\$acl.AddAuditRule(\$rule)
Set-Acl -Path \$file -AclObject \$acl

# — SACL sur le dossier etc pour héritage

\$aclDir = Get-Acl \$folder
\$ruleDir = New-Object System.Security.AccessControl.FileSystemAuditRule(
"Everyone",
\[System.Security.AccessControl.FileSystemRights]::Write `    -bor [System.Security.AccessControl.FileSystemRights]::Delete,     [System.Security.AccessControl.InheritanceFlags]::ContainerInherit`
-bor \[System.Security.AccessControl.InheritanceFlags]::ObjectInherit,
\[System.Security.AccessControl.PropagationFlags]::None,
\[System.Security.AccessControl.AuditFlags]::Success \`
-bor \[System.Security.AccessControl.AuditFlags]::Failure
)
\$aclDir.AddAuditRule(\$ruleDir)
Set-Acl -Path \$folder -AclObject \$aclDir 

Lire et interpréter les événements

Une fois l’audit actif :

  • 4656 : demande de handle (qui essaye d’accéder).
  • 4663 : accès effectivement réalisé (avec le type : WRITE_DATA, APPEND_DATA, DELETE, etc.).
  • 4688 : création de processus (corrélation via Process Name et Command Line).

Exemple de filtrage local rapide :

# — Accès écriture/suppression sur hosts (journal Sécurité)
Get-WinEvent -LogName Security |
  Where-Object { $_.Id -eq 4663 -and $_.ToXml() -match "\\Windows\\System32\\drivers\\etc\\hosts" -and $_.Message -match "WRITE_DATA|APPEND_DATA|DELETE" } |
  Select-Object TimeCreated, Id, Message |
  Format-List

Impact en production et bonnes pratiques

  • Charge : négligeable si vous ciblez un seul fichier. Le bruit provient surtout de lectures. Les écritures/suppressions produisent les événements utiles.
  • Taille du journal Sécurité : augmentez‑la et activez l’écrasement circulaire ou l’archivage.
REM — Passer le journal Sécurité à 96 Mo (exemple)
wevtutil sl Security /ms:100663296

Compléments conseillés

ActionButOutil / Service
Sauvegarde régulière de hostsRestaurer rapidement en cas d’effacementAzure Backup ou script PowerShell + Azure Blob
Surveillance d’intégritéDétecter tout changement non autoriséMicrosoft Defender for Cloud – File integrity monitoring
Alertes en temps réelÊtre prévenu dès qu’une réécriture survientAzure Monitor + règle basée sur l’événement 4663
Scan antivirus/EDRÉcarter la piste d’un malware modifiant le fichierMicrosoft Defender for Endpoint ou solution équivalente
Revue des GPO et extensions tiercesS’assurer qu’aucune stratégie/agent de configuration ne réécrit hostsGPMC, Endpoint Manager, scripts de login

Surveillance et alertes dans Azure Monitor (exemple)

Si la VM envoie ses journaux à Log Analytics, créez une règle d’alerte sur les événements 4663 visant hosts. Exemple de requête KQL (adaptez selon votre table : SecurityEvent ou Event) :

// Écritures/suppressions sur le fichier hosts
SecurityEvent
| where EventID == 4663
| where ObjectName endswith @"\Windows\System32\drivers\etc\hosts"
| where EventData has_any ("WRITE_DATA","APPEND_DATA","DELETE","WRITE_OWNER","WRITE_DAC")
| project TimeGenerated, SubjectAccount, SubjectUserName, SubjectDomainName, Process, ObjectName, EventData

Définissez ensuite un seuil (par exemple ≥ 1 événement) et une action group pour email/Teams/ITSM.

Restauration rapide et garde‑fou automatisé

En complément de la traçabilité, mettez en place une sauvegarde et une restauration éclair en cas d’effacement. Le script ci‑dessous :

  • crée un instantané daté ;
  • surveille la taille/empreinte ;
  • restaure la dernière version saine si le fichier devient vide.
# Requires: PowerShell 5+
$HostFile = "C:\Windows\System32\drivers\etc\hosts"
$BackupDir = "C:\Ops\HostsGuard\Backup"
$MinSizeBytes = 10           # Ajustez à votre norme interne
$HashAlgo = "SHA256"

New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null

function Backup-Hosts {
    $stamp = Get-Date -Format "yyyyMMdd_HHmmss"
    $dest  = Join-Path $BackupDir "hosts_$stamp"
    Copy-Item -Path $HostFile -Destination $dest -Force
    Get-FileHash -Path $dest -Algorithm $HashAlgo | Out-Null
    Write-Host "Backup: $dest"
}

function Get-LastGood {
    Get-ChildItem $BackupDir -File | Sort-Object LastWriteTime -Descending | Select-Object -First 1
}

function Test-HostsHealthy {
    if (-not (Test-Path $HostFile)) { return $false }
    $fi = Get-Item $HostFile
    return ($fi.Length -ge $MinSizeBytes)
}

# — 1) Sauvegarde initiale si aucune
if (-not (Get-ChildItem $BackupDir -File)) { Backup-Hosts }

# — 2) Vérification & restauration si vide
if (-not (Test-HostsHealthy)) {
    $last = Get-LastGood
    if ($last) {
        Copy-Item -Path $last.FullName -Destination $HostFile -Force
        Write-Host "Restauré à partir de $($last.Name)"
    }
}

# — 3) Sauvegarde après modification (si contenu différent)
$currHash = (Get-FileHash -Path $HostFile -Algorithm $HashAlgo).Hash
$lastFile = Get-LastGood
$lastHash = if ($lastFile) { (Get-FileHash -Path $lastFile.FullName -Algorithm $HashAlgo).Hash } else { "" }
if ($currHash -ne $lastHash -and (Test-HostsHealthy)) { Backup-Hosts }

Planifiez ce script via le Planificateur de tâches (toutes les 5–15 minutes), ou déclenchez‑le sur un événement 4663 pour réduire le temps d’exposition.

Checklist d’enquête

ContrôleCommentRésultat attendu
ACL NTFS minimalesicacls sur etc et hostsSeuls SYSTEM/Administrators en écriture
Audit File Systemauditpol /get /category:*Succès/Échec activés
SACL sur le fichierGet-Acl avec règles d’auditAudit Write/Append/Delete actif
Corrélation processÉvénement 4688 + ligne de commandeProcessus et arguments identifiés
Agents/ExtensionsInventaire des services & extensions AzureAgent coupable confirmé ou exclu
MDM/GPORevue des stratégies & scriptsAucune règle ne réécrit hosts

Diagnostic avancé (optionnel, utile sur systèmes très sollicités)

  • Sysmon : journalisez FileCreate/FileDelete et les hachages pour ...etc\hosts. Cela complète 4663 dans les cas où l’accès passe par des opérations indirectes.
  • Verrouillage ciblé : si un service identifie des tentatives d’écriture légitimes, créez un groupe dédié (Hosts‑Editors) dont les membres seront explicitement autorisés, tout en gardant l’audit.
  • Point de restauration : conservez une copie « d’OR » validée de hosts dans un coffre (Blob immuable, partage SMB en lecture seule) pour éviter les restaurations d’une version déjà compromise.

Erreurs à éviter

  • Se fier uniquement à l’attribut lecture seule : il n’empêche pas une écriture par un compte privilégié.
  • Activer l’audit en « large » sur tout le disque : vous noierez les signaux utiles dans le bruit.
  • Oublier d’augmenter/archiver le journal Sécurité : les événements critiques risquent d’être écrasés.
  • Supposer qu’un anti‑malware est en cause sans preuve : attendez d’avoir les événements corrélés (4663 + 4688) avant d’ajuster la configuration de sécurité.

Documentation utile

  • Microsoft Learn : « Apply a basic audit policy on a file or folder ».
  • Varonis : pas‑à‑pas détaillé de l’audit du système de fichiers Windows.

Procédure condensée (copiable en runbook)

  1. ACL : appliquez les commandes icacls ci‑dessus.
  2. Audit : activez File System et Process Creation (auditpol + clé Registre), posez les SACL (Set-Acl).
  3. Journal : augmentez la taille (wevtutil), configurez la collection vers Log Analytics si utilisé.
  4. Alertes : créez la règle KQL sur 4663 pour hosts.
  5. Restauration : déployez le script HostsGuard en tâche planifiée.
  6. Revue : inventaire des extensions/agents, GPO/Intune, EDR, et pipelines de déploiement.

Résultat attendu

En combinant des droits NTFS restrictifs et un audit ciblé, vous identifierez précisément le compte ou le processus qui vide hosts. L’impact en production reste minime : l’audit ne vise qu’un fichier, le bruit est contrôlé, et la surveillance/alerte via Azure Monitor garantit une réaction rapide. La restauration automatisée limite la durée d’indisponibilité applicative.

Annexe : commande unique de mise en place (tout‑en‑un)

Pour un déploiement rapide (exécuter en PowerShell administrateur) :

$ErrorActionPreference = "Stop"

# 1. ACL durcies

cmd /c 'icacls "C:\Windows\System32\drivers\etc" /inheritance\:r'
cmd /c 'icacls "C:\Windows\System32\drivers\etc" /grant\:r "SYSTEM:(OI)(CI)(F)" "Administrators:(OI)(CI)(M)" "Users:(OI)(CI)(R)"'
cmd /c 'icacls "C:\Windows\System32\drivers\etc\hosts" /inheritance\:r'
cmd /c 'icacls "C:\Windows\System32\drivers\etc\hosts" /grant\:r "SYSTEM:(F)" "Administrators:(M)" "Users:(R)"'

# 2. Audit activé (File System + Process Creation avec ligne de commande)

auditpol /set /subcategory:"File System" /success\:enable /failure\:enable | Out-Null
auditpol /set /subcategory:"Process Creation" /success\:enable | Out-Null
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" \`
/v ProcessCreationIncludeCmdLine\_Enabled /t REG\_DWORD /d 1 /f | Out-Null

# 3. SACL sur dossier et fichier

function Add-AuditRule(\$Path, \$Rights, \$Inherit, \$Propagate) {
\$acl = Get-Acl \$Path
\$rule = New-Object System.Security.AccessControl.FileSystemAuditRule(
"Everyone", \$Rights, \$Inherit, \$Propagate,
\[System.Security.AccessControl.AuditFlags]::Success \`
-bor \[System.Security.AccessControl.AuditFlags]::Failure
)
\$acl.AddAuditRule(\$rule)
Set-Acl -Path \$Path -AclObject \$acl
}

Add-AuditRule "C:\Windows\System32\drivers\etc" `  ([System.Security.AccessControl.FileSystemRights]::Write -bor`
\[System.Security.AccessControl.FileSystemRights]::Delete) `  ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor`
\[System.Security.AccessControl.InheritanceFlags]::ObjectInherit) \`
(\[System.Security.AccessControl.PropagationFlags]::None)

Add-AuditRule "C:\Windows\System32\drivers\etc\hosts" `  ([System.Security.AccessControl.FileSystemRights]::WriteData -bor`
\[System.Security.AccessControl.FileSystemRights]::AppendData -bor `   [System.Security.AccessControl.FileSystemRights]::Delete -bor`
\[System.Security.AccessControl.FileSystemRights]::WriteAttributes -bor `   [System.Security.AccessControl.FileSystemRights]::ChangePermissions -bor`
\[System.Security.AccessControl.FileSystemRights]::TakeOwnership) `  ([System.Security.AccessControl.InheritanceFlags]::None)`
(\[System.Security.AccessControl.PropagationFlags]::None)

# 4. Journal Sécurité agrandi

wevtutil sl Security /ms:100663296 | Out-Null

Write-Host "Verrouillage + audit du fichier hosts terminés." 

FAQ rapide

Rendre hosts en lecture seule suffit‑il ? Non. Un processus lancé en haute intégrité peut modifier/supprimer malgré l’attribut. Les ACL + l’audit sont nécessaires.

Que faire si l’événement indique un compte générique (ex. SYSTEM) ? Corrélez avec 4688 (processus et ligne de commande). En cas de service, activez la journalisation détaillée du service, ou isolez‑le en compte dédié.

Comment exclure un agent légitime ? Une fois identifié, créez un groupe Hosts‑Editors et accordez‑lui Modify sur hosts tout en conservant l’audit.


Conclusion : dans Azure comme on‑premises, un hosts qui « s’efface » révèle presque toujours un acteur technique. En verrouillant les droits NTFS et en consignant chaque accès (4663/4656 + 4688), vous transformez une panne aléatoire en incident traçable, actionnable et, au besoin, immédiatement réversible grâce à la sauvegarde automatisée.

Sommaire