Versión ampliada y actualizada de este tema: ¿Cómo limpiar un sitio WordPress hackeado? Guía práctica de eliminación de malware (2026).
“Este sitio puede estar comprometido” o “Sitio engañoso adelante”.
Ver aparecer la temida pantalla roja de Google Safe Browsing o recibir una notificación de suspensión urgente por parte del proveedor de alojamiento es una situación crítica para cualquier propietario de un sitio web. Una intrusión en WordPress no constituye solo un problema de reputación; pone en riesgo la privacidad de los datos de tus clientes, anula el posicionamiento orgánico mediante páginas trampa de spam y puede conllevar el bloqueo permanente de tu infraestructura en los registros de seguridad internacionales.
La gran mayoría de los ataques que sufre WordPress están totalmente automatizados. Como señala la documentación oficial de endurecimiento de WordPress, las redes de bots rastrean la red de manera ininterrumpida buscando extensiones desactualizadas, contraseñas débiles o fallos en temas. No se trata de un ataque personalizado contra tu marca; son procesos masivos que buscan servidores vulnerables para utilizarlos como repetidores de spam, nodos de ataque o granjas de enlaces ilícitos.
En este manual explicamos el procedimiento técnico profesional para desinfectar un WordPress comprometido. Olvídate de recurrir a plugins milagrosos que se limitan a ocultar los síntomas sin erradicar las puertas traseras. La solución definitiva exige rigor a nivel de servidor utilizando terminal SSH, WP-CLI y consultas directas en la base de datos.
Si el síntoma principal detectado consiste en la aparición masiva de resultados en idiomas asiáticos en los índices de búsqueda, te recomendamos revisar primero nuestra guía sobre el hack japonés de palabras clave antes de proceder con el borrado.
Síntomas de un sitio vulnerado y primeros pasos de triaje
Una intrusión se manifiesta a través de diversos indicadores de compromiso (IoC), descritos exhaustivamente en la documentación de FAQ: Mi sitio fue hackeado:
- Los motores de búsqueda como Google o Bing incluyen tu dominio en listas públicas de sitios dañinos.
- La empresa de alojamiento web suspende la cuenta por consumo anómalo de recursos o envío masivo de spam.
- Los navegadores o programas antivirus bloquean la entrada a los usuarios.
- Aparecen cuentas de administración no autorizadas en el panel de control.
- Se producen redirecciones automáticas imprevistas hacia portales fraudulentos o de apuestas.
- El sitio muestra alteraciones visuales notorias, elementos rotos o ventanas emergentes desconocidas.
El primer paso obligado consiste en documentar la situación con precisión. Antes de alterar o borrar cualquier fichero, toma nota detallada de lo que observas: fecha y hora exacta con huso horario, cambios recientes en el sitio (nuevos plugins, ajustes de plantilla, edición de widgets) y características técnicas del alojamiento (versión de PHP, tipo de servidor web, usuarios con acceso SSH). Esta memoria servirá como base forense y ahorrará horas de trabajo tanto a tu equipo como a los profesionales que intervengan.
Asimismo, es imprescindible ejecutar dos comprobaciones previas. En primer lugar, escanea tu propio ordenador de trabajo con herramientas de seguridad: un troyano local capaz de registrar pulsaciones de teclado o sustraer credenciales de FTP y /wp-admin invalidará cualquier limpieza que realices en el servidor. En segundo lugar, ponte en contacto con tu proveedor de alojamiento. En entornos compartidos, una infección puede propagarse entre cuentas vecinas, y una web que emite spam puede provocar que la dirección IP del servidor sea incluida en listas negras de correo.
Copia de seguridad de respaldo antes de iniciar la limpieza
Antes de realizar modificaciones, es prioritario generar una copia de seguridad íntegra del estado infectado actual. Si durante la desinfección eliminas por error un archivo legítimo modificado (por ejemplo, un functions.php que contenía código a medida imprescindible para tu negocio), necesitarás disponer del archivo original para recuperar dicha funcionalidad de manera limpia.
Accede mediante SSH al directorio raíz de la instalación y ejecuta:
# Empaquetar todo el sistema de archivos en un archivo comprimido
tar -czf backup-archivos-infectados_$(date +%F).tar.gz .
# Exportar un volcado íntegro de la base de datos
wp db export backup-bd-infectada_$(date +%F).sql --allow-rootDescarga estas copias a tu equipo o muévelas a un almacenamiento aislado fuera del servidor para su análisis forense.
Cómo buscar firmas de malware mediante grep
Los creadores de malware ocultan sus scripts tras funciones de ofuscación dinámica como eval(), base64_decode() y gzinflate(). Las directrices de seguridad de Google aconsejan rastrear expresamente estas llamadas junto a unescape() para localizar código malicioso incrustado.
Ejecuta desde la raíz de tu proyecto las siguientes búsquedas con grep:
Patrones y cadenas sospechosas más comunes
Búsqueda de llamadas a
eval()(prácticamente nunca utilizada en código web moderno y limpio):grep -rl --include=*.php 'eval(' .Búsqueda de scripts incrustados e iframes ocultos en archivos PHP:
grep -rl --include=*.php '<script' . grep -rl --include=*.php '<iframe' .Búsqueda de cadenas codificadas u ofuscadas en Base64 y Rot13:
grep -rl --include=*.php 'base64_decode' . grep -rl --include=*.php 'str_rot13' . grep -rl --include=*.php 'gzinflate' .Búsqueda de decodificaciones de JavaScript mediante
unescape:grep -rl --include=*.js 'unescape(' .
No añadas el parámetro -w a estas búsquedas. Dicha opción exige límites estrictos de palabra, lo que provocaría que patrones frecuentes como eval(base64_decode( quedaran fuera del rastreo.
Cómo diferenciar falsas alarmas de código malicioso real
No todas las coincidencias corresponden a virus:
- Determinados constructores visuales o librerías complejas pueden emplear
base64_decodepara transferir configuraciones serializadas o iconos en formato SVG. - Presta máxima atención a scripts PHP en ubicaciones inapropiadas. Bajo la estructura habitual de WordPress, la carpeta
/wp-content/uploads/jamás debe albergar ficheros PHP ejecutables.
Para listar todos los scripts ejecutables en la carpeta de subidas:
find ./wp-content/uploads -name "*.php"Cualquier archivo localizado en esta carpeta debe considerarse sospechoso y potencialmente lesivo de inmediato. Las extensiones legítimas almacenan documentos, imágenes y elementos multimedia, nunca código ejecutable en el servidor.
Inspección del sitio simulando el rastreo de Googlebot
Muchos ataques avanzados aplican técnicas de cloaking: muestran una página perfectamente normal a las visitas directas del administrador, pero inyectan enlaces fraudulentos y redirecciones maliciosas únicamente cuando la visita procede de Googlebot o de un buscador web.
Las recomendaciones de seguridad desaconsejan abrir el sitio infectado directamente desde el navegador habitual para evitar posibles exploits dirigidos a clientes. En su lugar, emplea curl desde la consola para simular la llegada de un rastreador:
curl -sv --referer "https://www.google.com/" \
--user-agent "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://tu-dominio.com/ -o rastreo-simulado.html
grep -iE 'eval|base64_decode|unescape|<iframe' rastreo-simulado.htmlRepite la petición sin el parámetro referer y compara el resultado. Si recibes un código de estado 301 o 302 únicamente al incluir la procedencia de Google, el servidor tiene activas reglas de redirección maliciosa en .htaccess o en las primeras etapas de ejecución de PHP.
Sustitución limpia de los archivos del núcleo mediante WP-CLI
Tratar de desinfectar manualmente cada archivo del núcleo en wp-admin y wp-includes es una tarea ineficaz y propensa a descuidos. El método más fiable y expedito consiste en reemplazar todos los archivos originales del sistema por copias oficiales e impolutas.
La documentación oficial exige reinstalar con precisión la misma versión que tiene instalada el sitio para evitar fallos de incompatibilidad. Mediante WP-CLI podemos forzar la descarga asegurando la protección del contenido de usuario:
# Descarga limpia de los archivos de la misma versión ignorando wp-content
wp core download --version=$(wp core version --allow-root) --force --skip-content --allow-rootEl parámetro --skip-content resulta determinante: garantiza que la carpeta /wp-content/, donde residen tus archivos multimedia, temas y plugins, se conserve intacta.
Conviene tener presente una limitación técnica: este comando sobrescribe los archivos existentes, pero no borra ficheros maliciosos nuevos que hayan sido añadidos en carpetas del núcleo. Un script extraño como wp-includes/class-auxiliar.php persistirá tras la descarga. Para descubrir estos archivos añadidos, es indispensable ejecutar la verificación de sumas de comprobación.
Si no dispones de WP-CLI en tu alojamiento:
- Descarga el paquete oficial de la misma versión desde WordPress.org.
- Descomprímelo en tu ordenador local.
- Elimina del paquete la carpeta
wp-contenty el ficherowp-config-sample.php. - En el servidor, borra por completo las carpetas
wp-adminywp-includes, sube las copias limpias por SFTP y sobrescribe los archivos de la raíz.
Verificación de sumas de comprobación en núcleo y plugins
WP-CLI incorpora utilidades nativas para contrastar los archivos de tu servidor contra los hashes MD5 oficiales publicados en WordPress.org. El comando wp core verify-checksums se ejecuta en el gancho before_wp_load, lo que permite examinar la instalación sin necesidad de ejecutar código potencialmente infectado:
wp core verify-checksums --allow-rootSi el núcleo está completamente limpio, el resultado confirmará la integridad:
Success: WordPress installation verifies against checksums.Si algún archivo ha sido alterado o se han incrustado ficheros lesivos, el diagnóstico alertará de forma individualizada:
Warning: File doesn't verify against checksum: wp-includes/version.php
Warning: File should not exist: wp-includes/fichero-agregado.php
Error: WordPress installation doesn't verify against checksums.El aviso “File should not exist” es la señal inequívoca de una puerta trasera. El parámetro --include-root amplía el análisis a la raíz del sitio (excluyendo ficheros habituales como .htaccess o wp-config.php). En instalaciones localizadas en español u otros idiomas, añade la bandera de idioma (como --locale=es_ES) para evitar que los archivos de traducción se señalen como discrepancias.
Para las extensiones existe la orden complementaria wp plugin verify-checksums:
wp plugin verify-checksums --all --allow-rootEsta orden coteja cada plugin contra los repositorios oficiales, notificando ficheros alterados o agregados ilegítimamente. Los plugins de pago o personalizados no figuran en este registro y emitirán un aviso de omisión, por lo que su integridad debe verificarse sustituyendo los archivos con los paquetes originales del fabricante.
Limpieza de archivos maliciosos en la carpeta wp-content
La carpeta /wp-content/ es el destino habitual donde los atacantes depositan sus cargas activas.
Desinfección de temas y extensiones
Para cualquier plugin gratuito descargado desde el directorio de WordPress.org, la mejor práctica radica en reinstalarlo íntegramente:
# Reinstalación forzada limpia de un plugin
wp plugin install contact-form-7 --force --allow-rootEn el caso de plugins de pago, descarga los archivos oficiales del desarrollador y sobrescríbelos mediante SFTP.
Revisa concienzudamente tu plantilla. Si empleas un tema hijo, audita de forma manual archivos como functions.php, header.php, footer.php e index.php. Los atacantes acostumbran a añadir funciones ofuscadas al inicio o al pie de estas plantillas para asegurar su ejecución constante.
Eliminación de scripts ejecutables en la carpeta uploads
Puesto que el directorio de subidas solo debe albergar archivos multimedia y documentos estáticos, podemos eliminar de manera sistemática cualquier script PHP presente en su interior:
# Revisar primero los ficheros detectados
find ./wp-content/uploads -name "*.php"
# Tras confirmar la lista, proceder a su eliminación definitiva
find ./wp-content/uploads -name "*.php" -deleteComprueba siempre el listado antes de ejecutar el borrado con -delete para verificar que no haya archivos de configuración de utilidades de caché legítimas mal ubicados.
Limpieza de la base de datos ante inyecciones de spam y falsos administradores
El malware con frecuencia extiende sus tentáculos a las tablas de la base de datos:
Usuarios administradores ilegítimos: Entra en phpMyAdmin o ejecuta la consola de base de datos para consultar:
SELECT * FROM wp_users;Localiza usuarios que no reconozcas, especialmente aquellos asociados a dominios sospechosos o con cadenas de caracteres aleatorias, y elimínalos de inmediato.
Spam inyectado en el contenido: Los ataques orientados al posicionamiento ilícito generan cientos de entradas trampa con caracteres asiáticos o anuncios de medicamentos. Busca patrones en la tabla
wp_posts:SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%'; SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%eval(%';
Si la instalación ha sufrido una inyección masiva de entradas de spam, es necesario depurar dichos registros en la base de datos y enviar posteriormente el mapa del sitio actualizado a Google Search Console para forzar su desindexación.
Auditoría de administradores con wp user list
Una consulta simple a wp_users muestra cuentas, pero no refleja con claridad sus roles reales, que se almacenan en wp_usermeta. El comando wp user list cruza ambas tablas y filtra específicamente por privilegios de administración:
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-rootCompara los resultados con los accesos autorizados. La fecha de registro reflejada en user_registered permite vincular una cuenta espuria con el momento en que se produjo la brecha inicial. En redes multisitio, conviene comprobar también los superadministradores:
wp super-admin list --allow-rootEn caso de que el atacante haya tomado el control de tu cuenta principal y no puedas iniciar sesión, accede a la base de datos, actualiza el correo en wp_users por una dirección que controles y utiliza el enlace de recuperación de contraseña de la pantalla de acceso.
Revisión de los archivos de configuración wp-config.php y htaccess
Ambos archivos de configuración son objeto recurrente de manipulación por parte de los intrusos:
wp-config.php: Inspecciona su contenido línea por línea. Es habitual encontrar inclusiones de archivos temporales que actúan como cargadores:
include '/tmp/sess_f3a987...'; // CARGADOR MALICIOSO SOSPECHOSOCoteja el contenido contra
wp-config-sample.php. Solo debe contener datos de conexión a la base de datos, claves secretas y constantes indispensables..htaccess: Los atacantes introducen directivas de reescritura para desviar las visitas procedentes de buscadores. Si observas líneas desconocidas, restituye la configuración estándar de WordPress:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
Revisa si existen archivos .htaccess adicionales ocultos en otros directorios:
find . -name ".htaccess"Medidas inmediatas de seguridad tras eliminar la infección
Una vez erradicado el código malicioso de archivos y tablas, es momento de sellar todos los accesos:
Renovación total de contraseñas:
- Cambia las contraseñas de todos los perfiles de usuario.
- Modifica la contraseña del usuario de base de datos y actualízala en
wp-config.php. - Renueva los accesos de SFTP, SSH y del panel del alojamiento.
Regeneración de las claves secretas (Salts): Cambiar los Salt Keys invalida al instante todas las sesiones activas en cualquier navegador:
wp config shuffle-saltsInhabilitación de la edición de archivos desde el panel: Añade en
wp-config.php:define( 'DISALLOW_FILE_EDIT', true );Esta directiva impide que un intruso que consiga acceso al panel pueda editar archivos PHP de temas o extensiones.
Restricción de XML-RPC: Si no empleas aplicaciones móviles de WordPress o Jetpack, desactiva XML-RPC para anular vectores de fuerza bruta. En Apache 2.4, añade a
.htaccess:<Files xmlrpc.php> Require all denied </Files>
Permisos de archivos y usuarios de base de datos tras la limpieza
La guía oficial de endurecimiento fija permisos estándar: directorios en 755 y archivos en 644, con propiedad del usuario asignado al alojamiento web:
find /ruta/a/wordpress/ -type d -exec chmod 755 {} \;
find /ruta/a/wordpress/ -type f -exec chmod 644 {} \;El archivo wp-config.php debe restringirse a permisos 400 o 440 para que solo resulte legible por el propietario y el servidor web.
El usuario de la base de datos debe disponer en su operativa habitual únicamente de permisos de manipulación de datos (SELECT, INSERT, UPDATE, DELETE). Si en el mismo servidor conviven varios sitios, asegúrate de que cada uno disponga de su propia base de datos y usuario exclusivo, evitando que una brecha en una web permita el acceso lateral a los demás proyectos.
Por último, examina los registros de acceso del servidor web. Estos registros permiten determinar la vía exacta de entrada empleada por el atacante, evidenciando las direcciones IP y las llamadas efectuadas en el momento de la intrusión.
Comprobación periódica para certificar la desinfección total
La desinfección solo se considera definitiva cuando el sitio supera de forma continuada las mismas pruebas durante los días posteriores. Repite periódicamente los rastreos con grep, ejecuta find ./wp-content/uploads -name "*.php" y valida las sumas con wp core verify-checksums.
Audita de nuevo los usuarios administradores para comprobar que no se registren cuentas imprevistas. Si alguna comprobación falla o el malware reaparece, no te limites a repetir la limpieza: debes localizar la vulnerabilidad de origen (un plugin vulnerable, un tema descargado de fuentes no oficiales o un acceso comprometido) y cerrarla antes de volver a sanear los archivos.
Informe de seguridad y solicitud de revisión en Google Search Console
Si Google incluyó tu sitio en sus listas de advertencia, el aviso permanecerá visible hasta que se complete una verificación formal. El Informe de problemas de seguridad en Search Console constituye el panel de referencia oficial.
En dicho informe se detallan las incidencias detectadas (contenido pirateado, malware o ingeniería social) junto con URLs de muestra. Es indispensable solucionar el problema en la totalidad del portal web antes de solicitar la revisión.
Una vez reparadas todas las incidencias, pulsa en el botón de Solicitar revisión. Una solicitud efectiva debe incluir:
- Una explicación clara sobre el origen del fallo detectado.
- La relación de medidas correctoras implementadas en archivos, base de datos y servidor.
- Las pruebas y verificaciones técnicas que demuestran que el sitio se encuentra limpio.
El proceso de revisión puede demorarse entre unos días y un par de semanas. Evita enviar solicitudes reiteradas mientras esté pendiente la evaluación para no retrasar el dictamen final.
Conclusión técnica para mantener un sitio seguro
Erradicar el software malicioso exige constancia y disciplina técnica. La mejor defensa a largo plazo no radica en comprar complementos complejos, sino en mantener una higiene técnica rigurosa:
- Aplicar de inmediato las actualizaciones del núcleo, plugins y temas.
- Rechazar de forma categórica el uso de extensiones piratas (“nulled”), origen habitual de puertas traseras.
- Disponer de copias de seguridad externas y contrastadas de forma periódica.
Si el procedimiento técnico resulta complejo o los ataques persisten, lo más prudente es recurrir a especialistas en la materia. Una desinfección incompleta deja puertas traseras ocultas que permiten a los atacantes recuperar el control en pocos días.
Consulta nuestro servicio de auditoría de seguridad en WordPress para evaluar los riesgos de tu portal y proteger tu infraestructura digital de manera definitiva.







