Kompromittierung von vela.uberspace.de

Posted by jonas on Tuesday, January 29, 2019

Am gestrigen 28.01.2019 gegen ca. 16:00 Uhr haben wir festgestellt, dass die Berechtigungen von /usr/bin/python auf dem Host vela.uberspace.de mit einem Setuid-Bit versehen waren. Das bedeutet, dass jeder User mittels dieses Python-Interpreters Code als root-User mit vollem Zugriff auf das gesamte System ausführen könnte. Wir haben insofern nach erster kurzer Analyse den Host um 17:33 Uhr aus Sicherheitsgründen komplett gestoppt. Eine umgehende Betrachtung aller anderen Hosts hat nichts Vergleichbares ergeben. Wir haben offline eine umfangreiche Bereinigung des Hosts vorgenommen und ihn am heutigen 29.01.2019 um 13:46 Uhr wieder hochgefahren. Wir haben allerdings den Start von User-Applikationen (dynamische Websites, eigene Services, Cronjobs, …) soweit möglich angehalten.

Was funktioniert im Moment?

Die von uns bereitgestellten Dienste (SSH, Mailempfang und -versand, MySQL, Webserver) funktionieren grundsätzlich.

Was funktioniert im Moment nicht?

  • Wir haben allen CGI- und FastCGI-Scripts von Uberspaces die Ausführungsrechte genommen. Das betrifft auch den php-fcgi-starter; es werden somit ohne weiteren Usereingriff keine PHP-Seiten ausgeführt. Du kannst sie mittels chmod +x <dateiname> wieder ausführbar machen, wenn du davon überzeugt bist, dass der von dir hochgeladene Code nicht kompromittiert ist. Im Fall von PHP meint das nicht die PHP-Dateien, sondern den Starter: chmod +x ~/fcgi-bin/php-fcgi-starter.
  • Wir haben alle Cronjobs deaktiviert, in dem wir sie mittels der Zeichenkette #vela-compromised# am Zeilenanfang auskommentiert haben. Du kannst sie wieder aktivieren, in dem du die Zeichenkette entfernst, wenn du davon überzeugt bist, dass die betreffenden Cronjobs nicht kompromittiert wurden.
  • Wir haben alle daemontools-Services deaktiviert, in dem wir sie mittels einer down-Datei (~/service/<dienstname>/down) vom automatischen Start beim Booten abgehalten haben. In der down-Datei haben wir die Zeichenkette vela-compromised hinterlegt; so kannst du unterscheiden, ob ein Service möglicherweise schon von dir selbst abgeschaltet worden ist oder ob dies von uns erledigt worden ist. Du kannst die Services wieder aktivieren, in dem du svc -u ~/service/<dienstname> ausführst, wenn du davon überzeugt bist, dass der betreffende Service nicht kompromittiert wurde. Die Datei ~/service/<dienstname>/down solltest du löschen, damit der Service nach einem Reboot ebenfalls automatisch startet.
  • Wir haben alle .qmail-Dateien deaktiviert, die ausführbare Programme enthalten, mit Ausnahme von /usr/bin/vdeliver und /usr/local/bin/ezmlm-*. Wir haben jene dazu umbenannt und ihnen die Endung .vela-compromised vergeben. Die Originaldatei haben wir durch eine Datei mit dem Inhalt |exit 111 ersetzt. Dieser Exitcode sorgt dafür, dass Mails an jene .qmail-Datei temporär in der Mailqueue verbleiben. Du kannst eine .qmail-Datei wieder aktivieren, wenn du davon überzeugt bist, dass das darin aufgerufene Programm nicht kompromittiert wurde, in dem du die verschobene .qmail-Datei zurück-umbenennst, also z.B. mv ~/.qmail-xyz.vela-compromised ~/.qmail-xyz.
  • Wir haben in allen .htaccess-Dateien, die Options ExecCGI gesetzt haben, jene durch Options -ExecCGI ersetzt, um die Ausführung dynamischer Inhalte zu verhindern. Wenn du davon überzeugt bist, dass die auszuführenden Programme nicht kompromittiert worden sind, kannst du das - vor dem ExecCGI wieder entfernen.
  • Wir haben Zeilen mit command="..."-Anweisungen in ~/.ssh/authorized_keys-Dateien auskommentiert, sofern hier Programme aufgerufen wurden, die nicht von uns selbst bereitgestellt werden. Wenn du davon überzeugt bist, dass jene nicht kompromittiert worden sind, kannst du die Zeilen durch Entfernen von #vela-compromised# in der ~/.ssh/authorized_keys wieder aktivieren.
  • Wir haben .bashrc, .bash_profile und .zshrc, wenn sie vom bereitgestellten Default abgewichen sind, umbenannt, in denen wir ihnen die Endung .vela-compromised verpasst haben, und haben sie durch die generischen Varianten aus /etc/skel ersetzt. Wenn du überzeugt bist, dass die umbenannten Dateien nur nicht kompromittierte Software aufrufen, kannst du sie durch zurück-umbenennen wieder aktivieren, also z.B. mit mv ~/.bashrc.vela-compromised ~/.bashrc.

Seit wann bestand die Kompromittierung?

