TLS: Reaktionen auf den ALPACA Attackvector

Vor ein paar Tagen wurde eine Cross-Protokoll-Attacke mit TLS bekannt, bei der auch bekannte OpenSource-Dienste wie Exim, Dovecot, Proftpd, Courier, Sendmail usw. usw. als „Bande“ beteiligt sind.

TLS: Reaktionen auf den ALPACA Attackvector

Wer die Attacke verstehen möchte, oder ganz genau hinsehen will, findet hier alles nötige: https://alpaca-attack.com/

Alle, die sich mit einem kleinen Beispiel begnügen können, hier ein Beispiel wie die Attacke ablaufen soll:

Angreifer baut eine Webseite.
Opfer besucht Webseite.
Angreifer erzeugt einen AJAX Request zu einer Opfer-Domain
Angreifer fügt einen oder mehrere spezielle Headerzeilen in den AJAX hinzu
Opferbrowser sendet Ajax an Zielserver
Angreifer lenkt ( als Man-in-the-Middle-Angriff ) Datenpaket auf einen anderen Dienst mit dem gleichen TLS-Zertifikat um
Dienst nimmt den HTTP Request zeilenweise an
Dienst reagiert auf die speziellen Headerzeilen

Was dann passiert hängt vom Dienst ab, der als Bande missbraucht wurde. Es sind Reflectionattacks möglich, bei dem dem Browser des Opfers über den Dienst als Bande z.b. Javascript untergejubelt werden soll, oder es in sehr speziellen Fällen Zugriffe auf den zweiten Dienst gibt ( zb. wenn die Benutzervalidierung nach IP und TLS-Cert geht ).

Das sieht dann in etwa so aus:

# nc testserver 25
220 testserver.de ESMTP Exim 4.94.2 Fri, 11 Jun 2021 09:45:34 +0200
GET / HTTP/1.1
500 unrecognized command
Host: target.domain
500 unrecognized command
HELO opfer.server
250 testserver.de Hello opfer.server [x.x.x.x]
MAIL FROM: <script>Alert()</script>
501-<script>Alert()</script>: malformed address: Alert()</script> may not follow <script>
501 Too many syntax or protocol errors

Um die markierte Zeile geht es meistens, denn wenn der Browser das Ergebnis jetzt im Context der Webseite anzeigt, dann wird das ungefilterte Javascript ausgeführt.

Bitte habt ihm Hinterkopf, das dies hier nur ein simplifiziertes Beispiel ist, um sich den Vorgang vorzustellen. In der Realität ist der Angriff ungleich komplexer, weil der Browser mitspielen muß, es einen Man-in-the-Middle-Angriff geben muß, es möglich sein muß, die Antwort im Context einer Webseite auszuführen, die nicht unter Kontrolle des Angreifer steht usw. usw. Trivial geht anders!

OpenSource-Dienste reagieren

Obwohl Dovecot als POP3/IMAP Server eigentlich gar nicht betroffen ist, hat das Dovecot Security Team um Timo Sirainen gestern bereits reagiert und angekündigt, die Fehlertoleranzgrenze zu erniedrigen und beim Vorfinden eines HTTP Headers sofort die Verbindung zu terminieren.

Auf der Eximmailingliste fand gestern eine ähnliche Diskussion statt, nur das Exim bereits lange über eine Runtime-Konfigurationsoption verfügt, die jeder Serveradmin jetzt einsetzen sollte:

smtp_max_synprot_errors = 0

In weniger als 18h kamen auf einem System ohne relevanten Mailverkehr folgende HTTP-Anfragen auf dem Mailserver zusammen:

