Vulnérabilité dans OpenSMTPD permettant l'exécution de code à distance avec des droits root

Dans le projet en développement du serveur de messagerie OpenBSD OpenSMTPD une vulnérabilité a été identifiée vulnérabilité critique (CVE-2020-7247), permettant d'exécuter à distance des commandes shell sur le serveur avec les droits de l'utilisateur root. La vulnérabilité a été découverte lors d'un audit de reprise effectué par la société Qualys Security (l'audit précédent d'OpenSMTPD a été réalisé en 2015, tandis que la nouvelle vulnérabilité est présente depuis mai 2018). Le problème a été corrigée se trouve dans la version d'OpenSMTPD 6.6.2. Tous les utilisateurs sont fortement conseillés de mettre à jour immédiatement (pour OpenBSD, le correctif peut être installé via syspatch).

Deux variantes d'attaque ont été proposées. La première variante fonctionne dans la configuration par défaut d'OpenSMTPD (acceptation des requêtes uniquement depuis localhost) et permet d'exploiter le problème localement, lorsque l'attaquant peut accéder à l'interface réseau locale (loopback) sur le serveur (par exemple, sur les systèmes d'hébergement). La seconde variante se manifeste lorsque OpenSMTPD est configuré pour accepter des requêtes réseau externes (serveur de messagerie acceptant du courrier extérieur). Les chercheurs ont préparé un prototype d'exploit qui fonctionne avec la variante d'OpenSMTPD incluse dans OpenBSD 6.6 ainsi qu'avec la version portable pour d'autres systèmes d'exploitation (testé sur Debian Testing).

Le problème est causé par une erreur dans la fonction smtp_mailaddr(), appelée pour vérifier la validité des valeurs dans les champs «MAIL FROM» et «RCPT TO», qui définissent l'expéditeur/le destinataire et sont transmises lors de la connexion au serveur de messagerie. Pour vérifier la partie de l'adresse e-mail qui précède le symbole «@», la fonction valid_localpart() est appelée dans smtp_mailaddr(), qui considère comme valides (MAILADDR_ALLOWED) les caractères «!#$%&’*?/^`{|}~+-=_», conformément aux exigences de la RFC 5322.
Cependant, l'échappement direct de la chaîne est effectué dans la fonction mda_expand_token(), qui ne remplace que les caractères «!#$%&’*?`{|}~» (MAILADDR_ESCAPE). Plus tard, la chaîne préparée dans mda_expand_token() est utilisée lors de l'appel de l'agent de livraison (MDA) via la commande 'execle(«/bin/sh», «/bin/sh», «-c», mda_command,…'. En cas de placement d'un message dans mbox via /bin/sh, la chaîne «/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}» est exécutée, où la valeur «%{mbox.from}» inclut les données échappées du paramètre «MAIL FROM».

L'échappement direct de la chaîne est effectué dans la fonction mda_expand_token(), qui remplace uniquement les caractères «!#$%&’*?`{|}~» (MAILADDR_ESCAPE). Par la suite, la chaîne préparée dans mda_expand_token() est utilisée lors de l'appel de l'agent de livraison (MDA) via la commande ‘execle(«/bin/sh», «/bin/sh», «-c», mda_command,…’. Dans le cas où le message est placé dans un mbox, la chaîne «/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}» est exécutée via /bin/sh, où la valeur «%{mbox.from}» inclut des données échappées du paramètre «MAIL FROM».

La vulnérabilité réside dans le fait que smtp_mailaddr() a une erreur logique qui, lorsqu'un domaine vide est transmis dans l'email, renvoie un code de vérification réussi, même si la partie de l'adresse avant « @ » contient des caractères non valides. Ensuite, lors de la préparation de la chaîne par la fonction mda_expand_token(), tous les caractères spéciaux possibles ne sont pas échappés, mais seulement ceux valides dans l'adresse email. Ainsi, pour exécuter sa commande, il suffit d'utiliser dans la partie locale de l'email le caractère « ; » et un espace, qui ne font pas partie de MAILADDR_ESCAPE et ne sont pas échappés. Par exemple :

$ nc 127.0.0.1 25

HELO professor.falken
MAIL FROM:
RCPT TO:
DATA
.
QUIT

Après cette session, OpenSMTPD exécutera une commande shell lors de la livraison dans mbox.

/usr/libexec/mail.local -f ;sleep 66; root

Cependant, les possibilités d'attaque sont limitées par le fait que la partie locale de l'adresse ne peut pas dépasser 64 caractères et que les caractères spéciaux ‘$’ et ‘|’ sont remplacés par « : » lors de l'échappement. Pour contourner cette limitation, on utilise le fait que le corps du message est passé après le lancement de /usr/libexec/mail.local via le flux d'entrée, c'est-à-dire qu'en manipulant l'adresse, on peut seulement lancer l'interpréteur de commandes sh et utiliser le corps du message comme un ensemble d'instructions. Comme les en-têtes SMTP sont spécifiés au début du message, il est proposé d'utiliser l'appel de la commande read dans une boucle pour les ignorer. L'exploit fonctionnel prend approximativement la forme suivante :

$ nc 192.168.56.143 25

HELO professor.falken
MAIL FROM:
RCPT TO:
DATA
#0
#1
…
#d
for i in W O P R; do
echo -n «($i) » && id || break
done > /root/x.»`id -u`».»$$»
.
QUIT

Source : opennet.ru

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster