Wie reagieren wir bei einem Security Incident?

Der Begriff „Incident Response“ sollte inzwischen den meisten web-affinen Menschen geläufig sein: Ein Incident ist schlicht ein Vorfall, ein Ereignis, nachfolgend ein Beispiel, und die Response ist die Antwort auf das Ereignis.

Heutzutage kommt der Begriff meist gekoppelt mit zwei weiteren Wörtern und wird so zur Abkürzung „DFIR“ – Digital Forensics and Incident Response. Bei der digitalen Forensik geht es, wie der Name schon sagt, um die Beweissicherung im Zusammenhang mit einem Sicherheitsvorfall.

Um den DF-Teil soll es nun weniger gehen, obwohl dieser beiläufig gestreift wird.

Was ist ein Sicherheitsvorfall?

Beim Managed Hosting kann dies zum Beispiel ein gehäuftes auftreten von fehlerhaften Loginversuchen an einem WordPress Login sein. Unsere WordPress-Installationen werden so konfiguriert, dass Sie uns so einen Vorfall per Email melden. Prinzipiell stehen öffentliche Webserver ohnehin im Dauerfeuer, irgendein Botnetz ist eigentlich das ganze Jahr über dabei, ssh oder Email Logins abzuklappern, um eine Schwachstelle zu finden. Nimmt die Last zu, erhalten wir eine Meldung, WordPress genauso wie Plesk dienen bei entsprechender Konfiguration also als Sensoren.

Da wir noch sehr klein sind, erfolgt die Reaktion darauf bisher manuell. Dazu wird auf dem betroffenen System ein spezielles, zusätzliches Logging aktiviert, ähnlich des Windows-Tools Sysmon, was fortan so ziemlich alles, was ein Angreifer machen könnte, aufzeichnet und an unser SIEM schickt. Haupsächlich werden nun also Dinge geloggt, die sonst nicht aufgezeichnet werden, zum Beispiel was ein Nutzer oder Root auf die Shell als Kommandos eingibt. Hierbei entstehen sehr große Datenmengen und auch die CPU des Servers wird einigermaßen belastet, deshalb, so wie aus Datenschutzgründen, nutzen wir solch ein Logging erst, wenn wir einen wirklichen Grund haben. Gleichzeitig erhöhen wir spezielle Maßnahmen auf dem betroffenen Server, zum Beispiel stellen wir die Web Application Firewall strenger ein, was im Alltagsbetrieb die Kunden sonst stören würde und die Ladezeiten der Webseiten verschlechtert. Ausserdem bewegen wir Backups der letzten 4 Wochen in einen Cold Storage.

Security Information and Event Management (SIEM)

In unserem SIEM sehen wir nun, was passiert und noch wichtiger, was passiert ist. Wer einmal versucht hat, einen laufenden Angriff manuell zu stoppen (ich habe das :D) wird sich fühlen, als wolle er einen Wasserrohrbruch mit Klebeband aufhalten. Das heißt, sind bisherige Sicherheitsmaßnahmen nicht ausreichend, um den Angriff zu stoppen, ist es wahrscheinlich nun zu spät hierfür – zum besseren Verständnis: wir können durchaus live eingreifen, können aber aufgrund der vielen Informationen und Möglichkeiten nie sicher sein, dass wir alle Lücken und / oder Persitence-Maßnahmen des Angreifers erfolgreich gepatcht haben. Aus diesem Grund sind Backups für sich gesehen kein ausreichendes Mittel, um Cybersecurity-Threats zu begegnen, denn in dem Backup sind definitiv noch die Lücken vorhanden, die ein Angreifer genutzt hat. Man muss davon ausgehen, dass ein Restore nach einem erfolgreichen Angriff ohne Analyse und Patching sofort wieder den erneuten, erfolgreichen Angriff zur Folge hat. Dies haben wir tatsächlich schon in realen Fällen erlebt. Um so wichtiger ist, dass der Angriff aufgezeichnet wird und später ausgewertet werden kann, hier beginnt unter anderem der Fachbereich der Threat Intelligence, dies kann man sowohl manuell (geringe Erfolgschancen), automatisiert / unter Zuhilfenahme von OSINT Quellen, Methoden und Tools (gute Erfolgschancen) als auch über KI (beste Erfolgschancen bei guter Datenbasis) machen, wie bei jedem Thema in der IT, findet genauso bei der Threat Intelligence eine kontinuierliche Weiterentwicklung statt.

