STARTTLS met à niveau une connexion SMTP en clair vers TLS sur place, mais sur le port 25 la mise à niveau est opportuniste : le client ne la tente que si le serveur annonce 250-STARTTLS dans sa réponse EHLO, et si elle manque le client poursuit en clair. Ce « si annoncé » est la faiblesse. Deux attaques distinctes y vivent. La première est le dépouillement : une machine en position d'intermédiaire réécrit la réponse EHLO du serveur pour supprimer la capacité STARTTLS, de sorte que le pair ne se met jamais à niveau et envoie AUTH et MAIL en clair. La seconde est l'injection de commandes avant TLS : certains MTA et proxys terminant TLS n'écartent pas le tampon de réception en clair quand le handshake commence, de sorte que les commandes qu'un attaquant ajoute après STARTTLS (envoyées avant TLS) sont analysées comme si elles étaient arrivées à l'intérieur de la session chiffrée désormais de confiance.
Prérequis#
- Le dépouillement nécessite une position sur le chemin entre les deux pairs SMTP (redirection ARP/DNS sur le LAN, un amont malveillant, un saut de relais contrôlé). Il n'aide que là où TLS n'est pas obligatoire, ce qui est le cas par défaut pour le port 25 entrant.
- Confirmez que STARTTLS est réellement proposé et joignable avant de l'attaquer :
# does the server advertise and complete STARTTLS?
openssl s_client -starttls smtp -connect mail.victim.com:25 -crlf
# ... reaches a TLS handshake and cert => STARTTLS works and is a downgrade target
echo | openssl s_client -starttls smtp -connect mail.victim.com:25 2>/dev/null | openssl x509 -noout -subject
Un handshake abouti confirme que le TLS opportuniste est en jeu ; un serveur en clair uniquement n'a rien à dépouiller mais est déjà interceptable.
Dépouiller la capacité#
L'intermédiaire transmet le dialogue mais édite l'unique ligne qui propose la mise à niveau, de sorte que le test « STARTTLS est-il disponible ? » du client échoue :
# server actually sends:
250-mail.victim.com
250-STARTTLS <-- attacker deletes or mangles this line in transit
250 AUTH LOGIN PLAIN
# client sees no STARTTLS, stays in cleartext, and sends:
AUTH PLAIN AGpzbWl0aAB... <-- credential captured on the wire
La dégradation (réécrire 250-STARTTLS en 250-XXXXXXXX, ou la commande STARTTLS du client en XXXXXXXX, de sorte que le verbe soit méconnu et reçoive un 500) obtient le même résultat sans changer la longueur de ligne. Après le dépouillement, lisez l'AUTH/MAIL FROM en clair exactement comme dans authentification.
Injection de commandes avant TLS#
Ici vous ne dépouillez pas TLS ; vous faites passer clandestinement une commande à travers la frontière du handshake. Tout ce qui suit STARTTLS\r\n dans le même segment TCP est du texte en clair que le serveur devrait jeter, mais une implémentation vulnérable le conserve et l'exécute après le handshake, à l'intérieur du contexte authentifié/chiffré :
EHLO attacker.test\r\n
STARTTLS\r\nRSET\r\n <-- "RSET" (or MAIL FROM/AUTH) is buffered BEFORE TLS
<TLS handshake begins>
<-- after TLS, the buffered RSET runs as a trusted command
Remplacez RSET par une commande significative : injecter MAIL FROM/RCPT TO permet à un attaquant qui présente ensuite un certificat client ou profite d'une session de confiance d'ajouter en préfixe une transaction que le serveur attribue au canal sécurisé. Cette faille de mise en tampon a affecté plusieurs MTA et proxys de messagerie.
Suites#
- Après un dépouillement, vous disposez des identifiants et du contenu des messages en clair : injectez les identifiants dans l'accès à la boîte aux lettres et dans une réutilisation plus large.
- Avec l'injection avant TLS, vous pouvez injecter des commandes dans la session que le serveur considère de confiance ; gardez ceci conceptuellement distinct du SMTP smuggling, qui abuse de l'analyse de la fin de données entre deux serveurs plutôt que de la frontière TLS sur une connexion.