
Detectar y limpiar el compromiso de WordPress por wp2shell (CVE-2026-63030) — ejecutable en lote, solo lectura por defecto
Detectar y limpiar el compromiso wp2shell (CVE‑2026‑63030) en uno o varios sitios WordPress.
wp2shell es la vulnerabilidad de ejecución remota de código sin autenticación previa corregida en WordPress 7.0.2 / 6.9.5 / 6.8.6 (2026‑07‑17). Apareció un PoC público en un día y la explotación masiva llegó en ~48 horas. Aplicar el parche cierra el agujero, pero un sitio explotado antes de parchearse ya está comprometido, y actualizar no elimina la persistencia del atacante.
Esta herramienta encuentra y elimina esa persistencia. Es un único script Bash con pocas dependencias que se ejecuta solo lectura por defecto y puede escanear miles de sitios en una sola pasada.
⚠️ Es una herramienta defensiva. No contiene código de explotación. Haz una instantánea (snapshot) de un sitio antes de ejecutar
--clean.
Tras la explotación, las herramientas wp2shell suelen dejar dos artefactos de persistencia, ambos detectados por esta herramienta:
user_login = wpsvc_<hex> / wp2_<hex> / w2s_<hex>, o un correo electrónico en un dominio del atacante (@wp2shell.*, @shellcode.*, @wordpress-svc.internal, @wordpress-noreply.net, @x.lol), con el rol administrator. (Nota: @system.local es un legítimo correo de administrador de relleno en algunos hosts gestionados — deliberadamente no se trata como IOC.)wp-content/plugins/<nombre-plausible>-<6hex>/<mismo>.php: un archivo PHP muy pequeño (~1.3 KB) con un falso encabezado Author: WordPress.org Community, protegido por un token, que expone una interfaz ?c=<comando>.También detecta el caso genérico: cualquier archivo PHP pequeño bajo wp-content/ que canalice $_GET['c'] a un sumidero de comando/evaluación.
curl -fsSLO https://raw.githubusercontent.com/InstaWP/wp2shell-scan/main/wp2shell-scan.sh
chmod +x wp2shell-scan.sh
Requiere bash, find, grep y un cliente mysql/mariadb. WP‑CLI se usa cuando está presente (para una eliminación de usuario más limpia) pero no es obligatorio — la detección de webshell no necesita base de datos en absoluto.
# Escanear UN sitio (solo lectura)
./wp2shell-scan.sh --path /var/www/ejemplo.com
# Escanear CADA instalación de WordPress bajo un directorio base (masivo)
./wp2shell-scan.sh --base /var/www
./wp2shell-scan.sh --base /home # hosting compartido
# Detección automática de diseños comunes (/var/www/*, /home/*/public_html, ...)
./wp2shell-scan.sh
# Formato legible por máquina
./wp2shell-scan.sh --base /var/www --json > report.json
# LIMPIEZA — poner en cuarentena + eliminar puertas traseras, rotar sales de wp-config (desconecta a todos)
./wp2shell-scan.sh --base /var/www --clean --yes
# Examinar un volcado de RESPALDO / INSTANTÁNEA / PLANTILLA antes de restaurarlo (ver advertencia abajo)
./wp2shell-scan.sh --sql /ruta/al/respaldo.sql
Los artefactos eliminados se mueven a un directorio de cuarentena (no se borran directamente) para conservar pruebas. El código de salida es 1 cuando se encuentra compromiso (scan) o se limpia (clean), 0 cuando está limpio — útil para cron/CI.
[COMPROMISED] /var/www/ejemplo.com — 2 administrador(es) puerta trasera, 2 webshell(s)
admin: ID=41 wpsvc_2e1487df8abb <[email protected]> (2026-07-19 06:41:48)
webshell: .../wp-content/plugins/security-headers-manager-8d1d21/security-headers-manager-8d1d21.php
[clean] /var/www/otro-sitio.com
----------------------------------------------------------------
scanned=812 clean=811 compromised=1 cleaned=0
Limpiar un sitio en vivo NO limpia tus respaldos. Una copia de seguridad, instantánea o plantilla de preparación/blueprint capturada mientras el sitio estaba comprometido todavía contiene la cuenta de administrador del atacante — restaurarla (o aprovisionar un nuevo sitio a partir de ella) reinfecta al instante. Lo aprendimos por las malas: después de limpiar todos los sitios en vivo afectados, seguían apareciendo sitios nuevos con la puerta trasera porque se aprovisionaban desde una instantánea de plantilla envenenada.
Examina un volcado antes de restaurarlo:
./wp2shell-scan.sh --sql /ruta/al/respaldo.sql
./wp2shell-scan.sh --sql respaldo1.sql --sql respaldo2.sql.gz # repetible, compatible con .gz
El código de salida es 1 si algún volcado está envenenado. Si lo está: no lo restaures — limpia primero el sitio en vivo, luego haz una copia de seguridad fresca y elimina/reemplaza cualquier instantánea o plantilla creada durante tu ventana de exposición.
--clean elimina el administrador y el webshell y rota las sales. Aún debes:
wp core verify-checksums).?c=./wp-json/batch/v1, ?rest_route=/batch/v1, incluyendo codificación %2f). Ponlo en el origen si un CDN pudiera pasar la ruta REST.Administradores fraudulentos:
SELECT u.ID,u.user_login,u.user_email,u.user_registered
FROM wp_users u JOIN wp_usermeta m ON u.ID=m.user_id
WHERE m.meta_key='wp_capabilities' AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;
Plugins webshell:
find wp-content/plugins -maxdepth 1 -type d -regextype posix-extended -regex '.*-[0-9a-f]{6}$'
grep -rl "\$_GET\['c'\]" wp-content/plugins/
Consulta CLEANUP-WITH-CLAUDE.md para un prompt listo para copiar y pegar que guía a Claude Code (o cualquier agente de codificación capaz) a través de la misma detección y limpieza en un solo sitio, con confirmación humana antes de cada paso destructivo.
MIT — ver LICENSE. Se proporciona tal cual, sin garantía. Construido y probado en batalla durante un incidente real por el equipo de InstaWP.