Zum Test des Systems haben wir auf der Rootshell unsere Webseite abgerufen, der Event wurde erfolgreich geloggt.

Für uns persönlich ist das Logging ausserdem sehr wichtig, um auf dem aktuellsten Stand zu bleiben. Ein Server spricht nicht mit uns, eine kompromitierte Konsole sieht ganz genauso aus, wie eine nicht-kompromitierte. Das SIEM ist unser Fenster, unsere Live-Schaltung und MAZ in den laufenden Angriff. Gleichzeitig halten wir unsere Kunden über unseren Twitter-Kanal auf dem neuesten Stand und können dort sein, wo wir gebraucht werden, in der First Line of Defense und bei Bedarf für Kunden ansprechbar. Es ist gängig, dass die gründliche Auswertung der Logs erst später erfolgt. Der kontinuierliche Live-Export der Logs (wir machen das selbstverständlich mit TLS) ist obendrein deshalb sehr wichtig, weil ein System einen Impact bekommen könnte, ein Angreifer vielleicht Logs löscht, manipuliert oder das ganze System verschlüsselt oder zerstört – oder uns einfach aussperrt. Das heißt, jetzt oder nie, sonst kommt man unter Umständen nie wieder an die Logs.

Sollte der Angriff erfolglos bleiben, löschen wir danach schlicht die Aufzeichnungen, denn unser kleines System ist nicht auf die Verarbeitung von Milliarden von Datenbankeinträgen ausgelegt und würde nach ein paar Wochen den Dienst komplett einstellen. Möchte man den Dauerbetrieb, wie gesagt, wir wollen es aus Datenschutzgründen nicht und finden, wir haben eine gute Balance, wäre es ein Einzeiler-Cronjob, die Logs automatisch zu löschen, wenn sie z.B. älter als 2 Wochen sind. Sollte es tatsächlich einmal zu so etwas wie der Exfiltration von Kundendaten kommen (was bei uns bisher noch nie der Fall war) anonymisieren wir die Loggfiles entsprechend (die irrelevanten Teile) und speichern sie verschlüsselt ab, zum Beispiel für die mögliche, spätere Verwendung in der Forensik. Prinzipiell wird hierdurch die Beweiskette beeinträchtigt, wir geben in unserem Betrieb dem Datenschutz vorrang – das muss jedes Unternehmen für sich selbst entscheiden. Ohnehin sind Anzeigen von Angreifern aus dem EU-Ausland für uns bedeutungslos, und da wir eben Red-Teamer sind, wollen wir vor allem wissen, wie der Angriff erfolgreich umgesetzt werden konnte, damit wir die Lücke patchen können.

International ist das eine konservative Strategie (veraltet), für deutsche Mittelstands-Verhältnisse sind wir wahrscheinlich unter den Top 0.1%.

Wir glauben, damit tun wir wieder einmal deutlich mehr, als die meisten Konkurrenz-Anbieter. In Zukunft werden wir unsere SIEM-Lösung auch für kleinere Budgets externen Firmenkunden anbieten. Ausserdem hoffen wir, mit dem Titelbild zum Ausdruck bringen zu können, dass sich unsere datenschutzfreundliche Einstellung mit der Einführung moderner Sicherheitsbausteine nicht verändert hat. Zum aktuellen Zeitpunkt sind nur unsere Shared-Server und Server aus dem Paket „Segmentiert“ an unser System angebunden, wenn Sie dies für Ihr System möchten, jedoch nicht zu diesem Kreis gehören, fragen Sie gerne an, wir finden eine gute Lösung.

