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

21Nails: Interview mit Eximentwickler Heiko Schlittermann

Liebe Linuxfans,

ein kleines Interview als Teaser für Euch, denn Heiko hat eingewilligt nächste Woche bei Linux am Dienstag aus dem Eximnähkästchen zu plaudern. Er steht allen Interessierten gern Rede und Antwort. Ich rate Euch dringend diesen Termin wahrzunehmen, denn in unserem Vorgespräch offenbarten sich wahre Schätze an Wissen, das ganz dringend in den Tux in Euch rein muß 😉

21Nails: Interview mit Eximentwickler Heiko Schlittermann

Die Firma Qualys hat Ihre Entdeckung 21Nails genannt, aber Sargnägel waren es mit Sicherheit nicht. Eximmitentwickler Heiko Schlittermann stand uns heute morgen dankenswerterweise für ein kurzes Interview zur Verfügung.

„21 Lücken, 7 Monate bis zur Behebung, wieviele schlaflose Nächte waren das?“

Die meiste Zeit nicht mehr als sonst auch, aber die letzten zwei Wochen
vor dem public release waren etwas anstrengend, da einige Bugs erst in
letzter Minute auftraten – wir konnten ja nicht großflächig testen.

„Was hat Euch(Devs) so lange Zeit gekostet? War es die Qualität des Fixes an sich, oder die Kommunikation mit Qualys?“

Das ist eine längere Geschichte. Anfangs hatten wir nur die Bugreports
von Qualys. In diesem Zusammenhang muss ich noch mal deren sehr
professionelles und freundliches Verhalten bei der Zusammenarbeit
hervorheben.

Wir hatten zeitnah begonnen, uns um die Probleme zu kümmern. Eigentlich
hatte ich das Taintwarn-Feature in der Pipeline, denn ich wollte das
noch vor Debian11 rausbringen und ein 4.95-Release wäre eigentlich im
November dran gewesen.

Leider wurde einer der Entwickler vom Burnout aus der Kurve geschossen.

Qualys unterstützte uns dann mit Ressourcen: Sie haben uns die Patches
geliefert, die wir *eigentlich* nur noch importieren mussten. Es gab
aber intern einige Diskussion über die technische Umsetzung: es ist
wieder seteuid()* dabei, das eigentlich nicht mehr im Exim-Code
auftauchen sollte
*) Seteuid => setzt die effektive UserID eines Prozesses auf einen bestimmten User, damit der Prozess nur noch mit dessen Rechten läuft und falls dieser Prozess exploitet wird, ist der Schaden minimiert. Hier vom User „Root“, mit dem der Prozess startet, zu User „Exim“.

Wir suchten nach anderen Lösungen, aber das funktionierte alles nicht,
und das hat Zeit gekostet.

Einige Patches mussten geringfügig umgebaut werden. Und dann blieben bei
der Testsuite einige Tests auf der Strecke, da mussten die Ursachen
gefunden werden und gefixt werden. Exim hat eine Regression-Testsuite, mit gut
1000 Testsscripts, die jeweils im Schnitt 2…6 Einzeltests enthalten.
(Anm.d.R. insgesamt knapp 4000 Tests)

Qualys hat uns die ganze Zeit wertvoll unterstützt.

Mein Fazit: Wir hätten die Patches importieren sollen, Testsuite anpassen, shippen.
Und uns dann anschließend um Verschönerungsmaßnahmen kümmern. Auf der
anderen Seite wurde uns von Qualys kommuniziert, dass ja noch nichts brennt
und es keine Anzeichen gibt, dass eine der gefundenen Vulnerabilites aktiv genutzt wird.

„Wie kam es dazu, daß die Deadline so knapp war? Die Distros hatten ja kaum Zeit die neuen Versionen zu testen, geschweige denn zu shippen. Bei Fedora fiel die Testversion mit dem Releasedate des Advisories zusammen.“

Soweit ich den Prozess bei oss-security* verstehe, ist 1 Woche Vorlauf für die Distros schon gut bemessen. 3 Tage werden angestrebt.
(* Anm.d.R. OSS-Security ist eine öffentliche Mailingliste zu Securitymeldungen auf der u.a. die großen Distributionen und andere Organisationen vertreten sind )

„Da bleibt nicht viel Zeit für Test. Hat sich im Ablauf des Teams etwas geändert durch die Herkulische Aufgabe? Seit Ihr jetzt für die Zukunft besser bewappnet?“

Lesson learned. See above 🙂

„In der Mailing sieht man jetzt wieder sehr viele Hilferufe wegen „Tainting“. Erklärst Du mal, wie es dazu gekommen ist.“

Nun. Wir haben das Konzept von „tainted data“ mit 4.94 eingeführt. Da
werden Daten, die „von außen“ kommen als nicht vertrauenswürdig
betrachtet, und können z.B. nicht verwendet werden, um Dateien zu
öffnen. Der Klassiker

data = ${lookup{$local_part}lsearch{/etc/exim/virtual/$domain}}

geht dann plötzlich nicht mehr. Die „$domain“ ist „tainted“.

Wer jetzt beim Update von < 4.94 auf 4.94.2 aktualisiert hat, stand
plötzlich vor einer Herausforderung. Die Konfig ist nicht mehr sicher
und Exim arbeitet nicht mehr wie gewohnt.

Auch darüber hatten wir intern viele Diskussionen. (Das ist auch ein
Grund, warum wir 4.95 noch nicht released hatten: weil ich der Meinung
war, dass das mit dem Tainted so nicht bleiben kann.) Bisher waren
Updates des Exim immer möglich, ohne die Konfiguration ändern zu müssen.

(Der einzige „breaking Change“ war das aus Sicherheitsgründen
vorgenommene Bereinigen der Umgebungsvariablen für Kindprozesse. Da
hatten wir keine Wahl.)

Zurück zur Frage: Ja, wer jetzt plötzlich von < 4.94 auf >= 4.94
aktualisiert hat, hat möglicherweise ein Problem. Um das zu mildern, haben
wir eine Main-Config-Option eingeführt: „allow_insecure_tainted_data“.
Diese Option ist aber *nicht* Bestandteil von 4.94.2. Es gibt die
Meinung, dass wir alte Versionen vor 4.94 eh nicht unterstützen, und die
die sich den Exim selber bauen, sind schon bei 4.94, haben also mit dem
Update kein Problem. Ist sicher diskutierbar…

Wer über seine Distro aktualisiert, hat kein Problem, wir haben Debian
beim Backport der Patches auf 4.92 unterstützt. Von den anderen Distros
wissen wir nichts, aber es sieht so aus, als hätten die das auch
irgendwie gelöst.

Wer von Debian 10 auf Debian 11 aktualisiert, hat auch kein Problem, weil
Debian freundlicherweise den oben erwähnten „taintwarn“ Patch mit
übernommen hat.

Hm. Zu viel Antwort für die kurze Frage…:)

„Letzte Frage: Wird es jetzt aus Deiner Sicht Zeit, die Beispiele in der Eximdoku zu überarbeiten und Tainting-sichere Beispiele anzuführen?“

Ja, definitiv ist da noch etwas dokumentarische Arbeit nötig. Jeder
ist eingeladen, sich daran zu beteiligen.

Die Beispiel-Config ist „tainting sicher“.

 

ROOT Exploits in Exim < 4.94.2

Ihr fragt Euch vermutlich, wieso sich so lange gebraucht habe, das zum Thema zu machen, weil die Nachricht ja gestern noch raus kam. Der Grund ist: Sichern, Suchen und Patchen was das Zeug hält.

ROOT Exploits in Exim < 4.94.2

Insgesamt sind es 21 Lücken, welche die Pentester von Qualys gefunden haben:

Summary
Local vulnerabilities
- CVE-2020-28007: Link attack in Exim's log directory
- CVE-2020-28008: Assorted attacks in Exim's spool directory
- CVE-2020-28014: Arbitrary file creation and clobbering
- CVE-2021-27216: Arbitrary file deletion
- CVE-2020-28011: Heap buffer overflow in queue_run()
- CVE-2020-28010: Heap out-of-bounds write in main()
- CVE-2020-28013: Heap buffer overflow in parse_fix_phrase()
- CVE-2020-28016: Heap out-of-bounds write in parse_fix_phrase()
- CVE-2020-28015: New-line injection into spool header file (local)
- CVE-2020-28012: Missing close-on-exec flag for privileged pipe
- CVE-2020-28009: Integer overflow in get_stdinput()
Remote vulnerabilities
- CVE-2020-28017: Integer overflow in receive_add_recipient()
- CVE-2020-28020: Integer overflow in receive_msg()
- CVE-2020-28023: Out-of-bounds read in smtp_setup_msg()
- CVE-2020-28021: New-line injection into spool header file (remote)
- CVE-2020-28022: Heap out-of-bounds read and write in extract_option()
- CVE-2020-28026: Line truncation and injection in spool_read_header()
- CVE-2020-28019: Failure to reset function pointer after BDAT error
- CVE-2020-28024: Heap buffer underflow in smtp_ungetc()
- CVE-2020-28018: Use-after-free in tls-openssl.c
- CVE-2020-28025: Heap out-of-bounds read in pdkim_finish_bodyhash()
Acknowledgments
Timeline

Davon konnten 4 Lücken genutzt werden um die Rechte zu Root auszuweiten und 3 für Remote-Code-Executions genutzt werden, was in der Kombination nichts anderes bedeutet, als daß die Angreifer die Server übernehmen können.

„We have not tried to exploit all of these vulnerabilities, but we successfully exploited 4 LPEs (Local Privilege Escalations) and 3 RCEs (Remote Code Executions):“

Ich vermute ja, daß diese Lücken durch eine automatische Code-Analyse gefunden wurden, da ich mir kaum vorstellen kann, das ein Mensch das alles so überblicken wird. Auch den Exim-Devs wurde nicht gesagt, wie die Lücken gefunden wurden. Aber auch hier die Vermutung, daß es mit automatischen Tools und sehr viel Erfahrung der Analysten geschafft wurde.

Auf der Exim-Mailingliste wurde dies von einigen negativ hervorgehoben, wobei man immer bedenken muß, daß alle Exim Entwickler auch noch ein Berufsleben haben. Wenn dann die Patche nicht mehr kaputt machen sollen, als die Lücken selbst, kann das schon ein bisschen dauern.

Ein bisschen gedauert hat es dann auch, bis z.b. Fedora die neue Exim Version ins Stable übernommen hat. Dies geschah erst durch Benutzerintenvention ( meine 😉 ) einen Tag nach der Veröffentlichung der Lücken. Für das im Endstadium befindliche Fedora 32 gab es den Fix nicht mehr, weswegen ich jedem nur raten kann, auf 33 zu updaten, wenn er Exim betreibt.