2021-06-10 17:09:54 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „HEAD / HTTP/1.0“, NULL)
2021-06-10 17:09:55 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 17:09:56 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „GET /c/version.js HTTP/1.1“, NULL)
2021-06-10 17:09:58 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „GET /streaming/clients_live.php HTTP/1.1“, NULL)
2021-06-10 17:09:59 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/version.js HTTP/1.1“, NULL)
2021-06-10 17:10:01 SMTP call from [134.122.7.20] dropped: too many syntax or protocol errors (last command was „GET /stream/live.php HTTP/1.1“, NULL)
2021-06-10 17:17:30 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „HEAD / HTTP/1.0“, NULL)
2021-06-10 17:17:31 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 17:17:32 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 17:17:34 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /c/version.js HTTP/1.1“, NULL)
2021-06-10 17:17:35 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /streaming/clients_live.php HTTP/1.1“, NULL)
2021-06-10 17:17:37 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/version.js HTTP/1.1“, NULL)
2021-06-10 17:17:39 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /client_area/ HTTP/1.1“, NULL)
2021-06-10 17:17:40 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/ HTTP/1.1“, NULL)
2021-06-10 17:17:42 SMTP call from [138.197.154.233] dropped: too many syntax or protocol errors (last command was „GET /stream/live.php HTTP/1.1“, NULL)
2021-06-10 19:08:50 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „HEAD / HTTP/1.0“, NULL)
2021-06-10 19:08:51 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 19:08:51 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 19:08:51 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /c/version.js HTTP/1.1“, NULL)
2021-06-10 19:08:52 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /streaming/clients_live.php HTTP/1.1“, NULL)
2021-06-10 19:08:52 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/version.js HTTP/1.1“, NULL)
2021-06-10 19:08:53 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /client_area/ HTTP/1.1“, NULL)
2021-06-10 19:08:53 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/ HTTP/1.1“, NULL)
2021-06-10 19:08:53 SMTP call from [46.101.86.104] dropped: too many syntax or protocol errors (last command was „GET /stream/live.php HTTP/1.1“, NULL)
2021-06-10 19:54:12 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „HEAD / HTTP/1.0“, NULL)
2021-06-10 19:54:13 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 19:54:14 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „GET /c/version.js HTTP/1.1“, NULL)
2021-06-10 19:54:15 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „GET /streaming/clients_live.php HTTP/1.1“, NULL)
2021-06-10 19:54:17 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/version.js HTTP/1.1“, NULL)
2021-06-10 19:54:18 SMTP call from [134.122.5.182] dropped: too many syntax or protocol errors (last command was „GET /stream/live.php HTTP/1.1“, NULL)
2021-06-10 20:21:18 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „HEAD / HTTP/1.0“, NULL)
2021-06-10 20:21:19 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „GET /system_api.php HTTP/1.1“, NULL)
2021-06-10 20:21:20 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „GET /c/version.js HTTP/1.1“, NULL)
2021-06-10 20:21:21 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „GET /streaming/clients_live.php HTTP/1.1“, NULL)
2021-06-10 20:21:23 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „GET /stalker_portal/c/version.js HTTP/1.1“, NULL)
2021-06-10 20:21:24 SMTP call from [64.225.63.33] dropped: too many syntax or protocol errors (last command was „GET /stream/live.php HTTP/1.1“, NULL)
2021-06-11 02:27:28 SMTP call from [192.241.214.95] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 02:27:30 SMTP call from [192.241.214.95] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 02:27:30 SMTP call from [192.241.214.95] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 02:27:30 SMTP call from [192.241.214.95] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 04:46:17 SMTP call from 92.118.160.1.netsystemsresearch.com [92.118.160.1] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 08:34:31 SMTP call from scanner-21.ch1.censys-scanner.com [162.142.125.128] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 08:34:36 SMTP call from scanner-21.ch1.censys-scanner.com [162.142.125.128] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 08:34:49 SMTP call from scanner-21.ch1.censys-scanner.com [162.142.125.128] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 08:34:50 SMTP call from scanner-21.ch1.censys-scanner.com [162.142.125.128] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)
2021-06-11 08:47:19 SMTP call from [45.113.70.146] dropped: too many syntax or protocol errors (last command was „GET / HTTP/1.1“, NULL)

Dies sind noch keine ALPACA Angriffe, das ist nur der alltägliche Wahnsinn mit dem man sich als Server so rumschlagen muß.

Proftpd hat bereits vorher reagiert und ist ab Version ProFTPD ≥1.3.5e stärker gegen den Angriff abgehärtet, aber noch nicht 100% immun.

Chromium und Firefox werden Ihre Browser auch abhärten, so daß es schwieriger wird, per Ajax andere Dienste zu kontaktieren. Da aber viele Firmenserver HTTP Dienste auf nicht Standardports anbieten , könnte das im Detail schwierig werden.

Verbesserungsvorschläge zur Absicherung von hauseigenen Pakete für Exim, Dovecot und Co. liegen bei Fedora/Red Hat bereits vor, müssen aber noch diskuttiert werden.

UPDATE

Wer sich die ALPACA Exploits mal ansehen will, bitte schön: https://github.com/RUB-NDS/alpaca-code/tree/master/exploits

ProFTPd – mod_copy Exploit … schon wieder

Keine gute Woche für altgediehnte  Linuxservices wie Exim und ProFTPd 🙁 ProFTPd hat einen Bug im Rechtemanagement von mod_copy, den man benutzen kann um als (anonymer) Benutzer sämtliche Dateien des Servers überschreiben kann: CVE-2019-12815

