Pentest a WordPress on-prem con validación de impacto hasta root

El disparador: “algo raro está pasando”

El cliente (academia) dependía de su web para la captación de matrículas y estaba observando señales fuera de patrón:

  • Correos del formulario de contacto fuera de horario, con cadencias repetitivas.
  • Picos de tráfico hacia rutas que no eran cursos ni contenidos públicos.
  • Dudas razonables antes de una campaña de captación: “necesito saber si esto es serio”.

El matiz crítico apareció en la primera reunión: no era un WordPress en un hosting externo. Era WordPress en un servidor físico propio (on-prem). En ese modelo, un fallo web puede escalar a un problema de control del activo.

Qué se acordó (y por qué importa)

Antes de tocar el primer paquete, se cerró un marco de trabajo defendible:

  • NDA y SOW/contrato (alcance, entregables, ventanas y limitaciones).
  • Authorization to Test y Rules of Engagement (técnicas permitidas, límites, kill switch, contactos).
  • Anexo de alcance técnico (dominio(s) y endpoints WordPress).
  • RGPD/DPA si aparecían datos personales en formularios/logs.
  • Gestión de evidencias (cifrado, retención, borrado seguro).
  • Confirmación de backup y procedimiento de restauración.

Esto no es burocracia: reduce fricción, protege al cliente y convierte un “míralo un momento” en un trabajo auditable.

Alcance técnico (resumen)

En alcance:

  • Sitio WordPress publicado por HTTPS.
  • Endpoints típicos:
    • /wp-login.php, /wp-admin/
    • /wp-json/
    • /xmlrpc.php (si activo)
  • Core/tema/plugins detectables desde la superficie web.
  • Validación de impacto en host solo si derivaba del compromiso de WordPress.

Fuera de alcance:

  • Auditoría integral del servidor (hardening completo del SO y servicios no-web).
  • DoS, pruebas disruptivas, ingeniería social.

Cómo se atacó el problema (metodología práctica)

Trabajo orientado a superficie → hipótesis → validación de impacto:

  1. Reconocimiento pasivo
    • Huellas de WordPress, rutas, headers, metadatos y exposición evidente.
  2. Enumeración activa controlada
    • Endpoints, roles, señales de autenticación, plugins/temas observables, comportamiento ante abuso.
  3. Autenticación y control de acceso
    • Respuestas del login, enumeración indirecta de usuarios, mecanismos anti-fuerza bruta.
  4. Flujos sensibles
    • Formularios, adjuntos y cualquier funcionalidad con entrada de usuario o subida de ficheros.
  5. Compromiso controlado y prueba de impacto
    • Evidencia mínima de ejecución en host en el contexto del servicio web.
    • Si era posible, validación puntual del impacto máximo (escalada local) y parada inmediata.

La cadena de ataque (en una línea)

Superficie WordPress → vector inicial en un flujo expuesto → ejecución como usuario del servicio web → condición insegura del host → root (PoC).

El valor del caso no es “llegar a root”. Es demostrar que, en on-prem, el salto de web a servidor puede ser inmediato si el host no contiene el impacto.

Cronología operativa (resumen)

  • Día 1: kick-off, validación de alcance, baseline de exposición.
  • Día 2: enumeración y pruebas sobre autenticación + flujos sensibles.
  • Día 3: compromiso controlado, evidencia de ejecución, validación de impacto y comunicación crítica.
  • Día 4: clasificación de hallazgos, priorización, plan por fases y cierre.

Hallazgos (resumen)

ID Severidad Hallazgo Impacto
B-01 Alta Compromiso de WordPress con ejecución en host Control de aplicación y punto de apoyo en servidor
B-02 Crítica Escalada local a root tras compromiso web Control total del servidor
B-03 Media Señales de enumeración de usuarios Facilita ataques dirigidos
B-04 Media Rate-limit/bloqueo insuficiente en autenticación Incrementa riesgo de toma de cuentas

B-01 — Compromiso de WordPress con ejecución en el host (Alta)

Qué demostré

Que un flujo expuesto en WordPress permitía pasar de interacción HTTP a capacidad de ejecución en el servidor bajo el usuario del servicio web.

Evidencia (mínima)

  • Confirmación del contexto de ejecución (usuario/grupos).
  • Acceso limitado a rutas del proyecto WordPress y lectura puntual de configuración de la aplicación (sin extracción masiva).

