Eine gehackte WordPress-Seite: ein veraltetes Plugin und eine Web-Shell

Ein veraltetes Plugin erlaubte eine Web-Shell, die Seite leitete Besucher um, Google markierte sie. Neuaufbau, Updates, Geheimniswechsel, Härtung.

Firma
Eine kleine Firma mit Präsentationswebsite, 10 Personen
Website
WordPress mit mehreren Plugins und einem Kontaktformular
Betreuung
Ein Externer betreut sie gelegentlich, Updates verfolgt niemand
Hosting
Ein VPS, Nginx und PHP-FPM, MySQL

01Ausgangslage

Die Website läuft auf WordPress mit mehreren Plugins. Eines davon, wp-file-manager, ist auf einer Version von vor der Korrektur. Die Anmeldung zur Verwaltung ist öffentlich erreichbar, das Bearbeiten von Dateien in der Verwaltung ist aktiv, und das Datenbankkonto von WordPress hat volle Rechte.

Backups gibt es, aber niemand hat je eine Wiederherstellung versucht, und die Integrität der Dateien wird nicht überwacht.

  1. Internet
  2. Nginx / PHP-FPM
  3. WordPress (veraltetes Plugin)
  4. MySQL

02Das Problem

Kunden meldeten, dass die Seite auf dem Handy auf eine zweifelhafte Seite umleitet. Die Google Search Console markierte die Seite als schädlich, und der organische Verkehr sank.

Ursache war CVE-2020-25213 im Plugin wp-file-manager vor Version 6.9. Das Plugin gab eine Datei frei, über die sich ohne Anmeldung PHP-Code hochladen und ausführen ließ, also Remote Code Execution. Der Angreifer lud eine Web-Shell hoch, eine kleine PHP-Datei zur Steuerung des Servers, und schleuste in die Seite eine bedingte Umleitung ein (auf Handys und aus Suchergebnissen) samt Spam-Inhalt für Suchmaschinen.

Voraussetzung: Es genügt, dass das verwundbare Plugin aus dem Internet erreichbar ist. Es ist eine öffentlich bekannte, massenhaft ausgenutzte Schwachstelle aus 2020, nichts, was wir hier offenlegen.

Eine gehackte Seite bedeutet, dass der Server unter Kontrolle des Angreifers stand. Deshalb wurde davon ausgegangen, dass nichts darauf mehr vertrauenswürdig ist.

03Technische Ursache

Die Hauptursache ist ein veraltetes Plugin mit bekannter Schwachstelle. Ohne Verfolgung der Updates blieb sie Monate nach der Korrektur offen.

Die Auswirkung vergrößerten die Einstellungen: das aktive Bearbeiten von Dateien in der Verwaltung und ein Datenbankkonto mit vollen Rechten erweiterten, was sich nach dem ersten Fuß in der Tür tun ließ. PHP ließ sich zudem aus dem Upload-Verzeichnis ausführen, wo die Shell landete.

Dass niemand eine Wiederherstellung versucht und die Integrität nicht überwacht hatte, führte dazu, dass sich der Vorfall erst über Kundenbeschwerden zeigte, nicht früher.

04Untersuchung

Die Änderungszeiten der Dateien zeigten unbekannte PHP-Dateien im Upload-Verzeichnis und bearbeitete Theme-Dateien. In der Datenbank saß eingeschleuster Code in den Einstellungen und im Seiteninhalt.

Die Nginx-Zugriffslogs zeigten Anfragen an die Datei des Plugins von ausländischen Adressen zu der Zeit, als die unbekannten Dateien auftauchten.

Die Search Console zeigte, welche URLs Google markiert hatte und was es den Besuchern zeigte.

Der Umfang wurde durch einen Vergleich mit einer sauberen Installation von WordPress und den Plugins aus offiziellen Quellen bestätigt, um klarzumachen, was auf dem Server nichts zu suchen hat.

05Behebung

Die Seite wurde in den Wartungsmodus genommen. Die Shell wurde nicht einfach gelöscht: Nach einer Kompromittierung lässt sich nicht verlässlich belegen, dass der Angreifer keine weitere Hintertür hinterließ, deshalb wurde die Seite neu aufgebaut.

Der WordPress-Kern, die Plugins und das Theme wurden aus offiziellen Quellen ersetzt. Der Inhalt wurde aus einem verifiziert sauberen Backup wiederhergestellt, oder die Datenbank wurde vom eingeschleusten Code gesäubert. Das Plugin wp-file-manager wurde entfernt, da die Seite es nicht brauchte.

Alle Geheimnisse wurden gewechselt: die Passwörter der Administratoren, das Datenbankpasswort, die Sicherheitsschlüssel in wp-config.php (was jede Anmeldung ungültig macht) und die Hosting-Zugänge.

wp-config.php
// turn off the built-in file editor in wp-admin: no code changes from the browser
define('DISALLOW_FILE_EDIT', true);

// rotate ALL of these after a compromise, with fresh values from the
// WordPress secret-key API; it invalidates every existing login cookie
define('AUTH_KEY',         '...'); // also SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY
define('AUTH_SALT',        '...'); // also SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT

Das Ausführen von PHP aus dem Upload-Verzeichnis wurde verboten, sodass eine weitere dort abgelegte Shell wirkungslos bleibt.

