Seit dem 17. Juli 2026 wird eine kritische Schwachstelle im WordPress-Core aktiv ausgenutzt – ohne Login, ohne Plugin, auf einer Standardinstallation. Wer inzwischen aktualisiert hat, ist gegen neue Angriffe geschützt. Ob zwischen dem 17. Juli und dem Update bereits jemand ins System gelangt ist, sagt die Versionsnummer allerdings nicht aus. Genau diese Lücke von wenigen Stunden oder Tagen ist der Punkt, den man jetzt kontrollieren sollte.
Was passiert ist
wp2shell ist keine einzelne Lücke, sondern eine Kette: eine Schwachstelle in der REST-API-Batch-Route und eine SQL-Injection im WordPress-Core greifen so ineinander, dass ein anonymer Angreifer bis zur Codeausführung auf dem Server durchkommt. Die vollständige Übernahmekette betrifft WordPress 6.9.0 bis 6.9.4 sowie 7.0.0 und 7.0.1. Die Versionen 6.8.0 bis 6.8.5 enthalten zwar die SQL-Injection, aber nicht die vollständige Standardkette. Behoben ist das Problem in 6.8.6, 6.9.5 und 7.0.2.
Wie schnell so etwas heute ausgenutzt wird, zeigen die Zahlen von Patchstack: Rund 90 Minuten nach Veröffentlichung des Updates liefen die ersten Exploit-Versuche, bis zum 22. Juli waren es über 65’000 blockierte Versuche. Beobachtet wurden Datenbankabfragen, das Auslesen von Benutzerdaten, das Anlegen neuer Administratoren und das Ablegen von Webshells.
Der unangenehme Teil daran: Ein Update repariert die Lücke, aber es entfernt nichts, was vorher passiert ist. Ein zusätzlicher Administrator oder eine PHP-Datei im Upload-Ordner bleibt nach der Aktualisierung genau dort, wo sie ist. Und ein sauberer Scan von Wordfence, Imunify oder dem WP-Toolkit ist ein gutes Zeichen, aber kein forensischer Nachweis.
Der wichtigste Hinweis: Benutzerkonten
Das derzeit aussagekräftigste Anzeichen sind Administratoren, die niemand angelegt hat. Auffällig sind Konten, die seit dem 17. Juli 2026 registriert wurden, Benutzernamen nach dem Muster wp2_* oder w2s_* – etwa wp2_65aff658915c – sowie E-Mail-Adressen auf Domains wie @wp2shell.invalid oder @wp2shell.shellcode.lol. Ebenso verdächtig: ein bestehender Benutzer, der plötzlich Administratorrechte besitzt, Lücken in der Reihenfolge der Benutzer-IDs oder verwaiste Einträge in wp_usermeta, deren user_id in wp_users gar nicht mehr existiert.
Für den schnellen Blick genügt die WP-CLI:
wp user list --role=administrator \
--fields=ID,user_login,user_email,user_registered
Gründlicher ist der Weg über die Datenbank, weil dort auch Rechte sichtbar werden, die im Backend unauffällig wirken:
SELECT u.ID, u.user_login, u.user_email, u.user_registered, m.meta_value
FROM wp_users u
JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key LIKE '%capabilities%'
AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;
Wichtig ist die Umkehrung: Einzelne Exploit-Varianten löschen den angelegten Administrator nach Gebrauch wieder. Dass kein fremder Admin auftaucht, beweist also nicht, dass nichts passiert ist.
Dateien, Plugins und Webshells
Zweiter Prüfpunkt sind Dateien, die seit dem 17. Juli neu sind oder verändert wurden. Besonders im Blick behalten sollte man wp-content/plugins/, wp-content/mu-plugins/, wp-content/uploads/, wp-content/cache/ und wp-content/upgrade/. PHP-Dateien in Uploads oder im Cache haben dort schlicht nichts verloren.
find /var/www/vhosts/DOMAIN/httpdocs \
-type f -name "*.php" \
-newermt "2026-07-17 00:00:00" \
-printf "%TY-%Tm-%Td %TH:%TM:%TS %u %g %p\n" | sort
Bei den Plugins lohnt sich der Blick auf harmlos klingende Namen wie «Security», «Cache» oder «Performance» und ganz besonders auf Must-use-Plugins, die im normalen Plugin-Menü gar nicht erscheinen (wp plugin list --status=must-use). Wiz hat sowohl minimale Einzeiler-Webshells beobachtet als auch umfangreiche, als Plugin getarnte Varianten – manche liefern ohne das korrekte geheime POST-Argument absichtlich eine ganz normale 404-Seite aus.
In den Dateien selbst sind eval($_POST[...]), base64_decode, gzinflate, shell_exec, passthru, system oder exec die üblichen Kandidaten. Einzelne Vorkommen sind noch kein Beweis, legitime Plugins verwenden manche dieser Funktionen ebenfalls. Die Kombination aus Verschleierung, eval, Benutzereingaben und Systembefehlen ist dagegen ziemlich eindeutig.
Logs und Datenbank
Charakteristisch für diese Welle sind POST-Requests auf /wp-json/batch/v1 beziehungsweise die Varianten mit ?rest_route=/batch/v1. Seit dem 21. Juli wird der Parameter teilweise nur noch im POST-Body mitgeschickt – im Access-Log steht dann bloss POST / HTTP/1.1. Eine reine Suche nach «batch/v1» in der URL greift damit zu kurz.
zgrep -Eai \
'batch/v1|rest_route.?=.?/batch/v1|author_exclude|author__not_in|wp2shell|wp/v2/users|wp/v2/plugins|upload-plugin' \
/var/www/vhosts/system/DOMAIN/logs/*access* \
/var/log/apache2/* /var/log/nginx/* 2>/dev/null
Solche Treffer belegen zunächst nur einen Versuch. Interessant wird die Abfolge danach: ein erfolgreicher Aufruf von /wp-admin/ durch eine fremde IP, ein Plugin-Upload über /wp-admin/update.php?action=upload-plugin kurz nach dem Batch-Request oder der direkte Abruf einer neuen PHP-Datei unter wp-content/uploads/. Genau diese Kette wurde bei tatsächlich erfolgreichen Übernahmen beobachtet.
Und weil einige öffentlich verfügbare Exploits nach dem Test aufräumen, Benutzer und Webshell also wieder entfernen, ist die Datenbank oft aussagekräftiger als das Log. Zurück bleiben typischerweise unerwartete customize_changeset-Beiträge, Changesets mit unplausiblen post_parent-Werten, auffällige oEmbed-Cache-Einträge, unbekannte serialisierte Daten in wp_options oder ein Cronjob, den niemand eingerichtet hat. Ebenso zu prüfen sind Änderungen an active_plugins, siteurl und home.
Bei einer vollständigen Serverübernahme kommen Spuren ausserhalb von WordPress dazu: Cronjobs unter www-data, neue Dateien in /tmp, Prozesse wie curl, wget oder python, die von PHP-FPM gestartet wurden, ausgehende Verbindungen des Webservers an unbekannte Adressen, unbekannte SSH-Schlüssel oder eine veränderte .htaccess, .user.ini beziehungsweise wp-config.php.
Was noch kein Incident ist
Genauso wichtig ist die Gegenrichtung, sonst wird aus jeder Prüfung ein Notfall. Blockierte Requests in Wordfence oder Imunify, viele Zugriffe auf /wp-json/batch/v1, Anfragen von verdächtigen VPS-Adressen, ein Scanner-User-Agent oder ein Request, der mit 403 oder 500 endet: Das alles heisst nur, dass die Website angeschaut wurde. Auch der Umstand, dass eine Seite ein paar Tage lang auf einer verwundbaren Version lief, ist für sich genommen noch kein Befund. Die Kampagne besteht zu einem grossen Teil aus automatisiertem Scanning über Cloud- und VPS-Anbieter, und die meisten dieser Versuche laufen ins Leere.
Wann es ein Sicherheitsvorfall ist
Als Vorfall behandeln sollte man eine Website, sobald mindestens einer dieser Punkte zutrifft: ein unbekannter Administrator oder unerklärliche Admin-Rechte, ein unbekanntes Plugin oder MU-Plugin, eine neue PHP-Datei in Uploads oder Cache, ein erfolgreicher Admin-Zugriff nach einem Batch-Request, verdächtige Changeset- oder oEmbed-Artefakte, oder ein Webserver, der Systembefehle startet und Verbindungen nach aussen aufbaut.
Dann geht es nicht mehr ums Aufräumen einzelner Dateien, sondern um saubere Wiederherstellung, neue Zugangsdaten und Schlüssel und eine Kontrolle, ob wirklich nichts zurückgeblieben ist. Weniger dramatisch, aber genauso nützlich ist der umgekehrte Fall: eine dokumentierte Prüfung, die zeigt, dass nichts passiert ist. Bei Kundenprojekten ist das oft mehr wert als die Aktualisierung selbst – denn die hat spätestens das automatische Update erledigt, die Frage nach dem Zeitfenster davor beantwortet sie nicht.