Update: Der Artikel wurde am gleichen Tag der Veröffentlichung nochmals um tiefergehende Informationen ergänzt.

Update 2: Und so sieht es dann in der Analyse aus (Bild unten)

Es macht gerade Spaß

und deshalb muss man ab hier fairerweise erwähnen, dass wir natürlich nicht bei jedem Sicherheitsvorfall unser SIEM auf- und umbauen. Es hat einfach gerade gepasst, deshalb haben wir die Gelegenheit genutzt. Zukünftig steht das ausgebaute System dann allen Server zur Verfügung.

Update 3: Im Laufe der Woche haben wir unser System ein gutes Stück ausgebaut, weitere Log-Quellen hinzugeschaltet (z.B. von unserem IDS, Snort und Netflow) und zum Spaß etwas Threat Intel und Threat Hunting betrieben. So langsam sind wir auch an die Grenzen von Rsyslog gekommen und haben deshalb nun einen TLS- und Auth-gesicherten Elastic-Endpunkt bereitgestellt, mit dem wir in Zukunft direkt Beats aus dem öffentlichen Netz, also von unseren Webservern und auf Wunsch auch anderen, firmeninternen Systemen anschließen können. Wir werden Preise hierfür noch bekannt geben. Wiederum an unserer derzeitigen Größe orientiert gehen wir nicht dem Umweg über Kafka oder Logstash für auth, apache, nginx und syslogs, da diese ja immernoch überschaubar in der Größe sind und es so deutlich weniger komplex ist. Die Architektur sieht nun wie folgt aus:

Der aufgebohrte HELK-Stack läuft nur on-demand, dafür mit viel Leistung auf einer unserer Workstations, der Logger läuft 24/7 und braucht fast keinen Strom. Die komplette Strecke ist wie schon gesagt transportverschlüsselt, auch intern haben wir schon lange die meisten Endpunkte mit eigenen Zertifikaten ausgestattet, so z.B. das Webinterface der Router, die Firewalls und das Kibana Frontend. Dazu betreiben ein eigenes DNS (mit Caching und DNSCrypt-Proxy) und ein Active Directory. Zu 100% Zero-Trust sind wir aber noch nicht, die Strecke vom Logger zum HELK, die ja ebenfalls nur on-demand läuft, ist noch unverschlüsselt.  Zwischengespeicherte Daten der Webserver auf dem Logger werden nach Hochfahren der Elastic-Stack VM nachgeschoben, es entsteht keine Lücke. Alle Produktiv-Systeme, auf denen auch die VMs laufen, sind vollverschlüsselt, die Daten also gut geschützt.

Unter der Annahme, wir wären kompromitiert worden, haben wir weitere Datenquellen hinzugefügt, sind zeitbasiert auf Suche gegangen, konnten aber die These nicht belegen – die These, dass wir nicht kompromitiert wurden, allerdings schon, es gab keinen einzigen erfolgreichen Login (ausser unserer eigenen), Snoopy hat kein einziges Kommando auf der Shell aufgezeichnet (ausser unserer eigenen, so wie viel weisses Rauschen von Plesk und dem System) und weder IDS noch Sysmon konnten nur Ansatzweise das kleinste Indiz für Malware, Code-Ausführung, Powershell-Code, persistente Verbindungen, neue Useraccounts, Dateien mit niedrigen Zugriffsraten oder Datenabfluss liefern. Nebenher habe ich mir APT1 als Lektüre zur Brust genommen. Spaß macht es natürlich trotzdem, ich freue mich um so mehr, bald neue Dashboards und eigene Regeln zu erstellen, um gerade die guten Auth-Logs von Snoopy besser darstellen zu können, ebenso möchte ich gerne geziehlt die F2B und ModSecurity Logs integrieren, da wir hier ähnlich eines IDS bereits gefilterte Daten mit einer hohen Inzidenz haben. Ob ich Bro / Zeek auf deutschen Webservern einsetzen kann oder will, muss ich mir noch überlegen, wie gesagt, das IDS ist hier in meinem eigenen Subnetz und betrifft potentiell nur mich selbst.

