WordPress em instalação padrão, sem endurecimento, costuma expor superfície suficiente para enumeração de usuários, brute-force otimizado e exploração de vulnerabilidades conhecidas do core/plugins.
Neste artigo, documento o fluxo real que apliquei para auditoria técnica com Bash em três frentes críticas:
- correlação de versão do core com CVEs (NVD + OSV);
- mapeamento de métodos no
xmlrpc.phpcom foco emsystem.multicall; - validação de enumeração de usuários via REST API.
O objetivo não foi apenas “coletar informação”, mas gerar evidência objetiva para remediação imediata.
1) Coleta de versão e baseline do alvo
Antes de consultar CVEs, normalizei alvo e versão detectada. Em ambiente real, este passo evita falso positivo por detecção parcial de versão.
Exemplo de baseline:
TARGET="https://domain.tld"
# Tentativa via generator meta tag (não é infalível)
SITE_VERSION=$(curl -skL "$TARGET" | grep -oP 'WordPress\s+\K[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)
# Fallback simples por readme (quando exposto)
if [[ -z "$SITE_VERSION" ]]; then
SITE_VERSION=$(curl -skL "$TARGET/readme.html" | grep -oP 'Version\s+\K[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)
fi
echo "Versão identificada: ${SITE_VERSION:-nao detectada}"
Se a versão não for detectada externamente, eu marco como “unknown” e sigo com auditoria de superfície (XML-RPC/REST), sem inferir segurança por obscuridade.
2) Consulta automatizada de CVEs (NVD + OSV)
A etapa seguinte foi correlacionar a versão detectada no core com vulnerabilidades públicas.
2.1 Função Bash para API da NVD
fetch_nvd_cves() {
local wp_ver="$1"
local encoded="wordpress%20$wp_ver"
curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=$encoded&keywordExactMatch" |
jq -r '.vulnerabilities[] |
"- " + .cve.id + ": " +
(.cve.descriptions[] | select(.lang=="en").value) +
" (https://osv.dev/vulnerability/" + .cve.id + ")"'
}
2.2 Correção de bug frequente na validação de retorno
Erro comum: chamar a função e testar variável não preenchida. O fluxo correto é capturar output antes da validação:
nvd_cves=$(fetch_nvd_cves "$SITE_VERSION")
if [[ -n "${nvd_cves//[[:space:]]/}" ]]; then
echo "$nvd_cves"
else
echo "Nenhuma CVE encontrada para a versão $SITE_VERSION"
fi
Esse detalhe evita falso “nenhuma CVE” por erro de lógica Bash.
2.3 Tratamento de resiliência (produção)
Em rotina operacional, adicionei timeout/retry para evitar pipeline quebrar por instabilidade de API externa:
curl -s --connect-timeout 8 --max-time 25 --retry 2 --retry-delay 1 "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=$encoded&keywordExactMatch"
3) XML-RPC: mapeamento de métodos e risco de brute-force consolidado
xmlrpc.php continua sendo vetor relevante, principalmente quando system.multicall está habilitado.
3.1 Coleta de métodos com system.listMethods
XMLRPC_GET_METHODS=$(curl -sLk -X POST "$TARGET/xmlrpc.php" \
-H "Content-Type: text/xml" \
--data '<?xml version="1.0"?>
<methodCall>
<methodName>system.listMethods</methodName>
</methodCall>')
3.2 Parse correto com array (evita sobrescrita em loop)
declare -a XMLRPC_METHODS_LIST
while IFS= read -r METHOD; do
XMLRPC_METHODS_LIST+=("$METHOD")
done < <(echo "$XMLRPC_GET_METHODS" | grep -oP '(?<=<string>).*?(?=</string>)')
O uso de array aqui é obrigatório para manter lista íntegra de métodos retornados.
3.3 Detecção precisa de system.multicall
if printf '%s\n' "${XMLRPC_METHODS_LIST[@]}" | grep -q "^system.multicall$"; then
echo "system.multicall ATIVO – Risco crítico de Brute-Force via XML-RPC"
fi
Nota operacional: não usar -e (teste de existência de arquivo) para validar string/lista. Para conteúdo textual, use [[ -n ... ]] ou grep -q como acima.
3.4 Classificação de severidade que apliquei
system.multicallpresente: severidade alta (acelera brute-force em lote por request);wp.getUsersBlogs+ autenticação fraca: risco elevado de enumeração/credential stuffing;- endpoint XML-RPC ativo sem WAF/rate limit: superfície ampliada de abuso.
4) Enumeração de usuários via REST API
A rota /wp-json/wp/v2/users pode expor metadados públicos de autores e facilitar ataque direcionado.
4.1 Coleta e parse de usuários
REST_USERS=$(curl -sk "$TARGET/wp-json/wp/v2/users" |
jq -r '.[] | "\(.id): \(.name) (\(.slug))"' 2>/dev/null)
if [[ -n "$REST_USERS" ]]; then
echo "Usuários encontrados:"
echo "$REST_USERS"
# Heurística: ID 1 exposto
if echo "$REST_USERS" | grep -q "^1:"; then
echo "ALERTA: Usuário ID 1 (admin padrão) está exposto!"
fi
# Heurística: slugs sensíveis
if echo "$REST_USERS" | grep -Eiq "admin|administrator|root"; then
echo "AVISO: Nomes de usuários administrativos detectados no slug."
fi
fi
4.2 Limitação técnica importante
Sem autenticação, a REST API não entrega role/capability de forma direta. Ela expõe metadados públicos; portanto, o risco vem da inteligência agregada (nome + slug + padrão de autoria), não de privilégio explícito retornado no endpoint público.
5) Script consolidado de auditoria (base que usei)
Abaixo, um consolidado funcional com foco no core da auditoria:
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-https://domain.tld}"
fetch_nvd_cves() {
local wp_ver="$1"
local encoded="wordpress%20$wp_ver"
curl -s --connect-timeout 8 --max-time 25 --retry 2 --retry-delay 1 \
"https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=$encoded&keywordExactMatch" |
jq -r '.vulnerabilities[]? |
"- " + .cve.id + ": " +
(.cve.descriptions[] | select(.lang=="en").value) +
" (https://osv.dev/vulnerability/" + .cve.id + ")"'
}
echo "[+] Alvo: $TARGET"
SITE_VERSION=$(curl -skL "$TARGET" | grep -oP 'WordPress\s+\K[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1 || true)
echo "[+] Versão detectada: ${SITE_VERSION:-nao detectada}"
if [[ -n "${SITE_VERSION:-}" ]]; then
echo "[+] Consultando CVEs no NVD..."
nvd_cves=$(fetch_nvd_cves "$SITE_VERSION")
if [[ -n "${nvd_cves//[[:space:]]/}" ]]; then
echo "$nvd_cves"
else
echo "Nenhuma CVE encontrada para a versão $SITE_VERSION"
fi
fi
echo "[+] Testando XML-RPC methods..."
XMLRPC_GET_METHODS=$(curl -sLk -X POST "$TARGET/xmlrpc.php" \
-H "Content-Type: text/xml" \
--data '<?xml version="1.0"?>
<methodCall><methodName>system.listMethods</methodName></methodCall>' || true)
declare -a XMLRPC_METHODS_LIST
while IFS= read -r METHOD; do
XMLRPC_METHODS_LIST+=("$METHOD")
done < <(echo "$XMLRPC_GET_METHODS" | grep -oP '(?<=<string>).*?(?=</string>)' || true)
if printf '%s\n' "${XMLRPC_METHODS_LIST[@]:-}" | grep -q "^system.multicall$"; then
echo "[!] system.multicall ATIVO – risco crítico"
else
echo "[-] system.multicall nao identificado"
fi
echo "[+] Testando enumeração REST users..."
REST_USERS=$(curl -sk "$TARGET/wp-json/wp/v2/users" | jq -r '.[]? | "\(.id): \(.name) (\(.slug))"' 2>/dev/null || true)
if [[ -n "${REST_USERS//[[:space:]]/}" ]]; then
echo "$REST_USERS"
echo "$REST_USERS" | grep -q '^1:' && echo "[!] ID 1 exposto"
echo "$REST_USERS" | grep -Eiq 'admin|administrator|root' && echo "[!] Slug sensível detectado"
else
echo "[-] Sem exposição direta de usuários ou endpoint restrito"
fi
6) Lições de trincheira (Bash e operação)
- Não use
-epara strings; para texto use[[ -n "$VAR" ]]. - Sempre capture retorno de função com
VAR=$(funcao). - Para listas dinâmicas, use arrays (evita perda de dados em loop).
- Em API externa (NVD), aplique timeout/retry para robustez.
- Trate ausência de dados com
?nojqpara evitar quebra de parser.
7) Roadmap de hardening após auditoria
Com achados confirmados, apliquei plano de mitigação por prioridade:
7.1 XML-RPC
- Bloquear
xmlrpc.phpquando não houver necessidade funcional; - se necessário manter, limitar métodos críticos e aplicar rate limit/WAF.
Exemplo NGINX (bloqueio total):
location = /xmlrpc.php {
deny all;
return 403;
}
7.2 REST API users
- Restringir exposição de autores para anônimos;
- rever naming policy de usuários/slugs administrativos.
7.3 Controle de brute-force
Rate-limit por IP/rota sensível no NGINX para reduzir efetividade de ataques automatizados, inclusive em cenários de system.multicall.
7.4 Gestão de vulnerabilidade
- Atualizar core/plugins/temas com janela controlada;
- registrar CVEs relevantes no backlog de segurança com SLA;
- repetir auditoria após patch para validação de remediação.
8) Conclusão técnica
Auditar WordPress com evidência técnica (CVE + superfície exposta + heurística de abuso) muda o jogo de segurança operacional: sai da percepção e entra em dados reproduzíveis.
Com Bash bem estruturado, você ganha velocidade para triagem, padroniza diagnóstico entre ambientes e converte resultado em hardening objetivo, reduzindo risco real de exploração.
Este post está licenciado sob CC BY-NC.
Comentários
Participe da discussão abaixo.
Comentários ainda não configurados. Adicione as opções do Cusdis em /assets/json/config/blog-comments-config.json.