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/03/2026 · 4 min · WordPress

Compartilhar

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, 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)

  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.

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.