Nachfolgend eine kleine Auswahl an Screenshots aus unserer Analyse: Wir haben nur die Adressen behalten, die tatsächlich auch bei AbuseIP das gleiche Verhalten wie auf unseren Servern gezeigt haben und dazu nicht älter als 6 Wochen sind – und nicht, wie oft bei öffentlichen Datenbanken kritisiert, nur unscharfe Meldungen sind (z.B. Meldungen des Bing-Bots als Angriff). Wir haben dazu eine weitere These aufgestellt, die Loginversuche könnten von verweisten Systemen stammen, welche bei unserer IP-Adresse (unter dem Vorbesitzer) ein verbundenes System hatten – jedoch wurden z.B. verschiedene Nutzernamen durchprobiert, was dies widerlegt.

Weitere Daten haben wir aus unseren WordPress-„Sensoren“, die wir aber hier nicht zeigen, da sie ausser IP-Adressen und Häufigkeit nichts neues bieten, jedoch haben wir sie ebenfalls abgeglichen. Wir konnten in einigen AbuseIP-Meldungen sehen, dass andere kleine Web- und Emailhoster von diesen Adressen angegriffen werden. Die Angriffsmethoden sind vollautomatisiert, wobei wir in SSH-Nutzernamen und Emailadressen tatsächlich auch ein paar öffentliche Kundeninformation sehen können (z.B. Teile von Domainnamen), und auf relativ niedrigem Niveau. Zwischenzeitlich konnten wir Spitzen gegen 1:00 morgens & 6:00 morgens (GMT+1) feststellen, die aber mit Veröffentlichung dieses Artikels wieder abflauten. Die geographische Häufung sehen wir in Uptown New York und darüber, Paris und Peking. Die Häufing auf reine WordPress-Login Angriffe begrenzt sehen wir im osteuropäischen und nordasiatischem Raum. Eigene Kundenstandorte wurden entfernt. Unser derzeitiges Zwischenfazit ist, dass hier mit wenig Aufwand möglichst viel Infrastruktur übernommen werden will, als kleiner Hoster sind wir einen Zweig über den Endkunden. Auf Noise wird keine Rücksicht genommen, vermutlich sind wir der einzige, kleine deutsche Webhosting-Anbieter, der eine derartige Analyse überhaupt in Betracht zieht. Einen eindeutigen Akteur können wir derzeit noch nicht erkennen, aufgrund der Verteilung über verschiedenste Anbieter wäre unsere Vermutung, dass die Angreifer-IPs bereits übernommene und in ein Botnetz integrierte Systeme darstellen. Eine weitere These wäre, dass wir eine Mischung von verschiedenen Angreifern sehen, zum einen einfache „Spambots“, zum anderen eben gezieltere Angriffe auf WordPress und SSH. FTP ist bei unseren Servern übrigens aus diesen Gründen seit über 5 Jahren abgeschaltet.

 

In den folgenden Tagen werde ich noch ein paar weitere Screenshots hinzufügen.


Auf der Jagd mit Netflow-Daten – ich hab mich selbst gefunden. Spoiler: Ich war’s nicht. 😀 – immerhin stimmt AbuseDB mit mir überein, unten rechts eine Reverse-DNS Anfrage, dies geht natürlich auch über die Bash mit dig.

So manch Skuriles…

…aber es war nur ein Private-DNS Anbieter (.53 ist mein interner DNS-Server)


Eine frühe Geolokation, bei SSH und SMTP blieb dies auch später größtenteils unverändert.

