Exim < 4.92 mit CVE-2019-10149

Jetzt muß ich es Euch doch erzählen, wo ich doch dachte, es dauert noch länger bis die Katze aus dem Sack ist. Ok, Exim < 4.92 hat eine schwerwiegende Sicherheitslücke, die man auch noch trivial ausnutzen kann: CVE-2019-10149

Um die Schwachstelle wurde viel Wirbel gemacht, dummerweise bekam bislang niemand die Zähne auseinander, ob man das auch ohne Update abwehren kann. Schauen wir uns mal an worum es überhaupt geht.

Was ist der triviale Exploit?

Es reicht, wenn man als lokaler Angreifer eine Email mit dem Sendmailersatz von Exim an „<${run{bash}}@zieldomain.de>“ sendet. Im Augenblick wo die zugestellt wird, wird der eingebettete Befehle (hier bash) als Root ausgeführt.

Das ganze kann man ggf. auch per Remote ausführen, so daß es eine richtig fiese Schwachstelle ist. Betroffen sind aber nur Versionen  > 4.87 < 4.92 . Dazu müssen aber diverse Dinge in der Config erlaubt sein, was in der Defaultkonfig nur teilweise der Fall ist. z.b. kann man keine „/“ in dem Befehl unterbringen, weil das unerlaubte Zeichen sind. Das schränkt den Angreifer natürlich stark sein.

Da selbst auf der Eximliste bis heute viel Geheimniskrämerrei im Spiel war, hier die ebenso triviale Gegenmaßnahmen:

Gegenmaßnamen

Einfach kein „$“ in Emailadressen erlauben 😀 Das war es. Da fiel mir nur ARGS zu ein 😀

Das hier kommt in Eure Exim Konfiguration rein, dann Exim neu starten:

acl_check_rcpt:

deny message = Restricted characters in address
domains = +local_domains
local_parts = ^[.] : ^.*[\$@%!/|]

deny message = Restricted characters in address
domains = !+local_domains
local_parts = ^[./|] : ^.*[\$@%!] : ^.*/\\.\\./

….

acl_check_mail:

drop message = Restricted characters in address
condition = ${if match{$sender_address}{\N.*\$.*run.*\N}{1}{0}}

# WICHTIG: Vor dieser Anweisung reinschreiben, sonst Essig!

accept hosts = +relay_from_hosts

Das würgt den Angreifer ab, bevor die Email zugestellt wird.

Die bessere Gegenmaßnahme wäre natürlich auf einen aktuelleren Exim umzusteigen. Aber wie das so ist, es gibt halt immer „Gründe“ warum und wieso was nicht aktualisiert werden kann.

Keiner bekommt die Zähne auseinander…

Was mich am allermeisten an der Lücke nervt ist, daß diese billige Gegenmaßnahme im Advisory von Qualys und in den Hinweisen vom Exim Team nicht vorkommen. Bei den Exim Leuten kann ich es noch verstehen, weil die den Bug selbstständig schon Anfang des Jahres gefixt hatten und halt mit Recht sagen können: Mach halt Updates.

Bei Qualyssieht anders aus, die schreiben :

As per the distros list policy:

Below is an abridged version of our advisory (with all the vulnerability
details, but without exploitation details); we will publish the complete
version in 24 hours, or as soon as third-party exploits are published,
whichever happens first.

We believe that it makes no sense to delay this any longer than that:
this vulnerability is trivially exploitable in the local and non-default
cases (attackers will have working exploits before that, public or not);
and in the default case, a remote attack takes a long time to succeed
(to the best of our knowledge).

Schön das Ihr den Exploit weggelassen habt, wie wär es mal mit dem Workaround, so das die guten Jungs einen kleinen Vorsprung haben?  Und dieser kryptische Hinweis „a remote attack takes a long time to succeed“ meint übrigens, das man seinen Exim mal alle 24h neu starten sollte, weil es da wohl irgend einen Scheiß mit „Teergruben“ gibt.

Das sind i.d.R. Spamfallen, die so langsam antworten, daß der Angriff des Angreifers einfach zäh wie in einer Teergrube abläuft, bis hin zu „gar nicht voran kommt“. So was in der Art nutzen die Angreifer hier aus. Daher einmal im Cron „killall -9 exim; systemctl restart exim“ per Cron: Fertig.

The Revenge of Mariadb IV

Es ist mal wieder Zeit für eine MariaDB Geschichte. Keine Panik, die wird nicht wieder biblisch werden 🙂

Es war mal wieder Zeit für ein OS-Upgrade

Mittlerweile waren drei OS-Releases ins Land gegangen und eine sich anbahnende Sicherheitslücke im Exim .. PSSST! Ich habe sie Euch nicht verraten. Tut so, also wenn Ihr nächste Woche das erste mal davon gelesen habt, ja? 😉 .. zwang zu einem schnellen Update auf eine nicht betroffene Version. Fedora 29 sollte es sein 😉

Nun, glücklicherweise war auch ein anderer Testserver noch auf der gleichen alten OS Release, so daß er als Testlauf herhalten durfte. Dieser Test lief ausgesprochen positiv ab, um genau zu sein, makellos. Daher wurde kürzestfristig entschieden, auch den eigentlichen Kandidaten auf die gleiche Art zu updaten. Ein Snapshot der VM und 30 Minuten später  war das Update komplett und der Server startete wieder.

Mailserver, Webserver, IMAP-Server, diverse Dienste liefen. Was natürlich nicht lief war die MariaDB .. Ätzzz. N I C H T  S C  H O N  W I E D E R!   Auch gutes Zureden, energisches Nachtreten mit systemctl änderte nichts an diesem Status, der Datenbankserver startete nicht.

Same procedure als last year, Miss Sophie?

Leider nein. Letztes mal hatte sich bekanntlich ein Konfigfile des Systemd geändert, so daß die zum Start nötigen Limits nicht gesetzt wurden. Natürlich wurde der DIFF Test vom letzten mal auch wieder angewendet, zeigte aber keinen Unterschied an. Also mußte die gute alte Methode „Start den Dienst von Hand, dann bekommst Du Infos“ herhalten.

Wie macht man das?

Wir schauen uns mal an, was der Systemd so starten wollen würde:

cat /usr/lib/systemd/system/mariadb.service

Da findet dann das hier:

ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf
# Note: we set –basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/libexec/mysqld –basedir=/usr $MYSQLD_OPTS $_WSREP_NEW_CLUSTER
ExecStartPost=/usr/libexec/mysql-check-upgrade

Das POST können wir ignorieren, soweit kommen wir nicht, bleiben nur Pre und der eigentliche Dienststart.

Das in den einschlägigen Envfiles  unter /etc/sysconfig/ nichts steht, reicht also ein :

/usr/libexec/mysqld –basedir=/usr

für den Test aus. Ja super.. eine Fehlermeldung:   Can’t set requested open_files (1024) to 2000 …

Das lag an dem ulimit hier:

# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32088
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 32088
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

Damit kann nicht mal die minimale Version der Datenbank starten 😉 Ergo geben wir ein: „ulimit -n 99999“ und starten es nochmal und siehe da, es hat sich doch wieder was geändert:

2019-06-04 23:13:41 0 [ERROR] /usr/libexec/mysqld: unknown variable ‚innodb_additional_mem_pool_size=50M‘
2019-06-04 23:13:41 0 [ERROR] Aborting

Wenn man denn endlich mal in Logfile schaut, sieht man dort auch die Warnung, daß sich das ja mal ändern könnte. Wer rechnet schon mit damit, daß da jemand mal Ernst macht 😉

2019-05-26 09:18:16 b753fd80 InnoDB: Warning: Using innodb_additional_mem_pool_size is DEPRECATED. This option may be removed in future releases, together with the option innodb_use_sys_malloc and with the InnoDB’s internal memory allocator.
2019-05-26 9:18:16 3075734912 [Note] InnoDB: innodb_empty_free_list_algorithm has been changed to legacy because of small buffer pool size. In order to use backoff, increase buffer pool at least up to 20MB.

Merke, erst ins Datenbank Log schauen, dann Server updaten!

