← All write-ups
April 1, 2025HIGHFINDING MISSION

Du kiosque au SYSTEM : backdoor Utilman persistant sous write-filter

Finding de mission (dispositif médical, client anonymisé). Technique développée et validée par 34zY / Hamza Terir. Le vecteur d’accès administrateur initial n’est pas documenté ici ; ce write-up couvre l’élévation et la persistance une fois un contexte admin obtenu.

Contexte

Poste médical sous Windows verrouillé en mode kiosque : une seule application plein écran (shell kiosque dédié), l’utilisateur n’est jamais censé atteindre le bureau ni l’OS. Le disque est protégé par un Unified Write Filter (UWF) : un overlay volatil qui réinitialise le système à chaque redémarrage.

Comment je l’ai trouvée

Une fois un shell administrateur disponible, j’ai atteint le bureau en terminant le processus du shell kiosque, ramenant l’écran de verrouillage Windows standard. J’ai ensuite ciblé un mécanisme d’accessibilité de l’écran verrou :

  1. Détournement Utilman via IFEO: pose d’une valeur Debugger sur utilman.exe dans les Image File Execution Options. Au clic sur le bouton « Options d’ergonomie » de l’écran de verrouillage, le debugger se lance avant utilman.exe, en contexte SYSTEM et avant authentification.
  2. Neutralisation de l’antivirus (temps réel, monitoring comportemental) pour éviter le nettoyage.
  3. Persistance UWF-aware: les modifications registre HKLM: frappent l’overlay RAM et sont perdues au reboot. La clé IFEO est donc écrite dans la couche de commit persistante du write-filter, pour survivre à la réinitialisation.
  4. Contrôle : Win+L → bouton d’accessibilité → le payload s’exécute bien en SYSTEM.

La faille

Chaîne de durcissement défaillant : confinement kiosque contournable, mécanisme d’accessibilité de l’écran verrou détournable en SYSTEM pré-auth, antivirus désactivable, et write-filter n’excluant pas les zones sensibles. Hypothèse cassée : « l’utilisateur du kiosque ne peut rien faire d’autre que l’application ».

Vérifications techniques non destructives

La validation publique se limite à l’inspection de la configuration et des journaux sur une image de laboratoire :

Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\utilman.exe'
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4657} -MaxEvents 20

Le contrôle de politique peut être automatisé sans exécuter le binaire d’accessibilité :

def kiosk_policy(*, debugger: str | None, shell: str, write_filter: bool) -> None:
    if debugger:
        raise ValueError("accessibility debugger must be absent")
    if shell.lower() not in {"approved-kiosk-shell.exe", "explorer.exe"}:
        raise ValueError("unexpected kiosk shell")
    if not write_filter:
        raise ValueError("persistent write protection is not active")

Le retest doit confirmer l’absence de la clé sensible après redémarrage, l’impossibilité de modifier la couche persistante et la présence d’une alerte d’intégrité.

Impact

Remédiation

CWE-269 (Improper Privilege Management) · MITRE ATT&CK T1546.008 (Accessibility Features).