secaudit.eu
Notfall

WordPress-Redirect-Hack: Weiterleitungen finden und entfernen

WordPress-Redirect-Hack: bedingte Weiterleitungen mit curl und DevTools nachstellen, in .htaccess, PHP, Datenbank oder CDN finden und dauerhaft stoppen.

Von , AngelForce OÜ 7 Min. Lesezeit

Auch auf: English Français Español Italiano Polski Português Türkçe

Ein WordPress-Redirect-Hack ist so gebaut, dass ausgerechnet Sie als Betreiber ihn nicht bemerken. Der Schadcode prüft, wer die Seite aufruft, und leitet nur bestimmte Besucher um. Das sind vor allem Smartphone-Nutzer und Besucher, die über Google oder soziale Netzwerke kommen. Häufig trifft es jeden Besucher nur ein einziges Mal. Eingeloggte Benutzer und Administratoren lässt der Code meist absichtlich in Ruhe.

Wenn ein Kunde also sagt „Ihre Website hat mich auf eine dubiose Gewinnspielseite geschickt“ und auf Ihrem Laptop alles normal aussieht, glauben Sie dem Kunden. Typische Ziele sind Betrugsseiten, gefälschte Gewinnspiele, aggressive Werbenetzwerke oder Malware-Downloads. Google kann die Website als gefährlich markieren, und Besucher verlieren das Vertrauen. Weiterleitungen sind nur eines von mehreren Symptomen. Die anderen beschreiben wir in 12 Anzeichen, dass Ihre WordPress-Website gehackt wurde.

Warum Betreiber den WordPress-Redirect-Hack nie sehen

Die Bedingungen sind simpel und wirkungsvoll. Der Code liest den User-Agent-Header aus, um Smartphones zu erkennen, und den Referer-Header, um Besucher aus Suchmaschinen zu erkennen. Außerdem prüft er, ob das Login-Cookie von WordPress gesetzt ist. Nach der ersten Weiterleitung setzt er ein eigenes Cookie oder merkt sich die IP-Adresse, damit dieselbe Person nicht erneut umgeleitet wird.

Diese Kombination erklärt die meisten Fälle von „Ich kann das nicht nachvollziehen“. Sie sind eingeloggt, sitzen am Desktop, tippen die Adresse direkt ein und wurden womöglich schon einmal umgeleitet. Jede einzelne dieser Bedingungen kann die Weiterleitung abschalten.

Diagramm: die Ebenen, in denen sich eine Spam-Weiterleitung verstecken kann, vom CDN-Cache bis zum eingeschleusten JavaScript im Browser
Eine Anfrage durchläuft mehrere Ebenen. Jede kann eine Weiterleitung enthalten, und die Art der Antwort zeigt Ihnen, wo Sie suchen müssen.

Die Weiterleitung gefahrlos nachstellen

Bevor Sie Dateien durchsuchen, klären Sie, welche Art von Weiterleitung vorliegt. Die Art der Antwort verrät Ihnen, auf welcher Ebene Sie suchen müssen.

Beginnen Sie im Browser. Öffnen Sie ein privates Fenster und stellen Sie sicher, dass Sie ausgeloggt sind. Öffnen Sie die Entwicklertools (F12 in Chrome, Edge und Firefox) und schalten Sie die Gerätesymbolleiste ein (Strg+Umschalt+M), um ein Smartphone zu simulieren. Aktivieren Sie im Tab Netzwerk die Option Log beibehalten (in Firefox: Logs beibehalten im Einstellungsmenü des Netzwerk-Tabs), damit die Einträge den Seitenwechsel überstehen. Für einen echten Google-Referrer suchen Sie bei Google nach Ihrer eigenen Domain und klicken auf das Suchergebnis.

Sehen Sie sich jetzt den ersten Eintrag im Netzwerk-Tab an:

  • **Status 301, 302, 307 oder 308 mit fremder Location**: Die Weiterleitung passiert auf dem Server. Dazu gehören das CDN, die Regeln des Webservers, PHP und WordPress selbst.
  • Status 200, danach eine Anfrage an eine fremde Domain: Die Seite wurde normal geladen, dann hat JavaScript (oder ein Meta-Refresh-Tag) den Browser weggeschickt. Suchen Sie nach eingeschleustem Skript.

