
POC_CVE-2026-45185 for nuclei-templates
Ce dépôt n'est pas un dépôt de PoC d'exploit à usage général. Il s'agit d'un
laboratoire de validation local permettant de reproduire et d'examiner le comportement d'un
modèle CVE-2026-45185 destiné à être contribué à
projectdiscovery/nuclei-templates.
Le modèle de code nuclei n'est pas un détecteur basé uniquement sur la version.
Il contrôle directement STARTTLS, BDAT, TLS close_notify et un octet
SMTP en texte clair suivant sur la même connexion TCP.
Cette séquence correspond dans le laboratoire local vulnérable Exim 4.99.2 GnuTLS et ne
correspond pas dans le laboratoire corrigé Exim 4.99.3 GnuTLS dans les mêmes conditions.
Le signal de validation actuel est un oracle de réponse SMTP distant, pas une observation
directe de l'écriture UAF elle-même. En interne, cette CVE est une use-after-free
où des octets de saut de ligne (\r/\n) peuvent être écrits dans un tampon de transfert
GnuTLS libéré après l'arrêt TLS. En pratique, un client ne peut pas observer
directement cette écriture dans le tampon libéré via les réponses SMTP. Par conséquent,
ce README et le modèle ne prétendent pas prouver directement l'écriture UAF
bdat_ungetc -> tls_ungetc ou une RCE. À la place, le modèle détecte une
différence de récupération de la pile/état de réception qui apparaît pendant le flux de déclenchement.
En traçant le mécanisme de la vulnérabilité, j'ai observé qu'après TLS
close_notify pendant la gestion STARTTLS + BDAT, des pointeurs de fonction tls_* obsolètes
peuvent rester dans la couche inférieure de la pile de réception BDAT au lieu d'être
correctement restaurés en pointeurs de fonction smtp_*. Cet état devient visible dans
la façon dont le serveur traite la prochaine commande SMTP. Après que le BDAT fractionné atteint sa
première complétion, l'envoi de NOOP sur la même session fait que le laboratoire vulnérable
Exim 4.99.2 GnuTLS renvoie 421 lost input connection, tandis que le laboratoire corrigé
Exim 4.99.3 GnuTLS le gère normalement avec 250 OK. Cette différence claire de réponse
vulnérable/corrigé est utilisée comme correspondance pour le modèle de code nuclei local et autorisé.
Pour une présentation plus détaillée du flux de la vulnérabilité, voir
CVE-2026-45185-Technical-Analysis.md.
Destinataire d'enveloppe SMTP commun (RCPT TO) :
L'ACL lab_rcpt du laboratoire Docker accepte ce destinataire d'enveloppe. Sur une cible
SMTP générale, si RCPT TO est rejeté, la séquence peut ne pas atteindre l'analyseur
de corps BDAT, donc le modèle a besoin d'un destinataire accepté.
Cette valeur est distincte de l'en-tête To: dans le corps BDAT. Le
destinataire RCPT TO est une adresse d'enveloppe SMTP qui doit passer les vérifications
de destinataire du serveur. La valeur To: dans le corps BDAT n'est qu'un texte d'en-tête
de message ; elle n'a pas besoin d'exister ou d'être acceptée comme boîte aux lettres par le serveur.
templates/CVE-2026-45185.yaml
Nom du modèle :
Exim 4.97-4.99.2 GnuTLS STARTTLS BDAT - Vérification de réponse sur la même session
Le modèle est écrit avec metadata.verified: true et possède les balises code et
intrusive.
Exécutez les commandes suivantes depuis le répertoire POC_2026_45185/.
docker compose build
docker compose up -d
Validez la syntaxe du modèle :
nuclei -duc -validate -code -t templates/CVE-2026-45185.yaml
Signez le modèle de code local avant de l'exécuter :
nuclei -duc -code -t templates/CVE-2026-45185.yaml -sign
Exécutez contre le laboratoire vulnérable :
nuclei -code \
-t templates/CVE-2026-45185.yaml \
-u 127.0.0.1:2525 \
-var [email protected] \
-debug
Résultat attendu :
CVE-2026-45185 : oracle de réponse vulnérable correspondant
Exécutez contre le laboratoire corrigé :
nuclei -code \
-t templates/CVE-2026-45185.yaml \
-u 127.0.0.1:2526 \
-var [email protected] \
-debug
Résultat attendu :
pas de correspondance
NO-MATCH : réponse de type corrigé : NOOP a réussi après le déclenchement fractionné
Notez que le protocole code de nuclei n'est pas exécuté par défaut, donc -code est
nécessaire. Nuclei bloque également les modèles code non signés. Si la clé privée
locale de nuclei est protégée par une phrase de passe, exécutez la commande de signature dans un
terminal interactif et saisissez cette phrase de passe. Re-signez après chaque
modification du modèle car le digest couvre le contenu du modèle.
Ces captures d'écran montrent le résultat de l'oracle de réponse du laboratoire local après la signature du modèle. Elles constituent une preuve de validation de la différence de réponse sur la même session décrite ci-dessus, et non une preuve directe par débogueur ou ASAN de l'écriture UAF interne.
Laboratoire vulnérable Exim 4.99.2 GnuTLS sur 127.0.0.1:2525 :