Leider ist das bislang für uns nicht abschließend feststellbar. Ein Abgleich mit unseren Backups ist aufgrund einer strukturellen Schwäche in unserem Setup nicht aussagekräftig.

Diese Schwäche ist auf das Problem zurück zu führen, dass bestimmte Parameter, wie das Setuid-Bit nicht sauber gesichert wurden. Die Langfassung ist, das wir in unserer Backup-Strategie auf ein inkrementelles Backup setzen, um den benötigten Speicherplatz zu minimieren. Inkrementell bedeutet, dass nur veränderte Dateien erneut vollständig gespeichert werden. Unveränderte Dateien werden mit einem Hardlink auf die ursprüngliche Datei im Dateisystem hinterlegt. Hardlink bedeutet, dass mehrere Einträge bzw.Verweise im Dateisystem auf die gleichen Daten zeigen. Normalerweise wird dieser Hardlink in dem Moment aufgelöst, in dem eine Veränderung der Datei stattgefunden hat, sodass eine neue Datei mit dem neuen Stand angelegt wird. Dies ist bei der Änderung an den Rechten der Datei leider nicht passiert, da rsync für diesen Sonderfall keine Option bietet dieses Verhalten zu unterbinden. Hier wurden von unserem auf rsync basierenden Backup nur die Rechte übertragen und, da es keine Änderung gab, nur diese angewendet ohne dass der Hardlink aufgelöst wurde. Da sich alle Hardlinks diese Rechte teilen, wurden diese auch auf alle vergangenen Versionen übertragen. Dadurch ist für uns aus dem Backup nicht zu erschließen, wann die Rechte der Datei geändert wurden. Eine genaue Festlegung auf den Zeitraum in dem die Kompromittierung bestand ist daher nicht möglich.

Wurde die Kompromittierung ausgenutzt?

Auch dies ist leider nicht feststellbar. Wir haben bei einem intensiven Abgleich von Binaries, möglicherweise hinzugefügten setuid-Binaries, Cronjobs, zusätzlich hinterlegten SSH-Keys beim root-User, zusätzlichen Systemusern mit administrativen Rechten, sudo-Konfiguration etc. keinerlei zusätzlichen Veränderungen vorgefunden. Es wird nicht protokolliert, welche User /usr/bin/python ausgeführt haben, und selbst wenn, so würde das keinen Hinweis darauf geben, ob es sich um eine böswillige Ausführung gehandelt hat oder aber um eine schlichte Benutzung von Python als bereitgestellter Programmiersprache. Es gibt keine Protokolle darüber, welcher Code mittels des Interpreters ausgeführt wurde. Ein Angreifer, der das setuid-Python-Binary absichtlich benutzt hat, konnte prinzipiell sämtliche Dateien des Systems lesen, löschen und ändern. Ob dies auch tatsächlich geschehen ist, ist nicht ersichtlich. Angesichts dessen, dass wir bei der Kontrolle von Dateien, die für unsere administrativen Zugänge wichtig sind, keine Hintertüren vorgefunden haben, halten wir es für nicht allzu wahrscheinlich, dass Hintertüren in User-Accounts hinterlegt worden sind. Technisch ausschließen lässt sich dies allerdings nicht.

Muss ich gemäß DSGVO etwas tun?

Wir haben gemäß Art. 33 DSGVO eine Meldung von dem Vorfall an den für uns zuständigen Landesdatenschutzbeauftragen Rheinland-Pfalz gemacht. Das Aktenzeichen liegt uns noch nicht vor, wir reichen es baldmöglichst nach. Dieses Aktenzeichen solltet ihr dann auch immer verwenden, falls ihr in dieser Sache Kontakt mit den Behörden habt.

Im Übrigen möchten wir alle Nutzer, die selbst als Verantwortliche personenbezogene Daten verarbeiten (also alle, die mit uns einen Auftragsverarbeitungsvertrag geschlossen haben), auf ihre eigenen Meldepflichten gemäß Art. 33, 34 DSGVO hinweisen. Wir hatten bereits Kontakt mit der Aufsichtsbehörde und haben uns persönlich bestätigen lassen, dass ihr als betroffene Nutzer nicht auch noch zusätzlich eine Meldung an die Behörde machen müsst. Eine Mitteilung von euch an eure Kunden/User/Besucher von dem Vorfall ist gemäß Art. 34 DSGVO nur eine gesetzliche Pflicht, wenn durch die Kompromittierung des Servers „voraussichtlich ein hohes Risiko für die persönlichen Rechte und Freiheiten natürlicher Personen“ entsteht. Unabhängig davon solltet ihr euch aber immer fragen: „Wäre ich als Nutzer gerne über einen solchen Vorfall informiert worden?“ Gerne könnt ihr bei einer solchen Mitteilung auf unseren Blogpost verlinken. Die Frist für eine solche Meldung beträgt 72 Stunden, nachdem ihr von dem Vorfall Kenntnis erlangt habt.

Stay tuned

Wir werden diesen Blogpost mit weiteren Informationen zum Hergang, zu unserer Analyse und weiteren aufkommenden Fragen ergänzen. Bitte wende dich an hallo@uberspace.de oder unseren Twitter-Account @hallouberspace, wenn du Fragen hast. Unser Support-Team ist darauf vorbereitet, betroffenen vela-Benutzern mit Priorität zu helfen.