Bestätigen Sie das Ergebnis anschließend mit curl. Curl führt nie JavaScript aus und folgt Weiterleitungen nur, wenn Sie es ausdrücklich verlangen. Der folgende Befehl sendet eine normale GET-Anfrage und gibt nur die Antwort-Header aus. Verzichten Sie auf curl -I, denn mancher eingeschleuste Code ignoriert HEAD-Anfragen:

curl -s -o /dev/null -D - \
  -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1" \
  -e https://www.google.com/ \
  https://example.com/

Eine Location:-Zeile, die auf eine unbekannte Domain zeigt, bestätigt eine serverseitige Weiterleitung. Steht in der Statuszeile 200, laden Sie den Seiteninhalt und durchsuchen ihn nach Weiterleitungscode und Verschleierung:

curl -s -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X)" \
  -e https://www.google.com/ https://example.com/ \
  | grep -Eio 'window\.location|location\.href|location\.replace|http-equiv=.?refresh|atob\(|eval\(|fromCharCode|script[^>]+src="[^"]+"'

Wiederholen Sie den Test ohne -A und -e und vergleichen Sie die Ergebnisse. Prüfen Sie danach mehrere URLs, etwa einen Blogbeitrag, eine Produktseite und die Kontaktseite. Viele Injektionen betreffen nur einzelne Templates.

Ein sauberes Ergebnis beweist nicht, dass die Website sauber ist. Leitet der Code jede IP-Adresse nur einmal um oder zielt er nur auf bestimmte Länder, kann Ihr Test ihn verfehlen. Testen Sie zusätzlich aus einem anderen Netz, zum Beispiel mit dem Smartphone über mobile Daten.

Serverseitige Weiterleitungen: .htaccess, Serverkonfiguration und PHP, das zuerst läuft

Zeigt curl einen 3xx-Status mit fremder Domain, durchsuchen Sie den Server und den Code, der läuft, bevor WordPress irgendetwas ausgibt.

Unter Apache prüfen Sie jede .htaccess-Datei, nicht nur die im Web-Root. Suchen Sie nach Rewrite-Bedingungen auf User-Agent oder Referrer und nach auto_prepend_file. Diese Direktive bringt PHP dazu, vor jeder Anfrage eine Datei des Angreifers zu laden:

grep -rn --include=.htaccess -E "HTTP_(USER_AGENT|REFERER)|auto_prepend_file" .
grep -rn --include=.user.ini --include=php.ini "auto_prepend_file" .

Legitime Zeilen mit RewriteCond %{HTTP_USER_AGENT} gibt es durchaus, etwa bei manchen Cache-Plugins. Eine Regel, die Smartphone- oder Google-Besucher auf eine Domain schickt, die Sie nicht kennen, ist dagegen nicht legitim.

Listen Sie als Nächstes PHP- und Konfigurationsdateien auf, die kürzlich geändert wurden. Angreifer können Zeitstempel von Dateien zurücksetzen. Betrachten Sie die Liste deshalb als Ausgangspunkt, nicht als Beweis. Führen Sie den Befehl im WordPress-Stammverzeichnis aus:

find . -type f \( -name "*.php" -o -name ".htaccess" -o -name ".user.ini" \) -mtime -14 -print

Sehen Sie sich alles genau an, was am Anfang oder Ende der wp-config.php hinzugefügt wurde, und jede Datei in wp-content/mu-plugins. Must-Use-Plugins werden automatisch geladen und erscheinen nicht in der normalen Plugin-Liste. Prüfen Sie auch die functions.php des aktiven Themes. Führen Sie dann wp core verify-checksums aus, um veränderte Core-Dateien zu finden. Wie Sie die Ausgabe lesen und den Core sicher neu installieren, erklärt unsere Anleitung zum Prüfen der WordPress-Checksummen.

Unter nginx stehen die Regeln in der Serverkonfiguration, nicht in .htaccess. Bei Managed Hosting haben Sie darauf möglicherweise keinen Zugriff. In beiden Fällen bitten Sie Ihren Hoster, auf Serverebene nach Weiterleitungsregeln und Prepend-Einstellungen zu suchen.

Die Optionen siteurl und home

Eine andere, plumpere Variante ändert die Optionen siteurl und home. WordPress leitet dann jeden Besucher auf die Domain des Angreifers um, auch Sie selbst. Prüfen Sie beide Werte:

wp option get siteurl
wp option get home

Ohne WP-CLI öffnen Sie phpMyAdmin und sehen sich die Tabelle wp_options an. Ihr Tabellenpräfix kann von wp_ abweichen. Schauen Sie deshalb in der wp-config.php nach $table_prefix. So korrigieren Sie die Werte:

wp option update siteurl 'https://example.com'
wp option update home 'https://example.com'

Führen Sie außerdem grep -n "WP_HOME\|WP_SITEURL" wp-config.php aus. Sind diese Konstanten definiert, überschreiben sie die Werte aus der Datenbank. Ein Angreifer kann sie dort platzieren, und Ihre Korrektur in der Datenbank scheint dann wirkungslos.

JavaScript-Weiterleitungen in Beiträgen, Widgets, Theme-Dateien und Header-Skripten

Eine 200-Antwort, auf die ein Sprung zu einer anderen Domain folgt, bedeutet: Auf der Seite läuft ein Skript. Es kann an mehreren Stellen stecken:

  • Beitragsinhalte: eingeschleuste Script-Tags in post_content, oft in Dutzenden Beiträgen gleichzeitig.
  • Optionen: Widget-Einträge (widget_*), Theme-Optionen und Einstellungen von Page Buildern in wp_options.
  • Einstellungen à la „Insert headers and footers“: Code-Snippet-Plugins und Page Builder speichern dort websiteweite Skripte. Ein Angreifer mit Admin-Zugang muss nur eine Zeile einfügen.
  • Theme- und Plugin-Dateien: header.php, footer.php und eingebundene JavaScript-Dateien.

Eine schnelle Datenbanksuche (passen Sie wp_posts an, falls Ihr Tabellenpräfix anders lautet):

wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%script%src=%';"
wp db search 'fromCharCode' --all-tables
wp option list --search='widget_*' --fields=option_name

Rechnen Sie mit Verschleierung. Eingeschleuster Code enthält die Ziel-URL selten im Klartext. Achten Sie auf atob(, lange Base64-Zeichenketten, String.fromCharCode und Skriptquellen, die bekannte CDN- oder Analytics-Domains mit leicht abweichender Schreibweise nachahmen. Die Suchtechnik in der Datenbank und die Bereinigung behandeln wir ausführlicher in WordPress-SEO-Spam.

Zwischengespeicherte Kopien: Cache-Plugins, Server-Cache und CDN

Sie können den Ursprungsserver vollständig bereinigen, und Besucher werden trotzdem weiter umgeleitet, weil die infizierte Seite noch irgendwo gespeichert ist. Kopien überleben in Page-Cache-Dateien (wp-content/cache), in einem Object Cache wie Redis oder Memcached, im Server-Cache Ihres Hosters und auf den Edge-Servern des CDN.

Leeren Sie die Caches in der Reihenfolge der Anfrage, vom Ursprung nach außen:

  1. Schließen Sie die Bereinigung von Dateien und Datenbank auf dem Ursprungsserver ab.
  2. Leeren Sie den Page Cache des Cache-Plugins.
  3. Leeren Sie den Object Cache mit wp cache flush.
  4. Leeren Sie den Server-Cache im Hosting-Panel.
  5. Leeren Sie beim CDN den gesamten Cache.
  6. Testen Sie erneut mit den curl-Befehlen von oben, jeweils mit und ohne Smartphone-User-Agent und Google-Referrer.

Denken Sie auch an den umgekehrten Fall: Jemand hat die Weiterleitung direkt auf CDN- oder DNS-Ebene eingerichtet. Wer Zugriff auf Ihr CDN-Konto hat, kann eine Weiterleitungsregel anlegen, ohne WordPress anzufassen. Prüfen Sie die Redirect- und Page-Rules im CDN-Dashboard sowie Ihre DNS-Einträge. Kontrollieren Sie, wer Zugänge zu diesen Konten hat, und entziehen Sie Zugriffe, die nicht mehr gebraucht werden.

Das Einfallstor finden, sonst kommt die Weiterleitung zurück

Die Weiterleitung ist die Nutzlast, nicht das Loch. Wenn Sie nur die Nutzlast löschen, ist sie meist innerhalb weniger Tage wieder da, weil der Weg hinein noch offen ist. Typische Einfallstore sind verwundbare oder genullte Plugins, gestohlene Admin- oder Hosting-Zugangsdaten, Web-Shells in wp-content/uploads und übrig gebliebene Hintertüren, die den Code über einen Cronjob oder eine Datenbankoption erneut einschleusen.

Eine kurze erste Prüfung:

  • Unbekannte Administratoren: wp user list --role=administrator
  • Anwendungspasswörter, die Sie nicht angelegt haben (Benutzer > Profil)
  • Unbekannte geplante Ereignisse: wp cron event list
  • PHP-Dateien im Uploads-Ordner: find wp-content/uploads -name "*.php"
  • Veraltete oder genullte Plugins und Themes

Sobald das Loch geschlossen ist, ändern Sie die Passwörter für Admin, Hosting, Datenbank, SFTP und CDN. Erneuern Sie anschließend die Salts mit wp config shuffle-salts. Dadurch werden alle Benutzer abgemeldet. Für die Beweissicherung und die Entscheidung zwischen Bereinigen und Wiederherstellen folgen Sie dem vollständigen Plan zur Malware-Entfernung in WordPress.

Möglicherweise konnte der Angreifer auch Kundendaten, Einträge aus Kontaktformularen oder Bestellungen einsehen. Dann müssen Sie den Vorfall als mögliche Verletzung des Schutzes personenbezogener Daten, also als Datenpanne, bewerten. Lesen Sie dazu die 72-Stunden-Meldepflicht nach DSGVO.

FAQ

Warum werden nur Smartphone-Nutzer umgeleitet?

Wer auf dem Smartphone surft, bemerkt eine seltsame Adresszeile seltener und tippt sich eher durch Betrugsseiten. Betreiber prüfen ihre Website außerdem meist am Desktop und eingeloggt. Die Bedingung „nur mobil“ soll die Weiterleitung vor Ihnen verbergen.

Google zeigt „Diese Website wurde möglicherweise gehackt“. Was nun?

Bereinigen Sie zuerst die Website, schließen Sie das Einfallstor und leeren Sie alle Caches. Beantragen Sie dann in der Google Search Console eine Überprüfung. Den Ablauf beschreiben wir in WordPress-SEO-Spam. Wenn Sie die Überprüfung beantragen, bevor die Weiterleitung wirklich weg ist, scheitert sie in der Regel.

Kann ein Sicherheits-Plugin die Weiterleitung für mich entfernen?

Scanner helfen beim Finden. Die manuelle Bereinigung und die Suche nach dem Einfallstor ersetzen sie nicht. Das Audit-Plugin von secaudit.eu prüft die Dateiintegrität gegen eine Baseline und meldet Hinweise auf eine Kompromittierung wie versteckte Administratoren, verdächtige Cron-Ereignisse und Spam in der Datenbank. Außerdem sucht es nach verstecktem SEO-Spam. Es erkennt und meldet. Den Code entfernen und das Loch schließen müssen Sie selbst oder ein Fachmann, den Sie beauftragen.

Prüfen Sie Ihre eigene Website

Security Audit & Compliance ist das WordPress-Plugin von secaudit.eu: Es sucht nach Malware, verstecktem Spam, veränderten Kerndateien und unsicherem Code und ordnet seine Befunde DSGVO Art. 32, NIS2 Art. 21 und den OWASP Top 10 zu.

Sehen, was das Plugin prüft
Melike Görel

Melike Görel schreibt die secaudit.eu-Ratgeber zu WordPress-Sicherheit und EU-Compliance für die AngelForce OÜ, das Softwareunternehmen aus Tallinn hinter secaudit.eu.

Mit KI-Unterstützung erstellt und vor der Veröffentlichung auf Fakten geprüft. Dieser Artikel ist eine allgemeine Information und keine Rechtsberatung.