Eine dunkle Holztür mit einem eisernen Riegel und einem verrosteten Vorhängeschloss.

Wie Hacker*innen über Websites dein Unternehmen kapern

Websites und Webanwendungen wie WordPress und Typo3 sind ständig Angriffen ausgesetzt. Dabei versuchen Angreifer zunächst das System von außen zu erforschen und mit Hilfe von Sicherheitslücken Schritt für Schritt ihre Privilegien auf einer Website oder einem Server auszubauen.

Das folgende Szenario beschreibt den Angriff auf eine WordPress-Website, der so tatsächlich bei einem neuen Kunden von mir stattgefunden hat. Der betroffene Website-Betreiber kontaktiere mich kurz nachdem seine Website von Google gesperrt worden war und er so den Hack bemerkte. Schnell stellte sich heraus, dass bei der Einrichtung der Website und der WordPress-Installation gleich mehrere fatale Fehler in Bezug auf Sicherheit gemacht wurden. Der Hack war mehr als ein ganzes Jahr völlig unbemerkt geblieben.

Ich werde im Folgenden darauf verzichten auf die Konsequenzen und die eingeleiteten Massnahmen einzugehen. Das werde ich eventuell in einem weiteren Artikel beschreiben. Dieser Artikel soll lediglich zeigen, wie der Hack verlaufen ist.

1. Scannen von Dateien und Verzeichnissen

Nach einer Analyse der Logfiles wurde schnell klar, dass ein Angreifer zunächst versuchte sensible Daten über Fuzzing zu bekommen. Dabei wird eine Software eingesetzt, welche die Website nach interessanten Verzeichnissen durchsucht, die aber nicht offensichtlich auf der eigentlichen Website verlinkt sind. Das Programm fragt dabei den Webserver ob bestimmte Dateien oder Verzeichnisse existieren. Dieses Verfahren ist also ähnliche wie ein Brute-Force Angriff auf Logins. Dabei kann die eingesetzte Software entweder nach bekannten Begriffen mit Hilfe von Wortlisten suchen oder einfach Zeichenkombinationen an den Server senden.

So könnten URLs aussehen, die mit Hilfe von Wortlisten getestet werden:

/index.php.old
/config.php.old
/config.php_old
/_config.php.backup
/backups
/backup
/dump.sql
...

Alternativ kann der Angreifer einfach Zeichenketten in alphabetischer Reihenfolge testen:

/a
/aa
/aaa
/b
/ab
/aab
...

2. Ausspähen sensibler Daten

Im Fall meines neuen Kunden stellte sich heraus, dass die gesamte WordPress-Installation mit alten ungenutzten Files durchsetzt war. Am kritischsten war jedoch ein Verzeichnis mit dem Namen /rd. In diesem befand sich eine Kopie den Tools Database Search and Replace. Dieses Tool wird oft genutzt um Ersetzungen in WordPress-Datenbanken durchzuführen. In dem Tool wird ausdrücklich darauf hingewiesen, es nach der Verwendung umgehend wieder zu löschen. Das ist jedoch nicht passiert. Zudem war es in einem leicht zu erratenden Verzeichnis untergebracht. Das wirklich fatale an dem Tool ist jedoch, dass es automatisch die WordPress-Konfiguration liest und für den Nutzer die Datenbankzugangsdaten im Klartext lesbar vorausfüllt. Aus den Logs war ersichtlich, dass es nach dem Scannen der Website mehrere Zugriffe auf dieses Tool gegeben hatte. Somit hatte der Angreifer nun die Zugangsdaten für die WordPress-Datenbank.

3. Remotezugriff auf die Datenbank

Die nächste sehr fatale Sicherheitslücke bestand darin, dass es möglich war, per Remote eine Verbindung mit der Datenbank herzustellen. Das bedeutet, dass nicht nur WordPress sich mit der Datenbank verbinden kann, sondern auch jede andere Maschine von überall auf der Welt, sofern man die Zugangsdaten hat. Bei den meisten Hostern laufen Datenbank und Webserver auf derselben Maschine. Daher kann man den Zugriff auf die Datenbank von außen bedenkenlos abschalten. Bei einigen Hostern ist ein Zugriff von außen auch generell nicht möglich. Datenbanken sollten immer nur dem Server zugänglich sein, der auch darauf Zugriff haben muss. Im Backend des Hosters konnte ich das abschalten. Warum der Remotezugriff aktiviert war konnte mir auch der Kunde nicht sagen.

4. Anlegen eines neuen Admin-Accounts

Über die Datenbank konnte dann einfach ein neuer Admin-Benutzer für WordPress angelegt werden. Fatalerweise waren in dem WordPress über 1000 Logins für verschiedenste Kunden hinterlegt, sodass das nicht aufgefallen ist. So könnten die MySQL-Befehle aussehen:

INSERT INTO `wp_users` (`user_login`, `user_pass`, `user_nicename`, `user_email`, `user_status`)
VALUES ('newadmin', MD5('pass123'), 'firstname lastname', 'email@example.com', '0');

INSERT INTO `wp_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) 
VALUES (NULL, (Select max(id) FROM wp_users), 'wp_capabilities', 'a:1:{s:13:"administrator";s:1:"1";}');

INSERT INTO `wp_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) 
VALUES (NULL, (Select max(id) FROM wp_users), 'wp_user_level', '10');

5. Einloggen als Admin