Schon wieder!

Es gibt zwar seit dem 17.7 einen Patch dafür, aber das ist nicht unbedingt dem profimäßigen Verhalten vom ProFTPd Team zu verdanken, sondern dem Debian-Security-Team, daß dem ProFTPd Team wohl mal in den Arsch getreten hat, wie diese Zeitangabe zeigt:

Timeline:

  • 28.09.2018 Reported to ProFTPd security@, ProFTPd asking for clarifications
    12.06.2019 Reported to Debian Security Team, replies by Moritz & Salvatore
    28.06.2019 Deadline for public disclosure on 28.07.2019 announced
    17.07.2019 Fix published by ProFTPd

2015 gab es so einen Fehler schon einmal in dem gleichen Modul „mod_copy“. Dies dürfte dazu geführt haben, daß es in der Default-Konfig von Fedora gleich mal auskommentiert ist. Normalerweise braucht man das auch nicht.

Das die Security-Typen bei ProFTPd für mich ein Haufen ignoranter Besserwisser sind, kann ich schon damit belegen, daß ich für den 29C3 einen Vortrag zum Thema „Chroot umgehen mit Links“ eingereicht hatte. Das eigentliche Problem hat das Security Team übrigens mit den Worten „Uns doch egal, haben wir in der Doku drauf hingewiesen“ abgewimmelt, nur im es dann Jahre später doch zu beheben.

Es muß offensichtlich erst ein namhafter Mitmensch kommen, damit dem geglaubt wird. Dabei hatte ich denen sogar einen Patch geschrieben, der das erfolgreich verhindert hat. Am Ende haben Sie es dann tatsächlich wie von mir vorgeschlagen mit einer entsprechenden Option „schaltbar“ gemacht. Ihr dürft mir glauben, gut zu sprechen bin ich auf die nicht und alleine auch nicht, wie man sieht!

 

 

Proftpd Bugfix macht Login unmöglich

Die späte Rache ereilte vermutlich die Entwickler vom allseits beliebten FTP-Server Proftpd. Um das Problem zu verstehen muß man etwas ausholen und in die Vergangenheit des Servers zurückgehen:

Spätestens im Jahr 1999 wurde mit der Version 1.2.0pre9 die Funktion eingebaut, daß FTP-Benutzer die einloggen, in einer Chroot gefangen werden, damit sie nur auf ihr Homeverzeichnis zugreifen können. Die Option hies „DefaultRoot“. In der Doku zu der Option findet sich folgender Hinweis:

When the specified chroot directory is a symlink this will be resolved to it’s parent
first before setting up the chroot. This can have unwanted side effects. For example if
a user has write access to the symlink he could modify it so that it points to ‚/‘

Meint auf Deutsch in Kurzform, daß wenn das Homeverzeichnis eigentlich ein Symlink ist, diesem gefolgt wird und das, wo der rauskommt, das neue „/“ von der Chroot ist.

Im Klartext: wenn  /home/testuser ein Symlink auf  „/“  ist, dann ist der User nicht in /home/testuser gefangen, sondern kann sich frei im normalen „/“ Verzeichnis rumtreiben. Ein Sicherheitsloch, daß locker mal 20 Jahre existiert hat.

Die FAQ von Proftpd meint zu dem Thema Chroot, daß man als Admin gefälligst dafür Sorgen soll, daß User das nicht anlegen/ändern können und halt kein Sicherheitsloch entstehen soll. Die schoben die Verantwortung also an die Admins weiter, was zu einem bestimmten grad ok war, aber dann darf man andere Sachen gar icht erst erlauben.

Mein Teil an der Story

In 2012 habe ich den Entwicklern von Proftpd einen Patch für proftpd geschickt, der genau dies Problem adressiert hat und keine Nebenwirkungen hatte. Der Patch prüft bei jedem Zugriff, ob sich in dem Pfad ein Symlink eingenistet hatte. So konnte es keine RACE Condition geben, bei der der Benutzer durch schnelles löschen und SymLink anlegen, die Sicherungsmaßnahmen umgehen konnte. Kurzfassung: Der Patch wurde mit : „Nicht unser Problem, siehe FAQ “ abgelehnt. Was sich jetzt als tragisch herausstellt. Besonders tragisch, da für den 29C3 in 2012 ein Vortrag zu dem Thema von mir eingereicht wurde.

Das Jahr 2016

