Aller au contenu

Pentest automatisé (surface d'attaque)

L’inventaire de monsys sait ce qui tourne sur vos hôtes (ports, certificats, paquets, runtimes). La couche de pentest automatisé regarde depuis l’extérieur et répond à ce que l’inventaire ne peut pas : qu’est-ce qui est réellement joignable depuis internet, et une CVE détectée est-elle exploitable ?

C’est opt-in, cela ne tourne que contre un périmètre dont la propriété est prouvée, et c’est detect-only : jamais d’exploitation, jamais de force brute, rien n’est écrit sur une cible.

Un scanner ne touche qu’un actif existant comme entrée de périmètre vérifiée. Aucun champ libre ne lance de scan. La propriété se prouve de trois façons :

  • agent_vhost : un agent a trouvé le domaine dans nginx/Caddy/certbot sur son hôte. Vérifié automatiquement uniquement si un certificat d’AC publique présent sur cet hôte couvre le nom (on n’obtient pas de certificat public pour un domaine qu’on ne contrôle pas). Sinon, c’est un candidat, non scannable, jusqu’à confirmation DNS-TXT ou manuelle.
  • dns_txt : placez un enregistrement TXT _monsys-challenge.<domaine> avec le jeton affiché. Pour les domaines sans agent.
  • manual_admin : un propriétaire de tenant ajoute un domaine/IP avec TOTP.

Dans le tableau de bord : Sécurité → Surface d’attaque.

  1. « Importer les domaines des agents » : vos vhosts d’agents arrivent, vérifiés via leur certificat.
  2. Activez la politique avec TOTP. Par défaut, le scan est désactivé.
  3. Choisissez une fenêtre de maintenance ; les scans planifiés ne tournent que là.
  4. « Scanner maintenant » (TOTP) pour une exécution immédiate. Le kill-switch est à côté et arrête un scan en cours en quelques secondes.

Tous les scanners tournent en open source dans des conteneurs Docker épinglés sur le hub.

Phase Scanner Ce qu’il détecte
1 nmap ports et services ouverts (connect scan, sans sonde OS)
1 testssl.sh certificats faibles/expirés, anciennes versions TLS, chiffrements faibles
1 nuclei mauvaises configurations, fichiers exposés (.git, .env), en-têtes de sécurité manquants, logins par défaut
2 nuclei (CVE) confirme qu’une CVE de l’inventaire répond vraiment → exploitable confirmé
3 OWASP ZAP baseline passive par application web

nuclei tourne avec les tags misconfig,exposure,ssl,default-login ; tout ce qui est intrusif (DoS, force brute, fuzzing, injection active) est exclu et l’interaction hors bande est désactivée.

  • Un seul point de passage. Chaque scanner reçoit ses cibles uniquement via la fonction interne ResolveTargets, qui (a) vérifie l’appartenance au périmètre avec un filtre tenant_id, (b) répète le garde-fou SSRF/plages privées sur l’IP résolue (pas de RFC1918, loopback, link-local, CGNAT, 169.254, NAT64/6to4/Teredo, métadonnées cloud), (c) applique le kill-switch, l’opt-in et la fenêtre.
  • Conteneurs durcis et épinglés. Les scanners passent par un wrapper sudo (/usr/local/sbin/monsys-scan) avec des images épinglées par digest, --read-only, --cap-drop ALL, --security-opt no-new-privileges, limites pids/mémoire/cpu, non-root quand l’outil le permet, et DNS épinglé sur des résolveurs publics. Le nom d’hôte est lié à l’IP vérifiée via --add-host, rendant le DNS rebinding impossible. Le hub non privilégié ne choisit qu’un nom de scanner et fournit un fichier de cibles validé ; le docker run lui-même est dans le wrapper.
  • Le kill-switch arrête vraiment. Chaque conteneur a un nom que le hub peut docker kill via la verbe kill du wrapper ; le worker vérifie le drapeau toutes les quelques secondes.
  • Caviardage. Les preuves sont caviardées récursivement (jetons, JWT, basic-auth dans les URL, clés privées) avant stockage. La sortie brute des scanners n’est jamais conservée.

Les résultats apparaissent avec catégorie, gravité, statut (ouvert / corrigé / accepté / faux positif) et sont comparés semaine après semaine (« nouveau depuis la semaine dernière »). Une CVE confirmée fait passer l’exposition correspondante en « exploitable confirmé » avec une alerte.

Chaque exécution de scan est signée Ed25519 et entre dans le pack d’audit mensuel : qui, quand, quel périmètre, quels résultats. C’est une preuve reproductible que vous évaluez l’efficacité de vos mesures : directement utilisable pour un audit NIS2.

Le hub a besoin de :

  • Docker sur l’hôte et du wrapper /usr/local/sbin/monsys-scan + /etc/sudoers.d/monsys-scan (fournis dans hub/packaging/).
  • Un /var/lib/monsys/scan-targets accessible en écriture (dans les ReadWritePaths systemd du hub) et un jeu de templates en cache dans /var/lib/monsys/nuclei-templates (monté en lecture seule).
  • Les images de scanner sont épinglées par digest ; rafraîchissez le jeu de templates périodiquement hors scan.

Le detect-only ne remplace pas un pentest manuel avec exploitation ; il couvre la surface joignable, connue et mal configurée, en continu. Les templates nuclei sont en cache et ne sont pas téléchargés à chaque exécution. ZAP tourne un conteneur par domaine.