Der Angreifer braucht nun nur noch auf http://yourdomain.com/wp-login.php zu gehen und sich mit newadmin und pass123 einzuloggen. Auch hier hätte man entgegenwirken können, indem man den Login entweder mit einem Plugin versteckt oder zusätzlich mit einer Basic-Authentifizierung schützt.

6. Installieren eines Backdoors

Nachdem der Angreifer als Admin im WordPress ist wird er versuchen eigenen PHP-Code auszuführen. Leider ist das oft ohne großen Aufwand möglich. Dazu gibt es nämlich verschiedenste Wege. Man kann zum Beispiel über den integrierten Theme-Editor das Theme anpassen und dort eigenen PHP-Code einschleusen. Das lässt sich jedoch relativ einfach mit Hilfe der Zeile define( 'DISALLOW_FILE_EDIT', true ); in der wp-config.php abschalten. Alternativ kann ein Angreifer jedoch auch versuchen ein Plugin zu installieren, welches die Ausführung von PHP-Code in Posts und Pages erlaubt. Hier könnte man zum Beispiel dem Webserver verbieten innerhalb des wp-content Verzeichnis zu schreiben. Das würde bedeutet, dass WordPress-Plugins nur noch via FTP installiert / aktualisiert werden können.

7. Eskalieren der Privilegien

Der Angreifer hat es auf jeden Fall geschafft so oder so ähnlich PHP-Code auszuführen. Oft wird einfach ein simples Upload-Formular für Files integriert, welches dann wiederum ein erweitertes PHP-Backdoor auf den Server lädt. Dieses wurde im Fall meines Kunden auf http://yourdaomain.com/wp-content/uploads/backup.php platziert. Aus den Logs ist ersichtlich, dass dann nur noch dieses Tool direkt genutzt wurde. Über dieses Tool konnte der Angreifer dann wirklich alles machen. Es enthielt einen kompletten Datei-Explorer, man konnte Dateien hoch und runter laden, SQL-Kommandos ausführen, Keylogger platzieren und Systemkommandos ausführen.

8. Erforschen des gesamten Servers

Wenigstens war in der php.ini die open-basedir Anweisung gesetzt, sodass der Angreifer mit seinem File-Explorer nicht das Installationsverzeichnis von WordPress verlassen konnte. Dennoch gab es eine andere Möglichkeit alle Dateien und Verzeichnisse des Servers auszuspähen. Über die exec-Funktion konnte der Angreifer Systemkommandos ausführen und sich so an dem open-basedir vorbeimogeln. Folgendes hätte in der PHP.ini gesetzt sein müssen um auch das zu verhindern:

disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

So konnte man einfach mit Befehlen wie ls -la /etc/apache2 oder ls -la /var/www oder cat /etc/passwd den ganzen Server ausspähen.

9. Überspringen auf andere Installationen

Auf dem Server gab es noch mehr Websites, die alle mit dem Unternehmen des Kunden zu tun hatten. Darunter befanden sich eine Typo3-Installation, diverse Testseiten und auch eine Intranet-Website für das Unternehmen. Es war für den Angreifer in den meisten Fällen jedoch nicht möglich dort hinein zu gelangen, da jede Website einem anderen Systembenutzer zugeordnet war. Nur in den genannten Fällen waren innerhalb der anderen Websites Ordner mit falschen Zugriffsrechten versehen, sodass darin geschrieben werden konnte. So gab es in einer Website beispielsweise ein Cache-Verzeichnis mit den Berechtigungen 0777. Dadurch konnten auch dort Backoors platziert werden. Durch den Aufruf der Backdoors über die Domains der anderen Websites konnte der Angreifer nun mit verschiedenen Systembenutzern arbeiten und auch diese Websites vollständig kontrollieren.

10. Ausspähen von Nutzerdaten

Angreifer versuchen immer lange Zeit unbemerkt zu bleiben und in dieser Zeit ihre Privilegien auszubauen. Es wurden an den Logins der übernommen Websites und auch an dem PHP-basierten Intranet-Dienst Keylogger installiert. Diese zeichneten einfach alle Loginversuche auf und speicherten diese in einem CSV-File. Der Angreifer musste sich also keine Mühe geben die Passwörter irgendwie aufwändig zu entschlüsseln oder sie zu erraten. Da viele User immer noch für verschiedene Services die gleichen Passwörter nutzen, kann ein Angreifer von dort aus natürlich auch auf Mailaccounts, Facebook, Google oder ähnliches überspringen.

Das spannende an dem Keylogger war jedoch, dass er einfach alles aufzeichnete. Auch fehlgeschlagene Logins wurden abgespeichert. Ich will mir gar nicht ausmalen wie oft ich schon gedankenverloren irgendwo ein Passwort eingegeben habe, dass eigentlich zu einem anderen Service gehört.

Jedenfalls stand in dem Logfile wirklich alles. Darin waren Zugangsdaten für Mailaccounts, Windows-Anmeldedaten, persönliche Passworte anderer Dienste und sogar ein altes SSH Passwort. Wenn ein Keylogger lange genug läuft, und sich genug Mitarbeiter vertippen, steht da irgendwann wirklich alles drin.

Fazit

Der Schaden für das Unternehmen war hier natürlich erheblich. Dieses Szenario zeigt jedoch keinesfalls einen Einzelfall. Ich würde es mir daher nur wünschen, wenn Unternehmen selbst in Pentests investieren und die Verantwortlichen die Sicherheit mehr in den Fokus rücken würden.

Titelbild: https://unsplash.com/de/fotos/braunes-vorhangeschloss-maaWpQVgi00