nginx: server block
# never run PHP from the uploads directory: a web shell dropped there stays inert
location ~* /wp-content/uploads/.*\.php$ {
    deny all;
}

Die Seite wurde gehärtet: das Bearbeiten von Dateien in der Verwaltung abgeschaltet, das Datenbankkonto auf die nötigen Rechte beschränkt, automatische Plugin-Updates, ein zweiter Faktor und eine Begrenzung der Anmeldeversuche für die Verwaltung sowie eine Überwachung der Dateiintegrität.

In der Search Console beantragte die Firma eine erneute Prüfung, damit Google die Markierung entfernt.

06Warum die Lösung wirkt

Das Entfernen des Plugins schließt den Weg, über den die Shell hochgeladen wurde. Ein Update würde ihn auch schließen, doch das Plugin wurde nicht gebraucht.

Der Neuaufbau aus offiziellen Quellen entfernt auch eine Hintertür, die eine Reinigung von Hand übersehen könnte.

Der Wechsel der Sicherheitsschlüssel in wp-config.php macht jedes Anmelde-Cookie ungültig, der Angreifer kommt also nicht über eine alte Sitzung zurück.

Das Verbot, PHP aus dem Upload-Verzeichnis auszuführen, bedeutet, dass der Server eine dort gelandete weitere Shell nicht ausführt.

Abgeschaltetes Bearbeiten von Dateien und ein Datenbankkonto mit minimalen Rechten verkleinern, was sich nach einem künftigen Fehler tun lässt.

Was das nicht löst: eine Schwachstelle in einem Plugin, das Sie behalten, oder einen Fehler im Hosting, das Sie mit anderen Seiten teilen. Deshalb sind Updates und wenige Plugins wichtig.

07Überprüfung

  • Die Datei des Plugins antwortet auf einen Upload nicht mehr, das Plugin ist entfernt.
  • Im Upload-Verzeichnis liegt kein unbekanntes PHP, und den Versuch, eines auszuführen, weist der Server ab.
  • Der eingeschleuste Code ist aus Datenbank und Theme verschwunden, und die Seite leitet auf dem Handy nicht mehr um.
  • Nach der Prüfung entfernte Google die Markierung, und die Dateiintegrität wird nun gegen einen Grundzustand überwacht.

08Ergebnisse

Behoben

  • Der Weg, der den Code-Upload erlaubte, ist geschlossen und die Shell entfernt.
  • Die eingeschleuste Umleitung und der Spam sind weg, und Google markiert die Seite nicht mehr.

Risiko gesenkt

  • PHP lässt sich nicht aus dem Upload-Verzeichnis ausführen.
  • Das Bearbeiten von Dateien ist aus, und das Datenbankkonto hat nur die nötigen Rechte.
  • Plugins aktualisieren sich automatisch, und die Dateiintegrität wird überwacht.

Weiter offen

  • Für den Zeitraum vor dem Neuaufbau lässt sich nicht belegen, was der Angreifer alles mit dem Server tat.
  • Solange die Seite auf Plugins Dritter beruht, ist jedes ein möglicher nächster Weg.

09Grenzen

  • Die Sicherheit einer Seite ist nur so gut wie ihr schwächstes Plugin. Jedes behaltene Plugin muss aktualisiert werden.
  • Die Integritätsüberwachung erkennt eine Änderung nur, wenn jemand die Warnung bemerkt und handelt.
  • Auf geteiltem Hosting kann auch ein kompromittierter Nachbar eine Seite gefährden. Diese Seite läuft auf einem eigenen VPS, was das begrenzt, einen Fehler in der Hosting-Umgebung aber nicht ausschließt.

10Erkenntnisse

  • Eine gehackte Seite bedeutet einen gehackten Server. Die Shell zu löschen genügt nicht, aus sauberen Quellen neu aufbauen.
  • Ein veraltetes Plugin mit bekannter Schwachstelle ist der häufigste Weg in eine WordPress-Seite. Aktualisieren oder entfernen.
  • Nach einer Kompromittierung jedes Geheimnis wechseln, auch die Sicherheitsschlüssel, sonst kehrt der Angreifer über eine alte Sitzung zurück.
  • Im Upload-Verzeichnis hat PHP nichts zu suchen. Verbieten Sie es.
  • Weniger Plugins bedeuten eine kleinere Angriffsfläche. Was die Seite nicht braucht, gehört nicht dorthin.
  • Ein Backup, dessen Wiederherstellung Sie nie versucht haben, ist nicht verifiziert, und einen Vorfall bemerken Sie spät, wenn Sie die Integrität nicht überwachen.

11Nächste Schritte für eine kleine Firma

  1. 1.Automatische Updates einschalten und regelmäßig prüfen, welche Plugins wirklich nötig sind.
  2. 2.Ein zweiter Faktor für die Anmeldung zur Verwaltung und eine Begrenzung der Anmeldeversuche.
  3. 3.Der Seite eine Schutzschicht voranstellen (etwa Cloudflare) und die Dateiintegrität überwachen.
  4. 4.Eine Wiederherstellung aus dem Backup verifizieren, damit sie beim nächsten Problem sicher ist.
Kontakt aufnehmen

Erkennen Sie Ihre eigene Firma darin?

Schreiben Sie uns, worum es geht. Wir antworten innerhalb eines Werktags und sagen Ihnen, ob es Arbeit für uns ist, auch wenn die Antwort nein lautet.