🔍 Contexte

Article technique publié le 16 septembre 2026 sur dfir.ch, rédigé par un analyste DFIR. Il documente l’abus potentiel du système de modules de zsh (shell par défaut sur macOS) à des fins d’évasion de détection et d’exécution furtive.

⚙️ Fonctionnalités des modules zsh exploitables

zsh dispose d’un système de modules chargeables à l’exécution via zmodload, exposant des fonctionnalités normalement associées à des utilitaires externes :

  • zsh/net/tcp : connexions TCP brutes via le builtin ztcp (sans curl, wget, nc)
  • zsh/mapfile : lecture/écriture/suppression de fichiers via un tableau associatif (sans cat, rm)
  • zsh/attr : manipulation des attributs étendus via zgetattr, zsetattr, zdelattr, zlistattr (sans /usr/bin/xattr)
  • zsh/files, zsh/stat, zsh/sched, zsh/zselect : autres fonctionnalités système

🎯 Technique d’attaque démontrée

L’article démontre une chaîne d’exécution complète :

  1. Chargement de zsh/net/tcp via zmodload
  2. Établissement d’une connexion TCP brute avec ztcp vers un serveur HTTP
  3. Envoi manuel d’une requête HTTP GET depuis le processus zsh
  4. Exécution du payload reçu via source /dev/fd/$fd directement depuis le socket, sans écriture sur disque
  5. Le second stage décode un plist en base64, crée un LaunchAgent et le charge via launchctl

Aucun processus curl, wget, nc ou fichier de payload sur disque n’est créé.

🛡️ Visibilité défensive

  • Les opérations sur attributs étendus restent visibles via Apple Endpoint Security framework (ES_EVENT_TYPE_NOTIFY_DELETEEXTATTR, ES_EVENT_TYPE_NOTIFY_SETEXTATTR), attribuées à /bin/zsh
  • L’activité réseau TCP existe mais sans processus curl associé
  • Les utilitaires appelés dans le second stage (base64, launchctl) génèrent leur propre télémétrie
  • L’abus de zsh/net/tcp pour un reverse shell a été documenté in-the-wild en 2020 par ESET
  • GTFOBins et Elastic disposent de références sur ce primitif

📐 Implications pour la détection

Les règles basées sur process == "/usr/bin/xattr" ou la présence de curl sont insuffisantes. La détection doit cibler le comportement sous-jacent (ex: event == DELETEEXTATTR AND extattr == "com.apple.quarantine") indépendamment du processus implémentant l’opération.

📄 Type d’article

Analyse technique à visée DFIR et detection engineering, documentant des techniques d’évasion exploitant des fonctionnalités légitimes de zsh sur macOS, avec démonstration pratique et implications pour la télémétrie défensive.

🧠 TTPs et IOCs détectés

TTP

  • T1059.004 — Command and Scripting Interpreter: Unix Shell (Execution)
  • T1105 — Ingress Tool Transfer (Command and Control)
  • T1620 — Reflective Code Loading (Defense Evasion)
  • T1564 — Hide Artifacts (Defense Evasion)
  • T1543.001 — Create or Modify System Process: Launch Agent (Persistence)
  • T1562.001 — Impair Defenses: Disable or Modify Tools (Defense Evasion)
  • T1070.006 — Indicator Removal: Timestomp (Defense Evasion)
  • T1071.001 — Application Layer Protocol: Web Protocols (Command and Control)

🟡 Indice de vérification factuelle : 60/100 (moyenne)

  • ✅ dfir.ch — source reconnue (Rösti community) (20pts)
  • ✅ 16354 chars — texte complet (15pts)
  • ✅ 4 IOCs (IPs/domaines/CVEs) (10pts)
  • ⬜ pas d’IOC vérifié (0pts)
  • ✅ 8 TTPs MITRE identifiées (15pts)
  • ⬜ date RSS ou approximée (0pts)
  • ⬜ aucun acteur de menace nommé (0pts)
  • ⬜ pas de CVE à vérifier (0pts)

🔗 Source originale : https://dfir.ch/posts/zsh_modules/