Update 4: Nur ein kurzes Update, neue Bilder folgen. Wir haben gestern die Plattform erneut etwas umgebaut und Logstash auf dem Intermediate Logger dazwischengeschaltet, damit wir dort unsere eigenen Filter einbauen können. Jetzt sind wir endlich an dem Punkt, an den wir eigentlich wollten, wir können die Logs, z.B. von Snoopy, selbst parsen und bestimmen, wie sie aufbereitet werden, dazu unsere eigenen Dashboards entwickeln usw. Das hat leider auch den Nachteil, dass wir das nun für alle anderen Logtypen ebenfalls machen müssen, welche vorher von Elasticsearch auf der direkten Verbindung Filebeat -> Elastic automatisch verarbeitet wurden, respektive über die Module, die Filebeat bereitstellt. Dass das jetzt nicht mehr automatisch passiert liegt daran, dass die Logs nun in einem gemeinsamen Index ankommen und die vorgefertigten Dashboards, welche von den Filebeat-Modulen installiert wurden, diesen Input nicht verstehen. Vielleicht kann man das noch besser lösen, denn mit den anderen Dashboards waren wir durchaus zufrieden und für die Threatsuche ist das meiste davon eher von untergeordneter Bedeutung. So lange wir Rsyslog im Stack behalten, sind wir an der Stelle tatsächlich fertig, denn Rsyslog macht bei den Auth-Logs einen guten Job, wir könnten nun einfach parallel einen Filebeat auf dem betroffenen System installieren und die anderen Logs an den Elastic-Endpunkt schicken. Wir möchten aber gerne zukünftig Rsyslog aus dem Stack entfernen, es hat seine Vorteile darin, schlank und unsichtbar zu sein, aber das Setup ist aufwendiger, man muss auf beiden Seiten RSA-Keys (Public/Private-Keypaare mit CA) bereitsstellen. Spielt Zeit / Geld keine so große Rolle, wäre die Lösung so aber tatsächlich noch besser, denn Angreifer müssten zwei verschiedene Mechanismen aushebeln, um das Logging vollständig abzustellen, und nicht nur den Beats-Prozess abschießen.

Wie vermutet, sind vorher schon andere über das erwähnte Henne-Ei-Problem mit Filebeat <=> Logstash gestolpert, Elastic bietet zwei Lösungswege an, einmal die Nutzung von Ingest-Pipelines für Filebeat-Module, so wie eben schon gesagt die Bereitstellung von eigenen Filtern. Wir wollen nun erst einmal den zweiten probieren. Schön, dass gleich fertige Filter genau dafür zur Verfügung gestellt werden:
https://www.elastic.co/guide/en/logstash/7.10/logstash-config-for-filebeat-modules.html

Die ersten Custom-Dashboards nehmen Gestalt an, hier sehen wir die seltensten Kommandos im System – auch wenn es anders aussieht, alles was hier zu sehen ist, wurde nicht von einer Person eingetippt, sondern stammt aus Skripten und Programmen, wie z.B. Plesk. Nun kann man weiter nach unten filtern, um potentiell bößartige Eingaben zu finden. Ziel der Übung ist es ein Dashboard zu kreieren, dass uns auch bei einem kurzen Blick schnell und direkt das liefert. Als nächstes werden wir z.B. Apache- oder Nginx Visualisierungen hinzufügen, um so Verbindungen aufzeigen zu können, so etwas wie Code Execution über eine POST-Anfrage an eine WordPress-Plugin Sicherheitslücke, die auf dem System ein Kommando ausführt. Die „Tortenvisualisierung“ zeigt uns übrigens die seltensten Kommandos pro User-ID.

Whoami – wie bitte?


Hat sich also doch bereits ein Hacker durch unsere Webseite eingehackt? Durch die Visualisierung war schnell ersichtlich, wer das whoami-Kommando ausgeführt hat: der Nutzer mit der UID 10000 – der Plesk-Benutzer ARTunchained.


Wir gehen auf die Suche, da wir die UID wissen, wissen wir auch, in welchem Ordner (Plesk Standard) wir nach potentieller Code-Ausführung suchen müssen. Und tatsächlich, ein exec-Befehl in dem Plugin WebP-Express.