In 2016 hat es dann endlich jemand geschafft, die Entwickler zu einer Option zum Checken von Symlinks im Pfad zu nötigen. Herzlichen Dank dafür, keine Ahnung wie Du das geschafft hast! Klasse!

Das Jahr 2017

Nun konnte ja nicht sein, was nicht sein durfte, in der Routine zum Checken der Symlinks wurde ein Sicherheitsloch entdeckt ( Hämischer Kommentar: Told you so ! ) und diesem wurde die CVE-2017-7418 zugeteilt.

Nun gabs es dieser Tage den Patch zu dieser Lücke im Server und damit das obligatorische Update auf den Produktivsystemen. Keine große Sache, sollte man denken. Tja, wer hat es geraten ? Auch diese Routine failed. Die hat das Sicherheitsproblem auf einer völlig neuen Ebene gelöst: Es kann sich kein Virtueller FTP-User mehr einloggen 😀

Ursache ist das hier:

[pid 32571] setresgid(-1, 99, -1)       = 0
[pid 32571] setresuid(-1, 99, -1)       = 0
[pid 32571] setresuid(-1, 0, -1)        = 0
[pid 32571] setresgid(-1, 1001, -1)     = 0
[pid 32571] setresuid(-1, 1000, -1)     = 0
[pid 32571] lstat("/", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
[pid 32571] lstat("/opt", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[pid 32571] lstat("/opt/root", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[pid 32571] lstat("/opt/root/home", {st_mode=S_IFDIR|0755, st_size=20480, ...}) = 0
[pid 32571] lstat("/opt/root/home/testuser", {st_mode=S_IFDIR|0750, st_size=4096, ...}) = 0
[pid 32571] lstat("/opt/root/home/testuser/public_html", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
...
[pid 32571] geteuid()                   = 1000
[pid 32571] setresuid(-1, 0, -1)        = 0
[pid 32571] setresgid(-1, 99, -1)       = 0
[pid 32571] setresuid(-1, 99, -1)       = 0
[pid 32571] setresuid(-1, 0, -1)        = 0
[pid 32571] setresgid(-1, 0, -1)        = 0
[pid 32571] setgid(1001)                = 0
[pid 32571] geteuid()                   = 0
[pid 32571] setresgid(-1, 99, -1)       = 0
[pid 32571] setresuid(-1, 99, -1)       = 0
[pid 32571] lstat("/opt/root/home/testuser/public_html", 0x7ffee3d84dd0) = -1 EACCES (Permission denied)

Für die Laien unter Euch, das ist der Auszug eines STRACE Logfiles. Darin finden wir alle Befehle die der Prozess ausgeführt hat ( API-Calls , nicht Bashkommandos 😉 ) . Man sieht deutlich das im ersten Block mit einer UID/GID von 1000/1001 auf das Homeverzeichnis des Benutzers zugegriffen wird, weil der Prozess entsprechend seine UID/GID ändert. Das ist RICHTIG so.

Was falsch ist, daß er das nicht auch beim zweiten Block tut. Hier ist die UID des Prozesses (proftpd) statt 1000, nur 99, was dem User NOBODY entspricht. Das ist der User, zu dem Prozesse werden sollen um Ihre Rechte zu verlieren um im Falle eines Sicherheitsbruches den Schaden zu begrenzen. (@Team: Der Teil hat 1a funktionert. Ohne Logins keine Bedrohung mehr) . Natürlich müßte auch hier die UID/GID auf 1000/1001 gesetzt werden, damit man an seine Dateien rankommt, denn normalerweise haben Verzeichnisse wie „/home/testuser“ einen chmod von 700, damit nur der User drankommt.

20 Jahre bis Problem akzeptiert. 4 Jahre bis zum Fix und nur 6 Monate bis zum Totalausfall der Server. Eine Glanzleistung sonders gleichen. Hätte man meinen Patch in 2012 nicht todgeredet, wäre uns das erspart geblieben 🙂 Da der Vortrag abgelehnt wurde, ging das Thema am 29C3 leider unter und so könnten die Jungs und Mädels vom CCC unabsichtlich auch dran beteiligt gewesen sein 😉  Tja, so ist das Leben.

Kleiner Disclaimer:

Es hängt ein bisschen von der Serverkonfiguration ab. Wer keine Datenbank benutzt, sondern nur reale User, der hat das Problem den bisherigen Infos nach nicht. Wer „AllowChrootSymlinks on“ aktiviert hat ( was der Default ist) hat auch kein Problem mit dem Login, wohl aber mit dem Umstand, daß er/sie ein angreifbares System hat ( siehe oben ) das ganz schnell gehackt werden kann.