Auditoria técnica em WordPress: XML-RPC, REST API e CVEs com automação Bash e hardening orientado a evidência
Voltar para blog

Auditoria técnica em WordPress: XML-RPC, REST API e CVEs com automação Bash e hardening orientado a evidência

07/06/2026 · 4 min · WordPress

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:

  1. correlação de versão do core com CVEs (NVD + OSV);
  2. mapeamento de métodos no xmlrpc.php com foco em system.multicall;
  3. 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#

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, o consolidado funcional com foco no core da auditoria. Você pode expandir e inspecionar o código completo abaixo sem sair da página, executá-lo no Google Colab ou acessar a versão mantida no Gist:

wp-audit-xmlrpc-rest.sh — Script consolidado de 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)#

  1. Não use -e para strings; para texto use [[ -n "$VAR" ]].
  2. Sempre capture retorno de função com VAR=$(funcao).
  3. Para listas dinâmicas, use arrays (evita perda de dados em loop).
  4. Em API externa (NVD), aplique timeout/retry para robustez.
  5. Trate ausência de dados com ? no jq para 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#

Exemplo NGINX (bloqueio total):

location = /xmlrpc.php {
deny all;
return 403;
}

7.2 REST API users#

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#

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 artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários