Écrire une règle Nuclei pour une CVE : de l'advisory au template qui tire (sans faux positif)
Une CVE tombe, l'avis de sécurité est public, mais aucun template Nuclei n'existe encore. Voici comment en écrire un propre : partir du fait, construire les matchers, et surtout prouver qu'il tire sur une cible vulnérable sans crier au loup sur une cible patchée.
Une CVE critique est publiée un vendredi soir. L'avis de sécurité décrit la faille, la version affectée, le chemin vulnérable. La question n'est plus « suis-je concerné ? » mais « combien de mes actifs le sont, maintenant ? ». Nuclei est l'outil de référence pour répondre à cette question à l'échelle : un moteur rapide, des templates YAML lisibles, versionnables comme du code. Le problème, c'est qu'au moment où la CVE tombe, le template officiel n'existe pas encore, il arrivera dans quelques jours, parfois quelques semaines. Ce délai, c'est votre fenêtre d'exposition.
Écrire soi-même le template comble ce trou. Mais un template mal écrit est pire que pas de template : il rate la version vulnérable (faux négatif, vous vous croyez à l'abri) ou il crie sur une version déjà corrigée (faux positif, vous noyez l'équipe sous le bruit). Cet article montre comment en écrire un qui tire juste, et surtout comment le prouver.
Pourquoi ne pas simplement attendre le template officiel
Trois raisons de savoir le faire vous-même :
- Le décalage. Entre la publication d'une CVE et l'arrivée d'un template public, il s'écoule un temps variable. Sur une faille activement exploitée (une entrée du catalogue CISA KEV), ce délai est exactement celui pendant lequel les attaquants scannent, eux.
- Vos applications maison. Aucun projet communautaire ne couvrira votre ERP interne, votre portail sur mesure ou cette appliance de niche. La détection sur ce périmètre, personne ne l'écrira à votre place.
- La priorisation. Vous ne pouvez pas écrire un template pour les 40 000 CVE de l'année. Savoir le faire vite pour la poignée qui compte (celles exploitées, exposées, sur vos actifs critiques) est une compétence de detection engineering, pas un luxe.
L'anatomie d'un template Nuclei
Un template est un fichier YAML en deux parties : les métadonnées (info) et la logique (la requête plus les matchers). Voici le squelette :
id: cve-2024-0000-config-disclosure
info:
name: "ACME Portal < 4.2 - Divulgation de configuration non authentifiée"
author: votre-equipe
severity: high
description: |
ACME Portal avant 4.2 expose /api/v1/config sans authentification,
révélant les identifiants de la base de données et les clés d'API.
classification:
cve-id: CVE-2024-0000
cvss-score: 8.6
tags: cve,cve2024,acme,exposure
http:
- method: GET
path:
- "{{BaseURL}}/api/v1/config"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
part: body
words:
- '"db_password"'
- '"api_key"'
condition: and(L'exemple est illustratif : le principe compte plus que la CVE choisie.) Chaque bloc a un rôle. Le id est unique et parlant. Le bloc info porte la sévérité et la classification (le cve-id, le score CVSS), ce n'est pas de la décoration : c'est ce qui permettra de trier, corréler et prioriser ensuite. La partie http décrit ce qu'on envoie et ce qui prouve la vulnérabilité.
Partir du fait, pas du proof-of-concept
C'est le point le plus important, et le plus souvent négligé. Sur GitHub, un PoC d'exploitation circule presque toujours avant le template. La tentation est de le recopier. Ne le faites pas, pour deux raisons.
D'abord la rigueur juridique : un PoC publié sans licence explicite est « tous droits réservés » par défaut. Le recopier dans un template que vous partagez ou revendez est un problème. En revanche, le fait décrit par l'avis de sécurité (« la version X expose le chemin Y qui renvoie la chaîne Z ») n'appartient à personne. Une signature de détection est votre œuvre, comme la signature d'un antivirus n'hérite pas des droits du malware qu'elle détecte.
Ensuite la qualité : un PoC cherche à exploiter, un template cherche à constater sans danger. Vous ne voulez pas déposer un webshell pour prouver une RCE ; vous voulez le signe le plus léger et le plus fiable que la faille est là. L'avis de sécurité vous donne exactement ce signe : le chemin, le marqueur de version, la signature de réponse. C'est votre matière première.
Construire les matchers, du plus grossier au plus précis
Un matcher qui renvoie « vulnérable » trop facilement est le piège numéro un. Prenons trois niveaux :
Niveau 1 : le code de statut seul. status: 200 sur /api/v1/config. Insuffisant : une version patchée peut renvoyer 200 avec une page vide ou un message d'erreur. Un statut ne prouve pas la vulnérabilité, il prouve que le chemin existe.
Niveau 2 : le statut plus un mot-clé. On ajoute la présence de "db_password" dans le corps. Bien meilleur : on ne se déclenche que si la réponse contient réellement la donnée fuitée. Le matchers-condition: and impose que les deux conditions soient vraies.
Niveau 3 : la discrimination de version. Le cas subtil. Si la version 4.2 (corrigée) renvoie encore la clé mais vide, le niveau 2 produit un faux positif. Il faut alors un matcher regex qui capture une valeur non vide, ou lire le marqueur de version dans un en-tête. C'est ici que se joue la différence entre un template qui fait du bruit et un template en lequel votre équipe a confiance.
Pour une faille aveugle (pas de réponse directe observable, une injection out-of-band, une SSRF), Nuclei fournit interactsh : le template déclenche une interaction réseau vers un serveur de contrôle et confirme la vulnérabilité par ce rappel, sans jamais exploiter la cible.
Valider ne suffit pas : il faut prouver
Nuclei propose un contrôle intégré :
nuclei -validate -t cve-2024-0000-config-disclosure.yamlAttention au malentendu : -validate vérifie la syntaxe, pas l'efficacité. Un template parfaitement valide peut ne rien détecter, ou tout détecter. La validation syntaxique est nécessaire, jamais suffisante.
La vraie preuve est empirique, et elle tient en deux tests :
- Le template tire-t-il sur une cible vulnérable ? Montez l'application dans sa version faillible (un conteneur Docker de la bonne version fait très bien l'affaire) et lancez le template dessus. S'il ne tire pas, il est inutile.
- Reste-t-il silencieux sur une cible patchée ? Montez la version corrigée et relancez. S'il tire encore, vous avez un faux positif, le pire résultat, car il érode la confiance dans toutes vos alertes.
Un template qui a passé ces deux tests vaut infiniment plus qu'un template simplement « valide ». C'est la différence entre « ça compile » et « ça marche, prouvé ».
Les pièges qui coûtent cher
- Le matcher trop générique. Se déclencher sur une bannière de version (« Server: ACME/4.1 ») est fragile : la bannière se maquille, se retire, ou reste après un correctif rétroporté. Préférez toujours le comportement vulnérable observable à l'auto-déclaration du logiciel.
- La version corrigée oubliée. Le test « patché » n'est pas optionnel. La moitié des faux positifs viennent de là.
- Le doublon. Avant de garder votre template, vérifiez qu'un équivalent n'existe pas déjà en amont. L'outil
centagrège et déduplique les collections de templates, utile pour ne pas maintenir en double ce que la communauté couvre déjà. - Les classifications bâclées. Renseignez
cve-id,cvss-score,severity. C'est ce qui rendra vos résultats exploitables, triables par gravité, corrélables avec vos autres sources.
Prioriser : toutes les CVE ne se valent pas
Écrire un template a un coût. L'investir sur les bonnes failles change tout. Deux sources publiques et gratuites orientent l'effort :
- CISA KEV (Known Exploited Vulnerabilities) : le catalogue des failles activement exploitées. Une CVE qui y figure est une urgence, pas une hypothèse.
- EPSS (Exploit Prediction Scoring System) : une probabilité d'exploitation à 30 jours. Utile pour arbitrer entre deux failles avant qu'elles ne soient exploitées.
Croiser « cette CVE est dans KEV » avec « elle touche un actif exposé chez moi » donne une liste courte et actionnable : voilà les templates à écrire en premier.
En résumé
Écrire un bon template Nuclei pour une CVE, c'est une méthode, pas de l'improvisation : partir du fait décrit par l'avis (pas du PoC), construire le matcher le plus précis possible (pas seulement un statut), et prouver empiriquement qu'il tire sur du vulnérable et se tait sur du patché. Le reste (validation syntaxique, classifications, déduplication) est de l'hygiène.
C'est précisément la discipline que nous appliquons à l'échelle dans le feed Nuclei de ThreatClaw : chaque template est validé sur le moteur réel, priorisé par KEV et EPSS, et livré en réponse rapide sur les failles qui comptent. Quand une CVE critique tombe un vendredi soir, la fenêtre d'exposition est déjà couverte, vous n'avez pas à l'écrire vous-même dans l'urgence.
Articles liés
Une désérialisation de données non fiables donne une RCE sur SharePoint on-premise. Au KEV, exploitée par Storm-2603. Règle Sigma sur w3wp et détection Nuclei.
Un cookie d'override mal validé ouvre une session GlobalProtect non autorisée. Score relevé à 7.8, au KEV, exploité. Détection Nuclei et mitigation immédiate.
Un jeton OIDC non signé donne un accès technicien à SimpleHelp RMM. CVSS 10, au KEV, exploité pour livrer des voleurs. Détection Nuclei et comptes à surveiller.
CVE-2026-15409 (SSRF, CVSS 10) et CVE-2026-15410 (RCE root) frappent les SMA1000, au KEV. Versions correctives, IOC et détection Nuclei pour prioriser.