Drei OS-Versionen sind dann vielleicht doch etwas happig bei einem Update. Diese Option findet man, so man sie gesetzt hat, in der Datei /etc/my.cnf . Anweisung auskommentieren, diesmal Datenbank über systemctl starten und läuft wieder 🙂

Und hier dachte ich eigentlich, ist die Story zu ende… war sie aber nicht!

Der an diesem Master angeschlossene Replications Elf ( Sklave sagt man im PCSG nicht mehr 😉 ) mochte die Replikationsblöcke vom Master nicht mehr lesen, weil Checksumme unbekannt! Das lag daran, daß der Replikations Elfe eine ältere Datenbankversion laufen hatte, da LTS. Einer langen Suche kurzes Ende:

Elfen anhalten: mysql -p -e „stop slave
auf den Master connecten: mysql -p -e „set global binlog_checksum=’NONE‘; SHOW MASTER STATUS;“ ausführen.

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000138 | 521505   |              |                  |
+------------------+----------+--------------+------------------+

Datenbank auf dem Master dumpen, auf den Elfen kopieren. Auf dem Elfen die Datenbank wipen, den SQL Dump einspielen.

Auf dem Elfen : mysql -p -e „change master to MASTER_LOG_FILE=’mysql-bin.000138′, MASTER_LOG_POS=521505;start slave

Sollte wieder gehen. Ging nicht.. Neuer Fehler! Statt:

Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Slave can not handle replication events with the checksum that master is configured to log; the first event 'mysql-bin.000136' a'

gabs jetzt :

Last_IO_Errno: 1045
Last_IO_Error: error connecting to master 'test@masterserver:3306' - retry-time: 60  retries: 86400

Er zum Geier ist „TEST“ !?

Tja, keine Ahnung wie das passieren konnte, aber der „change master to …“ Befehl hatte den Replikationsusernamen durch „test“ ersetzt! Einfach so! Passwort war ok, Servername war ok, Username weg! Wie geil ist das denn ?!?!?

Also nochmal mit dem change master an den Elfen ran:

/usr/bin/mysql -p -e „stop slave;;CHANGE MASTER TO MASTER_USER=’myreplicationusername‘,MASTER_PASSWORD=’MeinPasswort‘;start slave

Da machste was mit als Admin … Ich wollte doch nur den Exim abdichten, nicht das Rad neu erfinden! Naja, jetzt gehts ja erstmal wieder 🙂 Und bevor noch einer fragt, nein, der Server hatte extern nur Port 25 zu bieten, deswegen ja auch das Update 😉

Linux: auf SD-Karten installieren, gut oder schlecht?

Einem kleinen Experiment gleich, habe ich am Samstag Fedora Linux auf einem i3 Surface Tablet auf einer SD-Karte installiert, da der Besitzer seine WIN-Installation nicht direkt zerstören wollte. Das hat an sich auch geklappt. Leider gab es da ein „kleines“ Problem …

Linux auf SD-Karten und USB-Sticks

Bleiben wir erstmal beim Surface, das normalerweise eine SSD, einen USB-Slot und einen SD-Kartenslot aufweist. Die Installation von Linux auf die SSD ist natürlich die favorisierte Installationsmethode. Jetzt kann man Linux aber auch auf die SD-Karte oder einen USB-Stick installieren und wenn man es nur mal ausprobieren will, ist das ein legitimes Vorgehen. Grub hat das Dualboot auch im ersten Versuch sauber hinbekommen, klasse!

Nun hatte der Besitzer des besagten i3 Surface Pro eine Installation auf die SD-Karte gewünscht. Den Hinweis, daß es auf einer SD Karte natürlich nicht so schnell gehen würde, wie auf einer SSD, hat er akzeptiert. Das Gerät verließ unseren LPD Stand dann auch mit einem aktuellen Fedora 29, RPMFusions MPV, Thunderbird und anderen Apps, was man halt so braucht, mit der Auflage Zuhause dann mal ein Update laufen zu lassen, weil das SD-bedingt ewig dauern würde. Natürlich war es am Mittwoch dann nicht aktualisiert, also haben wir das nachgeholt. Das hätten wir besser nicht gemacht 🙁

