WPScan - Escáner de Vulnerabilidades para WordPress
WPScan - Escáner de Vulnerabilidades para WordPress
Section titled “WPScan - Escáner de Vulnerabilidades para WordPress”Introducción
Section titled “Introducción”WPScan es la herramienta de seguridad más popular y completa para auditorías de sitios WordPress. Desarrollada por el equipo de WPScan, esta herramienta de código abierto automatiza la detección de vulnerabilidades, enumeración de plugins, temas, usuarios y configuraciones inseguras en instalaciones de WordPress.
Características Principales
Section titled “Características Principales”- Base de datos actualizada: Más de 29,000 vulnerabilidades conocidas
- Enumeración avanzada: Plugins, temas, usuarios, medios
- Detección pasiva y agresiva: Múltiples modos de escaneo
- API integrada: Acceso a la base de datos de vulnerabilidades WPVulnDB
- Ataques de fuerza bruta: Integrado para credenciales
- Salida estructurada: JSON, CLI-friendly
Instalación
Section titled “Instalación”Kali Linux (Preinstalado)
Section titled “Kali Linux (Preinstalado)”# WPScan viene preinstalado en Kali Linuxwpscan --version
# Actualizar si es necesariosudo apt update && sudo apt upgrade wpscanUbuntu/Debian
Section titled “Ubuntu/Debian”# Instalar Ruby y dependenciassudo apt updatesudo apt install ruby ruby-dev build-essential libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev libgmp-dev zlib1g-dev
# Instalar WPScan como gemsudo gem install wpscan
# Verificar instalaciónwpscan --versionDocker
Section titled “Docker”# Usar imagen oficial de Dockerdocker pull wpscanteam/wpscan
# Ejecutar con Dockerdocker run -it --rm wpscanteam/wpscan --url https://ejemplo.comDesde Código Fuente
Section titled “Desde Código Fuente”# Clonar repositoriogit clone https://github.com/wpscanteam/wpscan.gitcd wpscan
# Instalar dependenciasbundle install
# Ejecutarruby wpscan.rb --url https://ejemplo.comConfiguración de API
Section titled “Configuración de API”Obtener Token de API
Section titled “Obtener Token de API”# Registrarse en https://wpscan.com/api# Obtener token gratuito (25 requests/día) o premium
# Configurar tokenwpscan --api-token TU_TOKEN_AQUI --url https://ejemplo.com
# Guardar token permanentementeecho "api_token: TU_TOKEN_AQUI" > ~/.wpscan/scan.ymlSintaxis Básica
Section titled “Sintaxis Básica”# Sintaxis generalwpscan [opciones] --url <URL>
# Escaneo básicowpscan --url https://ejemplo.com
# Escaneo con enumeraciónwpscan --url https://ejemplo.com --enumerate p,t,u
# Con API tokenwpscan --url https://ejemplo.com --api-token TOKENParámetros Principales
Section titled “Parámetros Principales”Opciones de Enumeración
Section titled “Opciones de Enumeración”| Parámetro | Descripción | Ejemplo |
|---|---|---|
-e, --enumerate | Enumerar componentes | -e p,t,u,m |
p | Plugins populares | -e p |
ap | Todos los plugins | -e ap |
vp | Plugins vulnerables | -e vp |
t | Temas populares | -e t |
at | Todos los temas | -e at |
vt | Temas vulnerables | -e vt |
u | Usuarios | -e u |
m | Archivos multimedia | -e m |
Opciones de Detección
Section titled “Opciones de Detección”| Parámetro | Descripción | Ejemplo |
|---|---|---|
--detection-mode | Modo de detección | --detection-mode aggressive |
--plugins-detection | Detección de plugins | --plugins-detection aggressive |
--plugins-version-detection | Detección de versiones | --plugins-version-detection aggressive |
Opciones de Salida
Section titled “Opciones de Salida”| Parámetro | Descripción | Ejemplo |
|---|---|---|
-f, --format | Formato de salida | -f json |
-o, --output | Archivo de salida | -o reporte.json |
--no-banner | Sin banner | --no-banner |
-v, --verbose | Modo verbose | -v |
Ejemplos Básicos
Section titled “Ejemplos Básicos”Escaneo Rápido
Section titled “Escaneo Rápido”# Escaneo básico con información generalwpscan --url https://ejemplo.com
# Ejemplo de salida:# [+] URL: https://ejemplo.com/# [+] Started: Mon Jan 01 12:00:00 2024# [+] Interesting Finding(s):# [+] WordPress version: 6.1.1 - Identified By: Rss Generator# [+] WordPress theme in use: twentytwentythreeEnumeración de Componentes
Section titled “Enumeración de Componentes”# Enumerar plugins populareswpscan --url https://ejemplo.com --enumerate p
# Enumerar usuarioswpscan --url https://ejemplo.com --enumerate u
# Enumeración completawpscan --url https://ejemplo.com --enumerate ap,at,u,m --api-token TOKENDetección Agresiva
Section titled “Detección Agresiva”# Modo agresivo (más detecciones, más requests)wpscan --url https://ejemplo.com --detection-mode aggressive --enumerate ap,at,u
# Solo plugins vulnerables con APIwpscan --url https://ejemplo.com --enumerate vp --api-token TOKENEjemplos Avanzados
Section titled “Ejemplos Avanzados”Script de Auditoría Completa
Section titled “Script de Auditoría Completa”#!/bin/bash
# Script de auditoría completa de WordPress con WPScan# Uso: ./wordpress_audit.sh <URL> [API_TOKEN]
URL=$1API_TOKEN=$2TIMESTAMP=$(date +%Y%m%d_%H%M%S)OUTPUT_DIR="wpscan_audit_${TIMESTAMP}"
if [ -z "$URL" ]; then echo "Uso: $0 <URL> [API_TOKEN]" exit 1fi
echo "[+] Iniciando auditoría completa de WordPress: $URL"mkdir -p $OUTPUT_DIR
# Función para ejecutar WPScan con parámetros comunesrun_wpscan() { local additional_params="$1" local output_file="$2"
if [ ! -z "$API_TOKEN" ]; then wpscan --url $URL --api-token $API_TOKEN $additional_params -f json -o $OUTPUT_DIR/$output_file else wpscan --url $URL $additional_params -f json -o $OUTPUT_DIR/$output_file fi}
# 1. Escaneo básicoecho "[+] Fase 1: Escaneo básico"run_wpscan "" "01_basic_scan.json"
# 2. Enumeración de plugins popularesecho "[+] Fase 2: Enumeración de plugins populares"run_wpscan "--enumerate p" "02_popular_plugins.json"
# 3. Enumeración de todos los plugins (si hay API token)if [ ! -z "$API_TOKEN" ]; then echo "[+] Fase 3: Enumeración completa de plugins" run_wpscan "--enumerate ap --plugins-detection aggressive" "03_all_plugins.json"fi
# 4. Enumeración de temasecho "[+] Fase 4: Enumeración de temas"run_wpscan "--enumerate t" "04_themes.json"
# 5. Enumeración de usuariosecho "[+] Fase 5: Enumeración de usuarios"run_wpscan "--enumerate u" "05_users.json"
# 6. Archivos multimediaecho "[+] Fase 6: Archivos multimedia"run_wpscan "--enumerate m" "06_media.json"
# 7. Detección agresivaecho "[+] Fase 7: Detección agresiva"run_wpscan "--detection-mode aggressive" "07_aggressive.json"
# 8. Solo vulnerabilidades (con API)if [ ! -z "$API_TOKEN" ]; then echo "[+] Fase 8: Solo vulnerabilidades" run_wpscan "--enumerate vp,vt" "08_vulnerabilities.json"fi
echo "[+] Auditoría completada. Resultados en: $OUTPUT_DIR"
# Generar resumengenerate_summary $OUTPUT_DIRFunción de Resumen
Section titled “Función de Resumen”generate_summary() { local output_dir=$1 local summary_file="$output_dir/RESUMEN_EJECUTIVO.txt"
echo "=== RESUMEN EJECUTIVO - AUDITORÍA WORDPRESS ===" > $summary_file echo "Fecha: $(date)" >> $summary_file echo "URL: $URL" >> $summary_file echo "" >> $summary_file
# Extraer información clave usando jq if [ -f "$output_dir/01_basic_scan.json" ]; then echo "=== INFORMACIÓN BÁSICA ===" >> $summary_file jq -r '.version.number // "No detectada"' $output_dir/01_basic_scan.json | sed 's/^/Versión WordPress: /' >> $summary_file jq -r '.main_theme.slug // "No detectado"' $output_dir/01_basic_scan.json | sed 's/^/Tema activo: /' >> $summary_file echo "" >> $summary_file fi
# Plugins encontrados if [ -f "$output_dir/02_popular_plugins.json" ]; then echo "=== PLUGINS DETECTADOS ===" >> $summary_file jq -r '.plugins | keys[]' $output_dir/02_popular_plugins.json >> $summary_file echo "" >> $summary_file fi
# Usuarios encontrados if [ -f "$output_dir/05_users.json" ]; then echo "=== USUARIOS ENCONTRADOS ===" >> $summary_file jq -r '.users | keys[]' $output_dir/05_users.json >> $summary_file echo "" >> $summary_file fi
# Vulnerabilidades (si hay API) if [ -f "$output_dir/08_vulnerabilities.json" ]; then echo "=== VULNERABILIDADES CRÍTICAS ===" >> $summary_file jq -r '.plugins[]?.vulnerabilities[]? | select(.fixed_in == null) | .title' $output_dir/08_vulnerabilities.json >> $summary_file echo "" >> $summary_file fi
echo "[+] Resumen ejecutivo generado: $summary_file"}Ataque de Fuerza Bruta Integrado
Section titled “Ataque de Fuerza Bruta Integrado”#!/bin/bash
# Ataque de fuerza bruta con WPScanwordpress_bruteforce() { local url=$1 local userlist=$2 local wordlist=$3 local threads=${4:-10}
echo "[+] Iniciando ataque de fuerza bruta" echo "URL: $url" echo "Usuarios: $userlist" echo "Wordlist: $wordlist" echo "Threads: $threads"
# Ejecutar ataque de fuerza bruta wpscan --url $url \ --usernames $userlist \ --passwords $wordlist \ --threads $threads \ --max-threads $threads \ -f json \ -o bruteforce_results.json
# Verificar resultados if grep -q "Valid Combinations Found" bruteforce_results.json; then echo "[!] CREDENCIALES ENCONTRADAS:" jq -r '.password_attack[].username + ":" + .password_attack[].password' bruteforce_results.json else echo "[-] No se encontraron credenciales válidas" fi}
# Crear lista de usuarios comúncreate_common_userlist() { cat > common_users.txt << EOFadminadministratorwp-admintestdemouserrootguestwwwwebblogsiteEOF}
# Uso del ataque de fuerza bruta# create_common_userlist# wordpress_bruteforce "https://ejemplo.com" "common_users.txt" "/usr/share/wordlists/rockyou.txt" 5Interpretación de Resultados
Section titled “Interpretación de Resultados”Información Básica
Section titled “Información Básica”{ "version": { "number": "6.1.1", "status": "latest", "found_by": "Rss Generator" }, "main_theme": { "slug": "twentytwentythree", "location": "https://ejemplo.com/wp-content/themes/twentytwentythree/", "style_uri": "https://ejemplo.com/wp-content/themes/twentytwentythree/style.css" }}Plugins Detectados
Section titled “Plugins Detectados”{ "plugins": { "akismet": { "slug": "akismet", "location": "https://ejemplo.com/wp-content/plugins/akismet/", "version": { "number": "4.2.1", "confidence": 100, "found_by": "Query Parameter" }, "vulnerabilities": [] } }}Usuarios Encontrados
Section titled “Usuarios Encontrados”{ "users": { "admin": { "id": 1, "username": "admin", "found_by": "Author Id Brute Forcing" }, "editor": { "id": 2, "username": "editor", "found_by": "Wp Json Api" } }}Técnicas Complementarias
Section titled “Técnicas Complementarias”Verificación Manual Post-WPScan
Section titled “Verificación Manual Post-WPScan”#!/bin/bash
post_wpscan_verification() { local url=$1 local wpscan_output=$2
echo "[+] Verificación manual post-WPScan"
# Extraer plugins de resultados WPScan plugins=$(jq -r '.plugins | keys[]' $wpscan_output)
for plugin in $plugins; do echo "[+] Verificando plugin: $plugin"
# Verificar archivos readme readme_status=$(curl -s -o /dev/null -w "%{http_code}" "$url/wp-content/plugins/$plugin/readme.txt") if [ "$readme_status" = "200" ]; then echo "[!] README accesible para $plugin" curl -s "$url/wp-content/plugins/$plugin/readme.txt" | head -10 fi
# Verificar changelog changelog_status=$(curl -s -o /dev/null -w "%{http_code}" "$url/wp-content/plugins/$plugin/changelog.txt") if [ "$changelog_status" = "200" ]; then echo "[!] CHANGELOG accesible para $plugin" fi done
# Verificar archivos sensibles adicionales sensitive_files=( "wp-config.php.bak" "wp-config.php.old" ".wp-config.php.swp" "wp-config.php~" "backup-wp-config.php" "wp-content/debug.log" "wp-content/uploads/wp-config.php" "error_log" ".htaccess.bak" "wp-admin/install.php" )
echo "[+] Verificando archivos sensibles adicionales" for file in "${sensitive_files[@]}"; do status=$(curl -s -o /dev/null -w "%{http_code}" "$url/$file") if [ "$status" = "200" ]; then echo "[!] CRÍTICO: $file accesible" elif [ "$status" = "403" ]; then echo "[?] PROTEGIDO: $file (existe pero inaccesible)" fi done}Análisis de Configuración de Seguridad
Section titled “Análisis de Configuración de Seguridad”#!/bin/bash
analyze_wp_security_config() { local url=$1
echo "[+] Analizando configuración de seguridad de WordPress"
# Verificar XML-RPC xmlrpc_status=$(curl -s -o /dev/null -w "%{http_code}" "$url/xmlrpc.php") if [ "$xmlrpc_status" = "200" ]; then echo "[!] RIESGO: XML-RPC habilitado" # Verificar métodos disponibles methods=$(curl -s -X POST "$url/xmlrpc.php" -d '<methodCall><methodName>system.listMethods</methodName></methodCall>') if [[ $methods == *"wp.getUsersBlogs"* ]]; then echo "[!] CRÍTICO: Método wp.getUsersBlogs disponible (fuerza bruta)" fi else echo "[+] XML-RPC deshabilitado" fi
# Verificar API REST api_status=$(curl -s -o /dev/null -w "%{http_code}" "$url/wp-json/wp/v2/users") if [ "$api_status" = "200" ]; then echo "[!] RIESGO: API REST expone usuarios" users=$(curl -s "$url/wp-json/wp/v2/users" | jq -r '.[].name' | head -5) echo "Usuarios expuestos: $users" else echo "[+] API REST protegida" fi
# Verificar directory listing uploads_listing=$(curl -s "$url/wp-content/uploads/" | grep -i "index of") if [ ! -z "$uploads_listing" ]; then echo "[!] RIESGO: Directory listing habilitado en uploads" else echo "[+] Directory listing deshabilitado" fi
# Verificar versión en generator generator=$(curl -s "$url" | grep -i "generator.*wordpress" | head -1) if [ ! -z "$generator" ]; then echo "[!] INFORMACIÓN: Versión WordPress expuesta en meta generator" echo "$generator" else echo "[+] Meta generator WordPress oculto" fi
# Verificar readme.html readme_status=$(curl -s -o /dev/null -w "%{http_code}" "$url/readme.html") if [ "$readme_status" = "200" ]; then echo "[!] INFORMACIÓN: readme.html accesible" else echo "[+] readme.html no accesible" fi}Integración con Otras Herramientas
Section titled “Integración con Otras Herramientas”Con Nuclei
Section titled “Con Nuclei”# Usar templates de WordPress en Nuclei después de WPScannuclei -u https://ejemplo.com -t ~/nuclei-templates/technologies/wordpress/
# Templates específicos basados en hallazgos de WPScannuclei -u https://ejemplo.com -t ~/nuclei-templates/vulnerabilities/wordpress/Con Metasploit
Section titled “Con Metasploit”# Usar módulos de Metasploit basados en hallazgosmsfconsole -q -x "use auxiliary/scanner/http/wordpress_scanner;set RHOSTS ejemplo.com;run;exit"Con Burp Suite
Section titled “Con Burp Suite”# Configurar proxy para capturar tráfico de WPScanexport http_proxy=http://127.0.0.1:8080export https_proxy=http://127.0.0.1:8080wpscan --url https://ejemplo.com --enumerate pCasos de Uso Específicos
Section titled “Casos de Uso Específicos”Auditoría de Múltiples Sitios
Section titled “Auditoría de Múltiples Sitios”#!/bin/bash
multi_site_wordpress_audit() { local sites_file=$1 local api_token=$2 local output_base="multi_audit_$(date +%Y%m%d_%H%M%S)"
mkdir -p $output_base
echo "[+] Iniciando auditoría de múltiples sitios WordPress"
while IFS= read -r url; do site_name=$(echo $url | sed 's/https\?:\/\///g' | sed 's/\/.*//g' | sed 's/\./_/g') echo "[+] Auditando: $site_name ($url)"
mkdir -p "$output_base/$site_name"
# WPScan básico if [ ! -z "$api_token" ]; then wpscan --url $url --api-token $api_token --enumerate vp,vt,u -f json -o "$output_base/$site_name/wpscan.json" else wpscan --url $url --enumerate p,t,u -f json -o "$output_base/$site_name/wpscan.json" fi
# Análisis de seguridad analyze_wp_security_config $url > "$output_base/$site_name/security_analysis.txt"
# Resumen por sitio echo "=== RESUMEN DE $site_name ===" >> "$output_base/resumen_general.txt" jq -r '.version.number // "No detectada"' "$output_base/$site_name/wpscan.json" | sed 's/^/Versión: /' >> "$output_base/resumen_general.txt" jq -r '.plugins | length' "$output_base/$site_name/wpscan.json" | sed 's/^/Plugins: /' >> "$output_base/resumen_general.txt" jq -r '.users | length' "$output_base/$site_name/wpscan.json" | sed 's/^/Usuarios: /' >> "$output_base/resumen_general.txt" echo "" >> "$output_base/resumen_general.txt"
sleep 10 # Delay entre sitios
done < $sites_file
echo "[+] Auditoría multi-sitio completada: $output_base"}
# Uso:# echo "https://sitio1.com" > sitios.txt# echo "https://sitio2.com" >> sitios.txt# multi_site_wordpress_audit "sitios.txt" "TU_API_TOKEN"Monitoreo Continuo
Section titled “Monitoreo Continuo”#!/bin/bash
wordpress_continuous_monitoring() { local url=$1 local api_token=$2 local baseline_file="baseline_$(echo $url | sed 's/https\?:\/\///g' | sed 's/\//_/g').json" local current_file="current_$(date +%Y%m%d_%H%M%S).json"
echo "[+] Monitoreo continuo de WordPress: $url"
# Generar escaneo actual if [ ! -z "$api_token" ]; then wpscan --url $url --api-token $api_token --enumerate ap,at,u -f json -o $current_file else wpscan --url $url --enumerate p,t,u -f json -o $current_file fi
if [ -f "$baseline_file" ]; then echo "[+] Comparando con baseline..."
# Comparar plugins baseline_plugins=$(jq -r '.plugins | keys[]' $baseline_file | sort) current_plugins=$(jq -r '.plugins | keys[]' $current_file | sort)
new_plugins=$(comm -13 <(echo "$baseline_plugins") <(echo "$current_plugins")) removed_plugins=$(comm -23 <(echo "$baseline_plugins") <(echo "$current_plugins"))
if [ ! -z "$new_plugins" ]; then echo "[!] NUEVOS PLUGINS DETECTADOS:" echo "$new_plugins" fi
if [ ! -z "$removed_plugins" ]; then echo "[!] PLUGINS REMOVIDOS:" echo "$removed_plugins" fi
# Comparar versión de WordPress baseline_version=$(jq -r '.version.number // "unknown"' $baseline_file) current_version=$(jq -r '.version.number // "unknown"' $current_file)
if [ "$baseline_version" != "$current_version" ]; then echo "[!] CAMBIO DE VERSIÓN WORDPRESS: $baseline_version -> $current_version" fi
# Actualizar baseline cp $current_file $baseline_file
else echo "[+] Creando baseline inicial..." cp $current_file $baseline_file fi}
# Ejecutar con cron cada 24 horas:# 0 2 * * * /path/to/wordpress_continuous_monitoring.sh https://ejemplo.com API_TOKENLimitaciones y Mejores Prácticas
Section titled “Limitaciones y Mejores Prácticas”Limitaciones de WPScan
Section titled “Limitaciones de WPScan”- Rate limiting: API gratuita limitada a 25 requests/día
- Detección pasiva: Puede no detectar todos los plugins/temas
- Falsos positivos: Especialmente en modo agresivo
- Sitios protegidos: WAF puede bloquear escaneos
Mejores Prácticas
Section titled “Mejores Prácticas”- Usar API token: Para mejores resultados y detección de vulnerabilidades
- Combinar modos: Pasivo para reconocimiento, agresivo para detalles
- Verificación manual: Confirmar hallazgos importantes
- Documentar todo: Mantener registros de auditorías
- Actualizar regularmente: Mantener WPScan y base de datos actualizados
Recursos Adicionales
Section titled “Recursos Adicionales”Herramientas Complementarias
Section titled “Herramientas Complementarias”- WP-CLI: Interfaz de línea de comandos oficial de WordPress
- WordPress Security Scanner: Herramientas online
- Nuclei: Templates específicos para WordPress
- CMSmap: Scanner multi-CMS
Bases de Datos de Vulnerabilidades
Section titled “Bases de Datos de Vulnerabilidades”Documentación Oficial
Section titled “Documentación Oficial”Disclaimer Legal
Section titled “Disclaimer Legal”⚠️ IMPORTANTE: Esta documentación es únicamente para fines educativos y de investigación en ciberseguridad. El uso de WPScan debe realizarse exclusivamente en:
- Sitios web propios
- Entornos de laboratorio
- Sitios con autorización explícita y por escrito
El uso no autorizado puede constituir un delito. Los autores no se hacen responsables del mal uso de esta información.