Schwachstelle in OpenSMTPD ermöglicht Remote-Codeausführung mit Root-Rechten

Im entwickelten Projekt OpenBSD-Mailserver OpenSMTPD entdeckt kritische Sicherheitsanfälligkeit (CVE-2020-7247), die es ermöglicht, Shell-Befehle auf dem Server mit Benutzerrechten des root-Kontos auszuführen. Die Schwachstelle wurde während eines erneuten Audits entdeckt, das von der Firma Qualys Security durchgeführt wurde (das vorherige Audit von OpenSMTPD wurde im Jahr 2015 durchgeführt, und die neue Schwachstelle besteht seit Mai 2018). Das Problem behoben betrifft die Version von OpenSMTPD 6.6.2. Allen Benutzern wird dringend empfohlen, das Update umgehend zu installieren (für OpenBSD kann das Aktualisierungs-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 die Möglichkeit hat, auf das lokale Netzwerk-Interface (Loopback) auf dem Server zuzugreifen (z. B. auf Hosting-Systemen). Die zweite Variante tritt auf, wenn OpenSMTPD so konfiguriert ist, dass externe Netzwerk-Anfragen angenommen werden (ein Mailserver, der externe E-Mails empfängt). Die Forscher haben einen Exploit-Prototyp entwickelt, der sowohl mit der Version von OpenSMTPD aus OpenBSD 6.6 als auch mit der portablen Version für andere Betriebssysteme (getestet in Debian Testing) erfolgreich funktioniert.

Das Problem wird durch einen Fehler in der Funktion smtp_mailaddr() verursacht, die aufgerufen wird, um die Korrektheit der Werte in den Feldern "MAIL FROM" und "RCPT TO" zu überprüfen, die den Absender/Empfänger definieren und im Laufe der Verbindung mit dem Mailserver übermittelt werden. Zur Überprüfung des Teils der E-Mail-Adresse, der vor dem Zeichen "@" steht, wird in smtp_mailaddr() die Funktion
valid_localpart() aufgerufen, die die Zeichen "!#$%&’*?/^`{|}~+-=_" als zulässig betrachtet (MAILADDR_ALLOWED), gemäß den Anforderungen der RFC 5322.

Dabei wird die direkte Escape-Umwandlung des Strings in der Funktion mda_expand_token() durchgeführt, die nur die Zeichen "!#$%&’*?`{|}~" ersetzt (MAILADDR_ESCAPE). In der Folge 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 eine mbox gelegt wird, wird der Befehl " /usr/libexec/mail.local -f %%{mbox.from} %%{user.username}" ausgeführt, wobei der Wert "%{mbox.from}" die maskierten Daten aus dem Parameter "MAIL FROM" enthält.

Die zentrale Schwachstelle besteht darin, dass smtp_mailaddr() einen logischen Fehler aufweist, aufgrund dessen 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 der Zeichenfolge durch die Funktion mda_expand_token() werden nicht alle möglichen Spezialzeichen der Shell maskiert, sondern nur die im E-Mail-Adresse erlaubten. Daher reicht es aus, in der lokalen Teil der E-Mail Zeichen wie „;“ und Leerzeichen zu verwenden, die nicht in der MAILADDR_ESCAPE-Set 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 beim Zustellen an mbox über die Shell den Befehl ausführen

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

Dabei sind die Angriffsmöglichkeiten darauf beschränkt, dass der lokale Teil der Adresse 64 Zeichen nicht überschreiten kann und die Sonderzeichen ‘$’ und ‘|’ beim Maskieren durch „:“ ersetzt werden. Um diese Einschränkung zu umgehen, wird der Fakt genutzt, dass der Text der E-Mail nach dem Start von /usr/libexec/mail.local durch den Eingabestrom übergeben wird, d.h. durch Manipulationen mit der Adresse kann nur der Shell-Interpreter sh gestartet und der Text der E-Mail als Befehlssatz verwendet werden. Da am Anfang der E-Mail die SMTP-Header angegeben werden, wird empfohlen, den Befehl read in einer Schleife aufzurufen, um sie zu überspringen. Der funktionierende Exploit sieht ungefähr so aus:

$ 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

Quelle: opennet.ru

60GB SSD 8Gb DDR4