Das Update war 1 GB groß und der Download der RPMs noch das kleinste Problem. Die Energieeinstellungen von Gnome waren leider so eingestellt, daß das Gerät irgendwann ausgeht. Da das i3 Surface von 2013 vom aktuellen Kernel voll unterstützt wird, hätte das eigentlich kein Problem sein sollen, zumal ja gerade eh ein Update per DNF läuft. Da würde man annehmen, daß das Abschalten des Bildschirms nicht zu Problemen führt, weil ein Updateinhibitor gesetzt wird. Führte es aber!

Es kam wies kommen mußte…

Die Hardware vom Surface wurde offensichtlich nach einer gefühlten Ewigkeit komplett abgeschaltet und als wir das Tablet wieder aktiviert haben, meldeten die RPMs nur noch IO Fehler. Die Root-Partition sprang wegen eines IO Fehler in den Read-Only-Modus und war auch nicht dazu zu bewegen, daß Read-Write wohl die bessere Wahl während eines Updates wäre. Meine Vermutung: Die Hardwareabschaltung hat den SD-Cardreader wohl überrumpelt und der hat den Schreibschutz von der SD-Karte fälschlich als aktiv gemeldet. Da eine Installation auf einem Read-Only Filesystem nicht funktionieren kann, stoppe DNF dann auch irgendwann… so 200 Fehlermeldungen später 🙁

Ich habe das System schon im Nirvana gesehen und beim nötigen Reboot die Augen zugekniffen 🙂 Es bootete doch tatsächlich noch, was bei Update 650 von 1563 nicht wirklich zu erwarten gewesen ist. Nach dem obligatorischen manuellen Filesystemcheck kam Gnome tatsächlich hoch. DNF ist schlau, aber nicht schlau genug. Natürlich war die RPM Datenbank defekt und mußte repariert werden. DNF aktualisierte dann im Rucksack die restlichen Pakete, als der Besitzer per Fahrrad gen Heimat fuhr. Natürlich hatten wir gelernt und den Akku aufgefüllt und die Energiesparoptionen so angepaßt, daß das hoffentlich nicht nochmal passiert.

Der ganze Update wäre in 5 Minuten durch gewesen, wenn Linux auf der SSD installiert gewesen wäre. Der Besitzer sollte dann Zuhause noch dnf reinstall „*“ ausführen, ob das geklappt hat, erfahren wir dann nächsten Mittwoch.

Sind USB-Stick und SD-Karten wirklich eine gute Idee für Linux?

Nach dieser Erfahrung muß ich sagen : Nein, sind sie nicht. Man kann sich nie sicher sein, ob die Hardware das Speichermedium nach einem Sleep/Hibernate wieder sauber anbietet und das „laufende“ System weiter funktioniert. Ein Strom-Aus für den USB-Port oder den SD-Kartenleser kann halt zu Fehlern führen wie man sieht. Im Gegensatz zum IDE/SATA Port des Mainboards sind USB und SD eben nur untergeordnete Peripherie-Geräte. Da wird von den Kernel- und Treiberentwicklern auch nicht soooooo viel Ambition reingeflossen sein, wie in die Hauptgerätetreiber SATA/IDE/SCSI. Wenn dann noch eine eher exotische Hardware wie ein Surface Pro angesprochen wird, kann es zu dem Fehler kommen.

Dazu kommt, daß die SD-Karte echt lahmarschig war. Für die 650 Updates vergingen locker 2 Stunden. Der USB Port wäre vermutlich schneller gewesen, weil der schafft auch 1 Gb/s aka 120 MB/s. Also, wenn Ihr das vorhaben solltet, und ich rate dringend ab, nehmt einen schnellen USB-3-Stick.

Zum Glück hängt der Besitzer nicht soooooo an Win10, nach einer kleinen Datensicherung und Umpartitionierung von Windows, werden wir wohl auch Linux noch auf die SSD quetschen können. Das wird an sich eine spannende Sache, weil… wie wird Win10 auf den Verlust einer geliebten Partition reagieren? Auch das erfahren wir nächste Woche 😉