Impacto real

Manipulación del sitio (integridad) y posibilidad de persistencia a nivel aplicación. Acceso a datos tratados por WordPress (formularios/adjuntos/usuarios). Base operativa para escalada local y potencial pivot si existe conectividad interna.

Causa raíz (alto nivel)

Componente/funcionalidad expuesta con controles insuficientes (validación, permisos, configuración o mantenimiento).

Remediación efectiva

Actualizar/retirar el componente afectado y reducir plugins a lo imprescindible. Revisar permisos del filesystem, especialmente wp-content/. Endurecer el tratamiento de subidas y deshabilitar ejecución donde no aplique. Monitorización de integridad (core/tema/plugins) y alertas ante cambios.

B-02 — Escalada local a root tras compromiso de WordPress (Crítica)

Qué demostré

Partiendo de ejecución como usuario del servicio web, fue posible alcanzar root mediante una condición insegura del host. La escalada se ejecutó como PoC, sin persistencia, sin acciones destructivas y con parada inmediata.

Evidencia (mínima)

  • Confirmación de privilegios elevados en el punto de control.
  • Identificación de la condición habilitante a nivel de permisos/configuración.

    Impacto real

  • Acceso total a ficheros, base de datos, credenciales y configuración.
  • Capacidad de manipular servicios, logs y controles de seguridad.
  • Riesgo de movimiento lateral si el servidor comparte red con otros activos.

    Causa raíz (alto nivel)

    Falta de contención del impacto en host: permisos o configuración que hacen viable que un usuario de servicio termine ejecutando con privilegios elevados.

    Remediación prioritaria

  • Eliminar la condición de escalada (según aplique: sudoers, SUID, tareas programadas, scripts con permisos indebidos, grupos privilegiados).
  • Mínimo privilegio real para el usuario del servicio web.
  • Aislamiento del servicio (separación de roles, segmentación, contención por proceso).

B-03 — Señales de enumeración de usuarios (Media)

Qué demostré

Respuestas/metadata que permiten inferir usuarios válidos y reducir el coste del ataque.

Remediación

  • Homogeneizar mensajes de error y evitar filtrados por comportamiento.
  • Revisar exposición de REST si no aporta valor.
  • MFA obligatorio para cuentas privilegiadas y políticas de contraseñas coherentes con riesgo.

B-04 — Controles insuficientes ante intentos de autenticación (Media)

Qué demostré

Ausencia o debilidad de rate-limit/bloqueo en rutas de autenticación (incluyendo endpoints alternativos si existen).

Remediación

  • Rate-limit con backoff y bloqueo progresivo.
  • MFA + allowlist administrativa cuando sea viable (VPN/IPs estáticas).
  • Deshabilitar/proteger XML-RPC si no es necesario.

Plan de remediación (por fases)

Fase 0 — Contención inmediata

  • Cerrar el vector inicial en WordPress (actualización/retirada y revisión del flujo afectado).
  • Eliminar la condición de escalada a root.
  • MFA para administradores y editores.
  • Retirar ficheros de backup/artefactos peligrosos accesibles.

Fase 1 — Endurecimiento a corto plazo

  • Permisos correctos y política estricta sobre subidas.
  • Reducción de superficie: endpoints no usados, paneles y rutas innecesarias.
  • Protección de login (rate-limit, WAF/reglas, alertas).

Fase 2 — Diseño para que el impacto no escale

  • Aislamiento del servicio: segmentación y separación de funciones.
  • Logging y retención con señales accionables.
  • Mantenimiento: inventario de plugins, ventanas de actualización, revisión periódica de exposición.

Entregables

  • Documento de alcance, reglas y limitaciones.
  • Inventario de superficie observada (endpoints y componentes).
  • Evidencias reproducibles por hallazgo (mínimas y seleccionadas).
  • Matriz de riesgos y priorización (negocio + técnico).
  • Plan de remediación por fases con acciones concretas.

Lección central del caso

En despliegues on-prem, “WordPress comprometido” no es un incidente web: puede ser control del servidor si el host no contiene el impacto. La medida estructural no es solo “actualizar plugins”, es diseñar para que un fallo web no pueda terminar en root.