Laboratoire corrigé Exim 4.99.3 GnuTLS sur 127.0.0.1:2526 :

Le cœur de cette CVE n'est pas une bannière SMTP ou une vérification de version. Le modèle doit créer la transition d'état de transport suivante sur la même connexion TCP :
SMTP en texte clair EHLO
-> STARTTLS
-> Poignée de main TLS sur la même connexion TCP
-> TLS EHLO / MAIL FROM / RCPT TO / BDAT 70 LAST
-> 69 premiers octets du corps BDAT en tant que données d'application TLS
-> TLS close_notify sans fermer la socket TCP
-> dernier octet du corps en texte clair sur la même connexion TCP
-> vérification de réponse NOOP en texte clair sur la même session
Le code Python dans le modèle YAML imprime le marqueur fixe uniquement après que toutes les conditions suivantes sont remplies. Le dispositif de correspondance nuclei ne correspond qu'à ce marqueur.
L'identité Exim est trouvée
ET STARTTLS est annoncé dans EHLO en texte clair
ET CHUNKING est annoncé dans EHLO en texte clair
ET STARTTLS est accepté
ET CHUNKING est annoncé dans EHLO TLS
ET MAIL FROM est accepté
ET RCPT TO est accepté
ET le BDAT fractionné close_notify atteint la première complétion
ET la première complétion contient "250 OK id="
ET la réponse NOOP en texte clair sur la même session contient "421"
ET la réponse NOOP en texte clair sur la même session contient "lost input connection"
Le modèle ne correspond sur aucun des signaux suivants seuls :
version uniquement
timeout uniquement
perte de connexion uniquement
réponse vide uniquement
rejet du destinataire
annonce STARTTLS/CHUNKING uniquement
Les deux laboratoires traitent le message BDAT fractionné jusqu'à la première complétion.
250- 70 byte chunk, total 72
250 OK id=...
La différence apparaît lorsque la prochaine commande SMTP en texte clair est envoyée sur la même session SMTP.
Vulnérable 4.99.2 :
NOOP -> 421 exim-lab.local lost input connection
QUIT -> 421 exim-lab.local lost input connection
RSET -> 421 exim-lab.local lost input connection
Corrigé 4.99.3 :
NOOP -> 250 OK
QUIT -> 221 exim-lab.local closing connection
RSET -> 250 Reset OK
Interprétation :
Observation :
Les deux laboratoires atteignent la complétion du message BDAT fractionné.
Seul le laboratoire vulnérable ne parvient pas à revenir proprement à la boucle
de commande SMTP en texte clair suivante dans la même session.
Preuve :
La réponse de suivi vulnérable est 421 lost input connection.
La réponse de suivi corrigée est 250 OK ou 221 closing connection.
Inférence :
Cette différence est cohérente avec la différence de récupération de la pile/état
de réception après STARTTLS close_notify.
Le modèle utilise le message de 70 octets suivant comme corps BDAT.
From: [email protected]\r\n
To: [email protected]\r\n
Subject: poc\r\n
\r\n
body
Le destinataire de l'enveloppe SMTP est passé séparément via la variable de modèle
recipient. L'en-tête To: dans le corps est du texte et n'est pas lié à l'acceptation
de RCPT TO par SMTP, donc il n'a pas besoin d'exister ou d'être accepté par le
serveur.
Forme fractionnée :
BDAT 70 LAST
Corps TLS : 69 premiers octets, se terminant par "bod"
Événement TLS : close_notify
Texte clair : dernier octet "y"
Suivi : NOOP
Vous pouvez vérifier manuellement que les deux laboratoires annoncent Exim, STARTTLS et CHUNKING.
printf 'EHLO lab-client.local\r\nQUIT\r\n' | nc -w 3 127.0.0.1 2525
printf 'EHLO lab-client.local\r\nQUIT\r\n' | nc -w 3 127.0.0.1 2526
Signaux attendus :
Exim
STARTTLS
CHUNKING
Vous pouvez également vérifier le chemin normal STARTTLS :
openssl s_client -starttls smtp -connect 127.0.0.1:2525 -crlf
openssl s_client -starttls smtp -connect 127.0.0.1:2526 -crlf
debugging/ et notes/source-walkthrough-progress.md.POC_2026_45185/
compose.yaml
images/ captures d'écran de validation nuclei locales
vulnerable/ Exim 4.99.2 + GnuTLS version de débogage
patched/ Exim 4.99.3 + GnuTLS version de débogage
nuclei-templates/ sous-module : espace de travail local des modèles nuclei
| Cible | Version | Backend TLS | STARTTLS | CHUNKING | Port | Résultat nuclei attendu |
|---|
| vulnérable | Exim 4.99.2 | GnuTLS | oui | oui | 127.0.0.1:2525 | correspond |
| corrigé | Exim 4.99.3 | GnuTLS | oui | oui | 127.0.0.1:2526 | pas de correspondance |