Aber scheinbar gehört das whoami irgendwie zu der Funktion des Plugins, im Screenshot der Quellcode. Etwas merkwürdig ist das jetzt schon.

Ich bin aber ehrlich gesagt nach ein paar langen Nächten froh, dass es heute mal so flüssig voranging, und lasse mir selbst die Antwort auf die Frage, ob ich gehackt wurde, offen. Morgen lade ich mir das Plugin aus einer neutralen Quelle herunter und vergleiche den Code. Und auch wenn es mir jetzt keiner glauben wird: Das ist wirklich heute abend passiert, es war nicht geplant, nicht vorbereitet, nicht geskriptet, wie man beim Film sagt. 😀

Update 5: Wie schon erwartet, das „whoami“ war kein Hack, sondern tatsächlich Bestandteil des Plugins. Da wir die Wochenenden immer selbst dem red teaming widmen (heute war zum ersten mal mein 11-jähriger mit an Bord und hat sich seine allererste Userflag bei HTB gesichert!), gab es bisher noch keine neue Entwicklung unserer Plattform oder des aktuellen Szenarios.

Update 6: Nur ganz kurz, damit man nicht denkt, das Projekt wäre eingeschlafen – wir haben nach ein paar weiteren Versuchen uns nun entschieden, Rsyslog wirklich nur auf die Auth-Logs (Snoopy via ld-preload, also Bash- und Systemkommandos) zu beschränken, weil der Overhead der Konfiguration bei einem derartigen Plesk-Server mit vielen Accounts und Domains einfach nicht mehr zu rechtfertigen ist. Rsyslog ist abseits der Standardkonfiguration sehr zickig, jede Änderung braucht einen „warm-up“, bis man überhaupt sieht, ob es funktioniert und das meiste ist schlecht bis garnicht dokumentiert, weil es vor einer Weile ein größeres Update gegeben hat, viele ältere Optionen nun deprecated sind, uvm. Natürlich kann man es als Premium-Option oder einfachere Server (z.B. Docker oder LAMP) weiter in Betracht ziehen und ich werde dem Konkurrenz-Werkzeug Syslog-ng auch noch eine Chance geben. Die Anbindung für die Apache, Nginx und weitere Logs wurde nun über einen Filebeat realisiert, mit TLS und Authentifizierung. Man sollte keinesfalls Logs ohne Verschlüsselung durch den Äther funken, die Menge an Infos und Metadaten ist dann doch einigermaßen brisant.

Man sieht die zeitliche Lücke, in der die Apache-Logs gefehlt haben. Das Mapping sieht aber vom Start weg super aus, auch ohne Logstash in der Mitte, leider funktionieren bisher die alten Dashboards immernoch nicht, aber wir wollten ohnehin vor allem ein paar Custom-Views in unser Hunting-Dashboard einbauen, damit wir Systembefehle neben GET- und POST-Requests sehen können, also kein Drama.

Und die erste Apache access.log Tabelle ist da, lustig, welche Menge an Bytes gerade übertragen wird. Der Angriff hat übrigens noch nicht aufgehört, der / die Angreifer scheinen zwischendurch die Mittel minimal zu ändern, aber es ist bisher immernoch sehr low-tech. Fraglich, ob ein APT für einen kleinen Player wie uns überhaupt einen Zero-Day aus der Mottenkiste holt – von APT1 weiss ich inzwischen, dass die Zielauswahl auch stark an der jeweiligen Sprache orientiert ist, da man nur begrenzt Kapazität für Fremdsprachen hat.

Manuel Geissinger, zertifizierter IT-Sicherheitsexperte, Webedesigner aus Freiburg, Webentwickler, Administrator und Digitalkünstler.
Ihr freiburger Webentwickler Nr. 1 auf LinkedIn Zertifizierter IT Sicherheits-Experte & Webdesigner auf Xing