Schadcode in WordPress lesen: eval(base64_decode()) entschlüsseln
Kurz gesagt
Verschleierter Schadcode in WordPress versteckt sich meist hinter eval(base64_decode(…)): Base64 ist keine Verschlüsselung, sondern eine Kodierung, die sich ohne Schlüssel zurückwandeln lässt. Wer den String dekodiert, statt ihn auszuführen, sieht, was der Code tut, etwa eine Hintertür, Spam-Links oder Weiterleitungen. Ein Treffer für base64_decode allein ist noch kein Beweis, die Kombination mit eval, gzinflate oder Nutzereingaben ist das eigentliche Warnsignal.
Wer eine gehackte WordPress-Seite untersucht, stößt fast immer auf dasselbe Muster: eine Zeile, die mit eval(base64_decode( beginnt und danach aus Hunderten scheinbar zufälligen Zeichen besteht. Das soll abschrecken und einfache Suchen ins Leere laufen lassen. Lesbar ist der Code trotzdem, und zwar ohne ihn auszuführen. Hier steht, wie du solche Stellen findest, sie gefahrlos entschlüsselst und was der Fund über den Angriff verrät.
Warum Angreifer Base64 benutzen
Base64 ist keine Verschlüsselung. Es ist eine Kodierung, die beliebige Daten in die Zeichen A–Z, a–z, 0–9, + und / übersetzt, am Ende oft mit einem oder zwei = aufgefüllt. Es gibt keinen Schlüssel: Wer den String hat, kann ihn zurückwandeln.
Für Angreifer hat das drei Vorteile:
- Sicherheits-Scanner und einfache Suchen nach verräterischen Begriffen wie
$_POST,systemoder fremden Domains finden im kodierten Text nichts. - Sonderzeichen stören nicht. Anführungszeichen und Zeilenumbrüche im Schadcode zerbrechen beim Einschleusen keine PHP-Syntax.
- Wer flüchtig hinsieht, hält den Block für Lizenzdaten oder eine eingebettete Grafik.
Ausgeführt wird der Code erst durch die Funktion davor. base64_decode macht den Text wieder lesbar, eval führt ihn als PHP aus. Diese Kombination ist das eigentliche Warnsignal.
Typische Muster
Die Grundform ist eine einzige Zeile:
<?php eval(base64_decode('aWYoaXNzZXQoJF9QT1NUWydjJ10pKS...')); ?>
Damit Suchen nach genau diesem Text nichts finden, wird sie oft abgewandelt:
- Mehrere Schichten:
eval(gzinflate(base64_decode('…')))odereval(str_rot13(base64_decode('…'))). Das Ergebnis einer Schicht ist die Eingabe der nächsten. - Zerlegte Funktionsnamen:
$f = 'base'.'64_'.'decode';und später$f('…'). Der Name steht nirgends am Stück. - Hex- oder chr()-Schreibweise:
"\x62\x61\x73\x65\x36\x34\x5f\x64\x65\x63\x6f\x64\x65"ist ebenfallsbase64_decode. - Nutzereingaben als Befehl:
eval(base64_decode($_POST['x'])). Hier steht der Schadcode gar nicht in der Datei, er kommt mit jeder Anfrage neu. Das ist eine Hintertür, über die der Angreifer beliebigen Code nachladen kann.
Wo du suchen solltest
Nicht jeder Treffer ist Schadcode. Auch der WordPress-Kern und seriöse Plugins nutzen base64_decode, etwa in mitgelieferten Bibliotheken. Die Suche liefert deshalb Kandidaten, keine Urteile.
Mit SSH-Zugang findest du die Kandidaten in einem Durchgang:
# Verdächtige Funktionsaufrufe in allen PHP-Dateien
grep -rnE "eval\s*\(|base64_decode\s*\(|gzinflate\s*\(|str_rot13\s*\(" --include="*.php" .
# PHP-Dateien im Uploads-Ordner: gehören dort nicht hin
find wp-content/uploads -name "*.php"
# Kern und Plugins mit den Originaldateien abgleichen (WP-CLI)
wp core verify-checksums
wp plugin verify-checksums --all
Ohne SSH bleibt der Weg per FTP: Dateien nach Änderungsdatum sortieren und die zuletzt geänderten öffnen. Besonders häufig betroffen sind:
- der Anfang von
wp-config.phpundindex.php, - die
functions.phpdes aktiven Themes, - der Ordner
wp-content/mu-plugins, dessen Plugins automatisch laden und im Backend leicht übersehen werden, - Dateien mit unauffälligen Namen wie
wp-cache.phpoderclass-wp-*.phpan Stellen, an denen es sie im Original nicht gibt.
Treffer, die verify-checksums meldet, sind besonders aussagekräftig: Die Datei weicht vom Original ab, obwohl das nie vorgesehen war.
Den Fund gefahrlos lesbar machen
Die wichtigste Regel: Die infizierte Datei niemals aufrufen und den Code niemals mit eval testen. Kopiere nur den String zwischen den Anführungszeichen oder die ganze Zeile und dekodiere sie getrennt davon.
Unser Werkzeug läuft vollständig in deinem Browser. Du kannst auch die ganze PHP-Zeile einfügen, der base64_decode(…)-Aufruf wird automatisch herausgelöst. Ausgeführt wird nichts, das Ergebnis erscheint nur als Text.
Base64-Werkzeug
Base64 kodieren oder dekodieren
Text eingeben, Richtung wählen, Ergebnis kopieren. Beim Dekodieren darfst du auch eine ganze PHP-Zeile mit base64_decode(…) einfügen.
# Oben Text eingeben … Deine Eingabe verlässt den Browser nicht. Dekodierter Code wird nur als Text angezeigt, nie ausgeführt.
Drei Fälle sind typisch:
- Lesbarer PHP-Code kommt heraus. Dann bist du fertig und kannst ihn deuten, siehe nächster Abschnitt.
- Das Ergebnis sieht wieder nach Base64 aus. Der Code ist mehrfach verpackt. Mit „Ergebnis erneut dekodieren“ gehst du Schicht für Schicht weiter.
- Es kommen nur Binärdaten heraus, angezeigt als Hex. Dann ist die nächste Schicht meist mit
gzinflatekomprimiert. Das Werkzeug kann sie nicht entpacken. Auf dem eigenen Rechner mit installiertem PHP geht es so, wobeievaldurchechoersetzt wird:
php -r 'echo gzinflate(base64_decode("HIER_DEN_STRING_EINFUEGEN"));'
Das gibt den Code nur aus und führt ihn nicht aus. Mach das auf deinem Rechner, nicht auf dem befallenen Server.
Was der entschlüsselte Code verrät
Der Klartext zeigt, was der Angreifer wollte, und damit, wo du weitersuchen musst:
- Hintertür: Code, der
$_POST,$_GET,$_COOKIEoder$_REQUESTaneval,system,execoderfile_put_contentsweiterreicht. Der Angreifer kann jederzeit neuen Code nachladen. Es gibt dann fast immer weitere Dateien mit demselben Zweck. - Weiterleitungen: Abfragen auf den User-Agent oder den Referrer, gefolgt von
header('Location: …'). Typisch sind Weiterleitungen nur für Besucher von Google oder nur auf dem Smartphone, damit der Betreiber am Desktop nichts bemerkt. - Spam-Links: Code, der HTML mit fremden Links in die Ausgabe schreibt, oft nur für Suchmaschinen-Crawler.
- Neue Administratoren: Aufrufe von
wp_insert_useroderwp_create_usermit der Rolleadministrator. Dann die Benutzerliste prüfen und unbekannte Konten entfernen. - Fremde Domains: Notiere jede Domain und jede IP-Adresse aus dem Klartext und suche danach in allen Dateien und in der Datenbank. Wo sie noch vorkommt, sitzt meist weiterer Schadcode.
Nach dem Fund: bereinigen statt löschen
Die verdächtige Zeile zu löschen, reicht selten. Wo eine Hintertür ist, sind meist weitere, und die Lücke, durch die sie kam, ist noch offen. Der Fund ist ein Hinweis, keine vollständige Diagnose.
Die eigentliche Bereinigung beschreibt unser Beitrag WordPress gehackt? Malware erkennen und bereinigen: sichern, Ausmaß eingrenzen, WordPress-Kern und Plugins aus sauberen Quellen ersetzen, Passwörter und Sicherheitsschlüssel erneuern, die Einfallstelle schließen. Wie du die Seite danach dauerhaft härtest, steht im Überblick zur WordPress-Sicherheit.
Das Werkzeug gibt es auch einzeln unter Base64 kodieren und dekodieren, zusammen mit unseren anderen kostenlosen Tools.
Du hast verschleierten Code gefunden und willst sicher sein, dass nichts übrig bleibt? Unser WordPress-Notfall-Service bereinigt die Seite und schließt die Lücke, oder schreib uns kurz.
Häufige Fragen
Ist base64_decode in einer WordPress-Datei immer Schadcode?
Nein. Auch der WordPress-Kern und seriöse Plugins nutzen base64_decode, etwa in mitgelieferten Bibliotheken oder für eingebettete Grafiken. Verdächtig wird es, wenn das Ergebnis direkt an eval, assert oder eine variable Funktion geht, wenn der String sehr lang ist oder wenn die Datei an einem Ort liegt, an dem kein PHP hingehört, zum Beispiel im Uploads-Ordner.
Kann das Dekodieren selbst gefährlich sein?
Nein, solange nichts ausgeführt wird. Dekodieren wandelt nur Zeichen um. Gefährlich wird es erst, wenn der Code an eval übergeben oder die infizierte Datei aufgerufen wird. Unser Base64-Werkzeug läuft im Browser und zeigt das Ergebnis nur als Text an.
Was mache ich, wenn das Ergebnis wieder nach Base64 aussieht?
Erneut dekodieren. Schadcode ist oft mehrfach verpackt, damit einfache Suchen ihn nicht finden. Kommen statt Text nur Binärdaten heraus, ist die Schicht meist mit gzinflate komprimiert. Die lässt sich auf dem eigenen Rechner mit PHP entpacken, indem man eval durch echo ersetzt.
Reicht es, die gefundene Zeile zu löschen?
Selten. Wo eine Hintertür ist, sind oft weitere, und die Lücke, über die sie kam, ist noch offen. Der Fund zeigt dir, was der Angreifer wollte. Die Bereinigung selbst heißt: WordPress-Kern und Plugins aus sauberen Quellen ersetzen, Konten und Passwörter prüfen, die Einfallstelle schließen.
Passende Leistungen
Gründer & Full-Stack-Entwickler
20+ Jahre Erfahrung in der Webentwicklung. Spezialisiert auf Laravel, WordPress und individuelle Software für den Mittelstand.