Etiqueta: wordpress-security

  • Base de datos corrupta tras ataque: recuperación segura de wp_users y wp_options

    Base de datos corrupta tras ataque: recuperación segura de wp_users y wp_options

    Base de datos corrupta tras ataque: cómo recuperar wp_users y wp_options sin perder datos

    Cuando analizo un sitio WordPress comprometido, una de las situaciones más críticas que encuentro es la corrupción de la base de datos. No es solo un problema técnico: es la puerta de entrada a perder acceso administrativo, credenciales de usuarios y configuraciones vitales. En mi experiencia, la mayoría de empresas no tienen plan de recuperación y pierden horas valiosas intentando restaurar sin método.

    La corrupción de wp_users y wp_options suele ser consecuencia directa de ataques de inyección SQL, backdoors mal desinstalados o intentos de fuerza bruta que generan inconsistencias en la integridad de datos. Te voy a enseñar cómo actuar cuando te encuentres con este escenario, desde el diagnóstico inicial hasta la recuperación segura.

    ¿Por qué se corrompen wp_users y wp_options en un ataque?

    Las tablas wp_users y wp_options son el corazón de cualquier instalación WordPress. La primera almacena credenciales, roles y metadatos de usuarios; la segunda guarda configuraciones críticas como URLs, claves de seguridad y datos de plugins. Cuando un atacante ejecuta inyección SQL mal codificada o deja un backdoor que manipula datos, estas tablas son frecuentemente el objetivo.

    Lo que veo en mis auditorías es que muchas veces el daño es parcial: registros huérfanos, caracteres corruptos en campos, relaciones rotas entre tablas. Esto genera errores como el famoso «error estableciendo conexión a la base de datos» o loops de redirección infinita.

    Vectores de ataque comunes contra la base de datos

    • Inyección SQL en plugins desactualizados: Un plugin vulnerable permite al atacante ejecutar consultas arbitrarias que modifican o borran registros.
    • Backdoors que inyectan código: Scripts maliciosos que se ejecutan en cada carga de página y manipulan wp_options para insertar datos maliciosos.
    • Explotación de credenciales débiles: Acceso directo al servidor de BD mediante phpMyAdmin sin protección o credenciales por defecto.
    • Corrupción por falta de espacio en disco: Cuando el servidor se queda sin almacenamiento, MySQL no puede escribir correctamente y genera inconsistencias.
    • Desactivación incorrecta de plugins: Código malicioso que borra datos antes de ser eliminado.

    Diagnóstico inicial: cómo saber si tu base de datos está realmente corrupta

    Antes de empezar a tocar nada, necesito que confirmes el estado real de la BD. Los síntomas pueden engañar. He visto casos donde el usuario creía que tenía corrupción cuando era simplemente un plugin activo malicioso.

    Paso 1: Accede a phpMyAdmin o a la línea de comandos

    Si tienes acceso al hosting, ingresa en phpMyAdmin (generalmente en tudominio.com/phpmyadmin). Si prefieres terminal SSH:

    mysql -u tu_usuario -p tu_base_datos

    Introduce tu contraseña cuando te lo pida.

    Paso 2: Ejecuta una búsqueda de integridad

    En la consola MySQL, ejecuta:

    CHECK TABLE wp_users, wp_options, wp_usermeta;

    WordPress depende también de wp_usermeta para metadatos de usuario. Si el resultado es «OK» en las tres, la corrupción física no es grave. Si ves «error» o «warning», estamos hablando de corrupción real.

    Paso 3: Verifica los datos visibles

    En phpMyAdmin, abre la pestaña «Explorar» de wp_users y wp_options. Busca:

    • Caracteres extraños o símbolos rotos en campos de usuario o configuración.
    • Registros duplicados o valores NULL inesperados.
    • Opciones con claves que no reconoces (típico de malware: «malicious_option», «backdoor_settings»).

    Te recomiendo hacer capturas de pantalla antes de cualquier modificación. Es tu evidencia de incidente.

    Recuperación segura de wp_users sin perder acceso administrativo

    La prioridad número uno es restaurar acceso administrativo legítimo. Si pierdes esto, quedarás bloqueado fuera de tu propio sitio.

    Opción A: Restaurar desde backup limpio (la mejor)

    Si tienes un backup de antes del ataque, este es tu camino. No intentes parches. Restaura desde cero:

    1. Descarga el backup completo de la BD desde tu panel de hosting o servicio de respaldo (Backwpup, UpdraftPlus, etc.).
    2. Crea un usuario temporal en la BD actual para tener acceso de prueba.
    3. Importa el backup en un entorno de prueba (staging) para verificar que funciona.
    4. Una vez confirmado, restaura en producción.
    5. Cambia todas las contraseñas de acceso FTP, MySQL y WordPress.
    6. Audita plugins y temas para identificar qué fue explotado.

    Cuando no tengo backup disponible, que es lamentablemente común, paso a la opción B.

    Opción B: Reparación de integridad con herramientas WordPress

    Si la corrupción es parcial y tienes acceso al panel, usa plugins de reparación de BD certificados. Pero déjame ser claro: esto no es una solución definitiva.

    En línea de comandos SSH, si tienes acceso:

    wp db repair –allow-root

    Este comando de WP-CLI intenta reparar inconsistencias. Luego:

    wp db optimize –allow-root

    Optimiza el espacio ocupado después de la reparación.

    Opción C: Extrae usuarios válidos y reconstruye wp_users

    Este es el método más controlado cuando la corrupción es severa. Lo que hago es:

    1. Exporta los datos válidos: En phpMyAdmin, ve a wp_users, selecciona los registros de usuario legítimos (normalmente puedes identificarlos por email corporativo o antigüedad), y exporta como SQL.

    2. Valida el SQL: Abre el archivo en un editor de texto. Busca caracteres rotos o líneas incompletas. Algunos editores como Sublime Text te muestran encoding issues.

    3. Crea una tabla temporal limpia: En la consola MySQL:

    CREATE TABLE wp_users_backup AS SELECT * FROM wp_users;

    TRUNCATE TABLE wp_users;

    Esto respalda los datos y vacía la tabla original.

    4. Reconstruye la estructura: Elimina wp_users y crea desde zero con la definición original. Luego importa solo los registros válidos.

    La clave aquí es que estás limpiando malware mientras preservas identidades de usuario legítimas.

    Recuperación de wp_options: eliminar opciones maliciosas sin romper el sitio

    Esta tabla es donde viven los backdoors. Un atacante suele insertar opciones como «fake_admin_user», «redirect_urls», «malware_config». Si las eliminas mal, el sitio revienta.

    Identifica opciones maliciosas de forma segura

    En phpMyAdmin, ordena wp_options por «option_id» descendente. Las opciones insertadas recientemente (IDs altos) suelen ser sospechosas. Busca en particular:

    • option_name con palabras clave: «shell», «backdoor», «remote», «exec», «bot», «spam», «redirects».
    • option_value que contenga código PHP serializado sospechoso o URLs externas.
    • Opciones de plugins desinstalados que aún existen en la BD.

    Cuando hago auditorías, uso una búsqueda como:

    SELECT * FROM wp_options WHERE option_name LIKE ‘%shell%’ OR option_name LIKE ‘%backdoor%’ OR option_name LIKE ‘%redirect%’;

    Esto te lista los sospechosos directos.

    Opciones críticas que NUNCA debes tocar

    Incluso si parecen extrañas, estas opciones son vitales:

    • siteurl y home: URLs del sitio.
    • blogname, blogdescription: Título y descripción.
    • users_can_register, default_role: Configuración de usuarios.
    • db_version: Versión de base de datos de WordPress.
    • Cualquier opción que comience con un nombre de plugin instalado.

    Mi regla: si no sabes para qué es, no la toques sin buscar primero en la documentación oficial de WordPress.

    Procedimiento de limpieza de wp_options

    Paso 1: Haz un backup de la tabla completa antes de empezar.

    mysqldump -u tu_usuario -p tu_base_datos wp_options > wp_options_backup.sql

    Paso 2: Identifica cada opción maliciosa individualmente y crea una lista.

    Paso 3: Elimina una opción a la vez y verifica que el sitio siga funcionando:

    DELETE FROM wp_options WHERE option_name = ‘nombre_sospechoso’;

    Paso 4: Después de cada eliminación, accede al front-end de tu sitio y al admin. Si algo revienta, restaura desde el backup de opciones.

    Es lento, pero seguro. Prefiero 30 minutos de cuidado a 4 horas arreglando un desastre.

    Pasos posteriores a la recuperación: hardening post-ataque

    Recuperar la BD es solo el primer 40% del trabajo. El otro 60% es prevenir que vuelva a pasar.

    Auditoría de plugins y temas

    El 85% de compromisos WordPress vienen de código de terceros desactualizado. Usando WP-CLI:

    wp plugin list –allow-root

    wp theme list –allow-root

    Identifica qué estaba activo en el momento del ataque. Disabilitalo todo temporalmente mientras investigas. Luego:

    • Actualiza a la última versión segura.
    • Si no hay actualización disponible, desinstala y reemplaza por alternativa mantenida.
    • Si es código custom, audítalo en busca de inyección SQL, RFI/LFI, ejecución de código.

    Protege wp-config.php y el prefijo de tablas

    Aunque tu BD ya esté limpia, un atacante puede volver si encuentra wp-config.php o adivina el prefijo «wp_».

    Mueve wp-config.php un nivel arriba del directorio WordPress (fuera de public_html si es posible). Luego, en la parte final de wp-config.php:

    $table_prefix = ‘sgx7k8_’;

    Cambia a un prefijo aleatorio de 6-8 caracteres. Luego en phpMyAdmin, rebautiza todas las tablas de wp_* a sgx7k8_*. WordPress detectará el nuevo prefijo automáticamente.

    Activar WordPress Security API y 2FA

    En wp-config.php, añade:

    define(‘FORCE_SSL_ADMIN’, true);

    define(‘DISALLOW_FILE_EDIT’, true);

    El segundo deshabilita la edición de archivos desde el panel, bloqueando un vector de persistencia común.

    Para 2FA, instala Wordfence o iThemes Security. Ambos permiten autenticación de dos factores en wp-login.php y protegen contra fuerza bruta.

    Implementa reglas .htaccess robustas

    En tu archivo .htaccess raíz, añade estas líneas para bloquear acceso directo a archivos peligrosos:

    # Bloquea acceso a wp-config.php
    <Files wp-config.php>
    order allow,deny
    deny from all
    </Files>

    # Bloquea acceso a wp-admin excepto desde panel
    <Directory ~ «^/.*wp-admin»>
    order allow,deny
    allow from 127.0.0.1
    deny from all
    </Directory>

    Monitoreo continuo: detecta futuras incidencias antes de que se conviertan en corrupción

    Lo que recomiendo siempre a mis clientes es monitoreo proactivo. No esperes a que explote.

    Vigila cambios en wp_users y wp_options

    Usa Wordfence o Sucuri para alertas de:

    • Nuevos usuarios administrativos creados sin tu consentimiento.
    • Cambios en URLs (siteurl, home).
    • Activación de plugins maliciosos.
    • Cambios en permisos de archivos.

    Logs de base de datos

    Si tu hosting lo permite, habilita query logging en MySQL. Esto crea un log de todas las consultas SQL ejecutadas. Cuando investigues un incidente, consultas las últimas horas y ves exactamente qué se modificó.

    SET GLOBAL general_log = ‘ON’;

    Advertencia: Esto consume recursos. Úsalo temporalmente durante auditorías, no en producción de forma permanente.

    Backups frecuentes y verificados

    No basta con tener backup. Necesitas saber que funciona. Mi protocolo:

    • Backup diario de BD y files (plugin UpdraftPlus con almacenamiento en Google Drive o S3).
    • Restauración de prueba semanal en staging para verificar integridad.
    • Backup manual antes de cambios críticos (actualizaciones, cambios de plugins).
    • Retención mínima de 30 días para poder restaurar si descubres ataque con retraso.

    Cuándo llamar a un profesional de seguridad

    Hay momentos donde la bricolaje se vuelve arriesgada. Si te encuentras con cualquiera de estos, contacta a un experto:

    • Corrupción en múltiples tablas, no solo wp_users y wp_options.
    • Inyección SQL activa: cada vez que reparas algo, vuelve a aparecer malware.
    • No tienes acceso SSH o phpMyAdmin: solo panel de hosting limitado.
    • El sitio genera errores PHP que no sabes interpretar.
    • Sospechas que el servidor completo (no solo WordPress) está comprometido.
    • Necesitas evidencia forense para reclamación a aseguradora o acción legal.

    En estos casos, lo que hacemos en ManuelFolgar.com es acceso directo con análisis forense, herramientas especializadas de detección y un informe completo de qué pasó, cuándo y cómo remediarlo. Te evitamos horas de prueba-error que podrían empeorar las cosas.

    Resumen: tu checklist de recuperación de BD corrupta

    1. Diagnostica con CHECK TABLE en MySQL.
    2. Si hay backup limpio, restaura en staging y verifica antes de producción.
    3. Si no: repara con wp db repair –allow-root o extrae usuarios válidos a tabla nueva.
    4. En wp_options, identifica y elimina una opción maliciosa a la vez, verificando funcionalidad cada vez.
    5. Audita plugins/temas y desactiva los sospechosos.
    6. Implementa hardening: FORCE_SSL_ADMIN, DISALLOW_FILE_EDIT, prefijo aleatorio, .htaccess restrictivo.
    7. Activa monitoreo y alertas (Wordfence, Sucuri).
    8. Establece política de backups diarios con restauración de prueba semanal.
    9. Planifica auditoría de seguridad completa para identificar vector de ataque original.

    La corrupción de base de datos es seria, pero recuperable si actúas con método y paciencia. Lo peor que puedes hacer es entrar en pánico y ejecutar comandos sin saber qué hacen. Cada paso documentado es un paso hacia atrás en el ataque.

    ¿Necesitas ayuda profesional para recuperar tu WordPress tras un ataque? En ManuelFolgar.com ofrecemos análisis forense, reparación de BD y auditorías de seguridad integral. Contacta aquí para una valoración sin compromiso y te indicaré exactamente qué está pasando en tu sitio y cómo arreglarlo de forma segura.

  • Diagnóstico profesional: herramientas que revelan lo que esconden los atacantes

    Diagnóstico profesional: herramientas que revelan lo que esconden los atacantes

    Diagnóstico profesional: herramientas que revelan lo que esconden los atacantes

    Cuando analizo un sitio web comprometido, lo primero que hago es dejar a un lado las suposiciones. En mi experiencia, la diferencia entre identificar una amenaza real o pasar por alto un backdoor silencioso depende casi enteramente de las herramientas que uses y de cómo las domines. En este artículo te muestro el arsenal técnico que yo utilizo diariamente para exponer lo que los atacantes intentan ocultarte.

    Por qué necesitas herramientas de diagnóstico específicas

    Un malware moderno no deja señales obvias. No es un archivo rojo titilante en tu panel de WordPress. Es código inyectado en funciones.php, es una tabla de base de datos con registros de backdoor, es un certificado SSL comprometido que sigue siendo válido, es un usuario fantasma creado hace seis meses que nadie recuerda. Sin las herramientas adecuadas, navegas a ciegas.

    Lo que recomiendo siempre es un enfoque en capas: escaneo superficial, análisis de código, inspección de base de datos, auditoría de logs, y búsqueda de indicadores de compromiso (IoC). Cada herramienta te revela una perspectiva distinta del ataque.

    Herramientas de escaneo web: tu primera línea de defensa

    Empiezo con Sucuri SiteCheck. No es una herramienta cara ni requiere instalación. Metes la URL y en segundos ves si Google ha marcado el dominio como malicioso, si hay inyección de código malicioso detectada, si los certificados SSL están comprometidos. He descubierto cryptominers que llevaban dos meses inyectados solo porque SiteCheck los detectó en la lista negra de proveedores.

    Sucuri SiteCheck es gratuito. Es tu aliado. Úsalo antes de hacer nada más.

    Para análisis más profundo, recomiendo MalCare Security. Es un plugin de WordPress que ejecuta un escaneo de malware comparando tu código contra una base de datos de más de 100 millones de firmas de malware conocidas. Lo que MalCare hace bien es detectar backdoors incrustados en temas y plugins legitimados. He visto casos donde un plugin de contacto aparentemente limpio contenía una webshell escondida bajo el nombre de una clase falsa.

    Wordfence Security es otra herramienta que uso constantemente. Su escáner es agresivo (a veces demasiado), pero su función de detección de cambios en archivos es imprescindible. Cuando alguien modifica tu wp-config.php o inyecta código en index.php, Wordfence lo sabe. Su CLI te permite automatizar auditorías sin depender del navegador.

    Inspección de línea de comandos: donde viven los ataques reales

    Las herramientas gráficas son tranquilizantes. La realidad está en la terminal.

    WP-CLI es mi arma más valiosa. Con un comando puedo listar todos los usuarios de WordPress, incluidos los fantasmas creados por backdoors. Con otro, puedo inspeccionar el contenido de funciones.php sin que el navegador intente renderizarlo (evitando que el código malicioso se ejecute mientras lo examino). Ejemplo básico:

    wp user list –allow-root

    Me muestra cada usuario, cada dirección de correo, cada fecha de creación. He encontrado usuarios llamados «temp», «admin2», «backup» creados en horarios extraños, siempre un indicador de compromiso.

    Para inspeccionar archivos sospechosos sin ejecutarlos, uso strings y grep. Si veo que un archivo .js tiene un tamaño inusual (200 KB cuando debería tener 20 KB), ejecuto:

    strings archivo.js | grep -i «eval|base64|setTimeout»

    Los atacantes casi siempre usan eval(), ofuscación base64 o setTimeout para ocultar código. Si lo encuentro, lo sé.

    Análisis de base de datos: donde los atacantes guardan los secretos

    La base de datos es el corazón del sitio. Un atacante que coloque una puerta trasera bien hecha siempre guarda credenciales, configuración maliciosa o registros en la BD.

    Accedo vía SSH y conecto directamente a MySQL:

    mysql -u usuario -p basedatos

    Luego ejecuto:

    SELECT * FROM wp_users WHERE user_registered > DATE_SUB(NOW(), INTERVAL 30 DAY);

    Esto me muestra cada usuario creado en los últimos 30 días. Frecuentemente encuentro usuarios que no reconoce nadie.

    También inspecciono tablas personalizadas que no deberían existir. Los atacantes a menudo crean tablas como wp_cache_malware o wp_tmp_data para almacenar datos exfiltrados. Un comando simple:

    SHOW TABLES;

    Te revela si hay tablas inusuales. Una vez encontré una tabla llamada «crypto_data» con direcciones de wallet de Bitcoin.

    Análisis de logs: la cronología del ataque

    Los logs nunca mienten. Un atacante puede borrar muchas cosas, pero si los logs de servidor están intactos, puedes reconstruir el ataque completo.

    Apache/Nginx logs en /var/log/apache2/access.log o /var/log/nginx/access.log contienen cada solicitud HTTP. Busco patrones sospechosos:

    grep «wp-admin|wp-login.php» /var/log/apache2/access.log | cut -d’ ‘ -f1 | sort | uniq -c | sort -rn

    Este comando me muestra qué IPs intentaron acceder a wp-login.php más veces. Ataques de fuerza bruta son obvios: cientos de peticiones desde la misma IP en minutos.

    Wordfence genera sus propios logs (en /wp-content/plugins/wordfence/) que son aún más útiles porque ya filtran intentos de ataque identificados.

    Herramientas de detección de inyección de código

    VirusTotal no es específicamente para WordPress, pero es poderosa. Subo archivos sospechosos (o incluso URLs completas) y dejo que 70+ antivirus los analicen simultáneamente. He detectado webshells que MalCare pasó por alto simplemente porque VirusTotal lo flagueó como Trojan.PHP.Shell.

    Para análisis local, grep recursivo es tu aliado. Busco patrones característicos de inyección:

    grep -r «eval(» . –include=»*.php» | head -20

    grep -r «base64_decode» . –include=»*.php»

    grep -r «assert(» . –include=»*.php»

    El 90% de los backdoors contienen al menos una de estas funciones. Es raro encontrar código legítimo que las use.

    Auditoría de permisos de archivos y propietarios

    Un ataque exitoso casi siempre requiere cambiar permisos de archivos. Un archivo .php que debería ser 644 pero es 777 es una bandera roja. Ejecuto:

    find . -type f -perm 777 -o -type f -perm 666

    Cualquier archivo con permisos de escritura global es sospechoso.

    También verifico propietarios:

    find . -not -user usuario_www -type f

    Si hay archivos propiedad de «root» o un usuario extraño en una carpeta que el servidor debería controlar, algo ocurrió.

    Inspección de certificados SSL y conexiones externas

    Atacantes modernos a menudo redirigen tráfico hacia servidores C2 (command and control). Inspecciono:

    openssl s_client -connect dominio.com:443

    Verifico que el certificado es legítimo y que no hay MITM (man-in-the-middle). También busco configuraciones de DNS sospechosas o modificaciones en .htaccess que redirijan tráfico.

    Monitoreo continuo vs. diagnóstico puntual

    El diagnóstico profesional no es un evento único. Después de detectar y limpiar un ataque, configuro monitoreo permanente. Wordfence en modo «monitoring» revisa cambios de archivos diariamente. Sucuri proporciona alertas de malware. Google Search Console notifica si hay malware detectado nuevamente.

    Lo que aprendí después de limpiar cientos de webs es que el 40% de los sites reinfectados lo fueron porque no se configuró vigilancia post-limpieza.

    Herramientas específicas para PrestaShop

    Si tu problema es PrestaShop, el enfoque es ligeramente distinto. Busco modificaciones en /classes/, inyecciones en /modules/, y especialmente en módulos de pago comprometidos. La herramienta más útil es una auditoría manual de hashes de archivos comparándola con la versión oficial de PrestaShop descargada directamente desde su web.

    El diagnóstico que no puedes hacer solo

    Estas herramientas te dan visibilidad. Pero cuando encuentras un backdoor bien ofuscado, o cuando necesitas reconstruir un ataque APT (Advanced Persistent Threat) para entender cómo los atacantes mantuvieron acceso durante meses, necesitas análisis forense profesional. Yo combino estas herramientas con análisis manual de código, ingeniería inversa de malware, y reconstrucción de cadenas de ataque.

    Si tu sitio ha sido comprometido o sospechas que lo está, estas herramientas te dan un diagnóstico inicial. Pero si necesitas garantía de que está completamente limpio, si necesitas investigación forense de un ataque sofisticado, o si el malware está bien oculto, contacta conmigo para un diagnóstico profesional completo. Ejecuto análisis manual, verifico cada línea de código sospechosa, audito permisos, inspecciono logs históricos, y te doy un reporte detallado de qué pasó, cómo entró, y cómo garantizar que no vuelva.

    El coste de no diagnosticar correctamente es mucho mayor que el de hacerlo bien desde el principio.

  • Por qué los atacantes dejan trampas que rompen limpiezas manuales incompletas

    Por qué los atacantes dejan trampas que rompen limpiezas manuales incompletas

    Por qué los atacantes dejan trampas que rompen limpiezas manuales incompletas

    Cuando analizo un sitio web comprometido, siempre encuentro lo mismo: no solo malware evidente, sino capas de protección inversa diseñadas específicamente para sabotear limpiezas amateur. Los atacantes no son tan ingenuos como para dejar un backdoor simple. Saben que el administrador web intentará eliminar archivos manualmente, así que preparan trampas que reinfectan el sitio en cuestión de horas. En mi experiencia, el 87% de las limpiezas manuales incompletas fallan precisamente porque ignoran estos mecanismos de persistencia.

    La mentalidad del atacante: permanencia sobre oportunismo

    Un backdoor moderno no es un virus de los 90. Los atacantes profesionales piensan en control a largo plazo, no en acceso puntual. Cuando comprometen tu WordPress o PrestaShop, invierten tiempo en asegurar que, aunque borres archivos, ellos sigan dentro. Es una inversión: una vez dentro, pueden robar datos de clientes, inyectar skimmers de tarjetas (tipo Magecart), distribuir malware a tus visitantes o alquilar acceso a otros delincuentes.

    Lo que hace que una limpieza manual sea tan vulnerable es que el propietario asume que con eliminar el archivo .php sospechoso ya está resuelto. Incorrecto. El atacante ha plantado múltiples llaves maestra antes de que tú siquiera notes que estás comprometido.

    Las trampas más comunes que sabotean limpiezas manuales

    1. Backdoors múltiples dispersados en carpetas no obvias

    Cuando encuentro una webshell en /wp-admin/, el atacante ya ha dejado 4 o 5 más en ubicaciones como /wp-content/uploads/2024/01/, /wp-includes/fonts/, o incluso dentro de directorios de caché de plugins. En una limpieza manual, el administrador busca en la raíz y wp-admin, elimina lo evidente, y se va satisfecho. El sitio se reinfecta en 48 horas desde esos backdoors dormidos.

    2. Código incrustado en librerías legítimas

    He visto backdoors inyectados dentro de archivos de Google Fonts, fontawesome.min.js, o jquery.min.js. El .htaccess o wp-config.php contiene una línea que incluye esos archivos «legítimos» que, en realidad, contienen código malicioso. Borras el wp-config.php sospechoso, pero el atacante lo restaura automáticamente mediante una tarea cron o un hook de WordPress gancho oculto que nunca localizaste.

    3. Hooks de WordPress y filtros persistentes

    En WordPress, un atacante inteligente no escribe backdoors en archivos de tema. Usa add_action() y add_filter() en functions.php o en un archivo MU plugin (/wp-content/mu-plugins/). Cuando haces una limpieza manual, eliminas el tema comprometido, pero si la base de datos contiene opciones guardadas con esos hooks serializados, o si dejaste un plugin «inactivo» cargado, el malware persiste.

    4. Modificaciones en wp-config.php y .htaccess permanentes

    Estos archivos suelen contener líneas como:

    define('WP_DEBUG_LOG', '/tmp/.cache/error_log'); @eval($_POST['cmd']);

    O reglas .htaccess que redirigen tráfico a través de tu propio servidor antes de entregarlo, capturando datos. Borras el archivo, pero si no cambias las credenciales de FTP/SFTP, el atacante lo restaura desde cero en minutos. He visto casos donde el administrador borra wp-config.php, WordPress lo regenera automáticamente con los datos en la base de datos, y el atacante ya tiene acceso de nuevo.

    5. Base de datos comprometida: opciones de WordPress y tablas personalizadas

    No todas las infecciones viven en archivos. Un atacante puede insertar una opción de WordPress con un nombre inocente como «widget_text_1» que contiene código PHP serializado. Durante la limpieza, te enfocas en archivos, y nunca tocas la base de datos. La puerta trasera permanece abierta en la tabla wp_options.

    Lo que recomiendo siempre es usar WP-CLI para auditar la base de datos:

    wp option get widget_text_1 | grep eval

    Si encuentras patrones sospechosos, sabes que la infección es más profunda.

    Por qué una limpieza manual incompleta es peor que nada

    Aquí está el problema psicológico: si eliminas el 90% del malware visible, el sitio parece funcionar. Google tardará días en notar que sigue siendo malicioso. En ese tiempo, el atacante observa tu limpieza, ve qué eliminaste y optimiza sus trampas para la próxima ronda. Una limpieza incompleta es, para el atacante, un regalo: le das información sobre tus defensas débiles.

    Además, Google Search Console empezará a mostrar notificaciones como «Malware detectado» una semana después de tu limpieza. Tu sitio será desindexado. Los visitantes verán advertencias de navegador. Y el atacante está riéndose, porque sabe que vuelvas a intentar lo mismo.

    Las herramientas que los atacantes usan para fortalecer sus trampas

    Ofuscación y compresión

    El malware moderno no viene como código legible. Se empaqueta con herramientas como WP-VulnDB Exploit Pack o aPHP, que comprimen y ofuscan el payload. Cuando lo ves en un editor de texto, parece galimatías ilegible. Una limpieza manual que se basa en «buscar código sospechoso» fallarán al instante.

    Verificación de integridad falsa

    El atacante injerta código que, cuando lo ejecutas, verifica si ciertos archivos existen. Si no están presentes (porque los borraste), el código se regenera automáticamente desde una ubicación remota o desde la base de datos. Es una rueda de hámster: cuanto más intentas limpiar, más rápido se reinfecta.

    Rootkits a nivel servidor

    En compromisos graves, el atacante no solo toca tu WordPress. Ha conseguido acceso SSH y ha instalado un rootkit en el servidor. Significa que puede moverse entre directorios, restaurar archivos, modificar logs, e incluso ocultar procesos maliciosos de herramientas como top o ps. Una limpieza manual es completamente inútil aquí; necesitas reimaginar el servidor.

    Señales de que tu limpieza manual fue incompleta

    Si ves esto después de limpiar, sabes que quedaron trampas:

    • Google Search Console sigue marcando malware después de una semana de limpieza
    • Logs de acceso muestran POST a /wp-admin.php o rutas inexistentes después de la limpieza
    • Tu velocidad de sitio cae repentinamente (el malware consome CPU minando criptomonedas)
    • Intentos de login desde IPs extrañas con credenciales débiles que nunca deberían funcionar
    • Archivos nuevos aparecen en /uploads/ con nombres tipo «shell.php.jpg» o «admin_panel.php»
    • El archivo wp-config.php tiene una fecha de modificación más reciente de la que debería

    Cómo detectar estas trampas antes de que sabotéen tu limpieza

    Audita desde fuera del servidor

    Usa herramientas como Sucuri SiteCheck y VirusTotal para obtener una visión externa del malware. Estos servicios detectan patrones que un editor FTP nunca vería. Si Sucuri marca 5 archivos maliciosos pero tú solo ves 1, hay 4 escondidos.

    Descarga una copia del sitio y analízala localmente

    Con herramientas como Wordfence CLI, puedes escanear la copia descargada sin conectarte al servidor comprometido. Permite que los patrones maliciosos se revelen sin el ruido de un acceso FTP lento.

    Examina la base de datos completa

    Descarga una copia de la base de datos (phpMyAdmin o directamente vía shell) y busca strings sospechosas como «eval», «base64», «system», «assert». Serialized data (que parece s:10:»eval_post») suele contener malware en opciones de WordPress.

    Revisa los permisos de archivos y carpetas

    Los backdoors suelen vivir en carpetas 777 (permisos de lectura-escritura-ejecución para todos). Si ves /wp-content/uploads/ con permisos 777, es una invitación abierta. Los atacantes escriben sus shells ahí directamente.

    Por qué es mejor hacer una limpieza profesional

    En ManuelFolgar.com, cuando hacemos una auditoría de seguridad, no buscamos archivos. Buscamos la cadena completa de compromisos: dónde entró el atacante, cuánto tiempo estuvo dentro, qué datos robó, y qué dejó tras de sí.

    Usamos:

    • Análisis de logs de acceso (Apache, Nginx, FTP, SSH) para reconstruir la cadena de ataque
    • Comparación de hashes de archivos contra versiones oficiales de WordPress/PrestaShop
    • Auditoría completa de la base de datos, tabla por tabla
    • Reinstalación controlada desde cero con arquitectura hardened
    • 2FA, CSP headers, HSTS, y reglas WAF para evitar reinfecciones

    Una limpieza manual te cuesta horas de estrés y reinfecciones. Una limpieza profesional cuesta menos de lo que pierdes en una reinfección.

    Pasos de hardening post-limpieza para evitar trampas futuras

    Cuando termina la limpieza, estos pasos previenen que vuelva a ocurrir:

    Cambiar contraseñas (todas): WordPress admin, FTP, SSH, base de datos, hosting cPanel/Plesk.

    Deshabilitar edición de archivos: Añade a wp-config.php: define('DISALLOW_FILE_EDIT', true);

    Cambiar prefijo de tablas: Si la base de datos aún usa «wp_», cambio a algo como «xyz_». Muchos exploits apuntan a wp_users de forma automática.

    Proteger wp-config.php y .htaccess: Permisos 644, no 755. Considera moverlos fuera de web root si es posible.

    Limitar intentos de login: Con Wordfence o similar, bloquea después de 5 intentos fallidos en 5 minutos.

    Auditorías regulares: Scans mensuales con Wordfence CLI o MalCare que te alertan de cambios sospechosos.

    Conclusión: la trampa del «ya está limpio»

    Los atacantes saben que una limpieza manual te da una falsa sensación de seguridad. Crees que lo peor pasó, que el sitio está salvado. Pero ellos ya han plantado las semillas de la próxima infección. Una gota de malware escondida en la base de datos, un hook de WordPress en la tabla de opciones, un archivo .htaccess modificado en el servidor: cualquiera de esos es suficiente para tener acceso total de nuevo en una semana.

    Lo que recomiendo siempre es este enfoque: si tu sitio ha sido comprometido una vez, fue porque había vulnerabilidades (desactualizaciones, contraseñas débiles, plugins nulled). Una limpieza que no cierra esas puertas solo compra tiempo. Necesitas una auditoría profesional que identifique cómo entraron, limpie completamente, y fortifique contra futuras intrusiones.

    Si tu WordPress o PrestaShop ha mostrado signos de malware, no intentes una limpieza manual. Los atacantes son profesionales. Ellos cuentan con eso. Contacta conmigo para una auditoría de seguridad profesional que elimine la infección de raíz y cierre todas las puertas traseras que dejaron abierta.

  • Cómo auditar logs de WordPress para encontrar malware

    Cómo auditar logs de WordPress para encontrar malware

    Cómo auditar logs de WordPress para encontrar malware

    Cuando analizo un sitio WordPress comprometido, lo primero que hago es revisar los logs. Los archivos de registro son tu mejor aliado para detectar qué ha pasado, cuándo entró el atacante y qué acciones realizó. En mi experiencia, muchos administradores ignoran completamente estos archivos, lo que les impide identificar infecciones hasta que es demasiado tarde.

    Los logs de WordPress no están habilitados por defecto, y esa es precisamente la razón por la que tantos sitios caen sin que nadie se dé cuenta. Aquí te enseño cómo configurarlos, dónde encontrarlos y cómo interpretarlos para detectar actividad maliciosa antes de que cause daños irreversibles.

    ¿Por qué los logs son críticos en la seguridad de WordPress?

    Los logs son el registro de eventos de tu sitio. Sin ellos, es como tener una tienda sin cámaras de vigilancia: cualquiera puede entrar, robar y marcharse sin dejar rastro. Un atacante que inyecta un backdoor, modifica archivos o ejecuta consultas maliciosas deja huellas en los logs si están configurados correctamente.

    Cuando no auditas logs regularmente, los malwares pueden vivir en tu servidor durante meses sin que lo sepas. He visto sitios de clientes con cryptominers ejecutándose 24/7, robando recursos, mientras el propietario no tenía ni idea. Los logs habrían mostrado exactamente cuándo se instaló el script malicioso y desde dónde.

    Además, los logs te permiten:

    • Identificar intentos de acceso no autorizados al wp-admin
    • Detectar inyecciones SQL y XSS en tiempo real
    • Encontrar plugins o temas modificados maliciosamente
    • Rastrear cambios no autorizados en la base de datos
    • Cumplir requisitos legales de auditoría (RGPD, AEPD)
    • Análisis forense después de una brecba de seguridad

    Habilitando debug y logging en WordPress

    Lo primero es activar los logs. WordPress tiene un sistema nativo de debug que, sorprendentemente, está deshabilitado por defecto. Accede a tu archivo wp-config.php (en la raíz de tu instalación) y busca esta sección:

    define(‘WP_DEBUG’, false);

    Cámbialo por:

    define(‘WP_DEBUG’, true);
    define(‘WP_DEBUG_LOG’, true);
    define(‘WP_DEBUG_DISPLAY’, false);

    El parámetro WP_DEBUG_DISPLAY en false es importante: hace que los errores se registren en un archivo en lugar de mostrarse públicamente en tu sitio (lo que sería un riesgo de seguridad).

    Una vez guardado, WordPress creará automáticamente un archivo de log en /wp-content/debug.log. Este archivo contendrá todos los errores de PHP, advertencias y mensajes de depuración de plugins y temas.

    Los diferentes tipos de logs en WordPress

    WordPress genera varios tipos de logs, y cada uno cuenta una historia diferente:

    1. Debug.log (PHP errors)

    Este es el más obvio. Contiene errores de PHP, advertencias y notificaciones. Si un plugin malicioso intenta ejecutar código, aquí aparecerán sus errores. Cuando reviso un sitio comprometido, busco patrones como:

    • Llamadas a funciones no definidas (típico de backdoors que intentan ejecutar comandos del sistema)
    • Errores de permisos en archivos (alguien intentó escribir un webshell)
    • Warnings de conexión a bases de datos externas (comunicación con servidores de comando y control)

    2. Logs del servidor (Apache/Nginx)

    Estos están a nivel de servidor, no de WordPress. Contienen:

    • Access logs: Cada solicitud HTTP (GET, POST) con IP, timestamp, navegador, código de respuesta
    • Error logs: Errores del servidor, intentos de acceso a archivos inexistentes, errores de permiso

    En Apache, busca en /var/log/apache2/access.log o /var/log/apache2/error.log. En Nginx, en /var/log/nginx/access.log.

    3. Logs de la base de datos MySQL

    Si habilitaste el query logging en MySQL, verás cada sentencia SQL ejecutada. Esto es especialmente útil para detectar inyecciones SQL. Para habilitarlo en MySQL, añade esto a /etc/mysql/mysql.cnf:

    general_log = 1
    general_log_file = /var/log/mysql/mysql.log

    Ten cuidado: el query logging impacta en el rendimiento. Úsalo solo durante auditorías, no en producción permanentemente.

    4. Logs de plugins de seguridad

    Si tienes Wordfence, Sucuri o similar instalados, generan sus propios logs. Estos son especialmente valiosos porque esos plugins ya filtran eventos sospechosos por ti. Wordfence CLI permite analizar logs desde la terminal:

    wordfence-cli scanner scan –verbose

    Dónde encontrar los logs de WordPress

    El archivo debug.log está en /wp-content/debug.log (suponiendo que tu instalación de WordPress está en la raíz).

    Lo puedes consultar vía:

    • SFTP/FTP: Conecta a tu servidor y descarga el archivo directamente
    • SSH: Usa comandos como tail -f /path/to/wp-content/debug.log para ver el final del archivo en tiempo real
    • Panel de control: Si tienes cPanel, busca File Manager y navega a wp-content
    • WP-CLI: wp eval ‘echo file_get_contents( WP_CONTENT_DIR . «/debug.log» );’

    Para los logs del servidor (Apache/Nginx), necesitarás acceso SSH o a través de tu proveedor de hosting.

    Señales de malware en los logs: qué buscar

    Ya tienes los logs. Ahora vamos a lo importante: detectar el malware. Aquí están los patrones que yo busco siempre:

    Intentos de ejecución de comandos del sistema

    Los backdoors intentan ejecutar comandos como exec(), system(), shell_exec(), passthru(). Si ves errores como:

    Fatal error: Call to undefined function exec()

    Significa que alguien está intentando ejecutar comandos. Busca el archivo fuente en el mensaje de error.

    Accesos a archivos sospechosos en access.log

    En los logs de Apache/Nginx, busca patrones como:

    • wp-admin/upload.php?param=… – Upload de archivos no autorizado
    • wp-admin/admin-ajax.php?action=malicious_action – AJAX manipulation
    • GET /wp-content/uploads/2024/01/shell.php – Acceso a webshell inyectado
    • POST /index.php?id=1′ OR ‘1’=’1 – Inyección SQL clásica

    También busca códigos de respuesta sospechosos: 403 (acceso denegado), 500 (error interno, a menudo por malware), 200 para archivos que no deberían estar ahí.

    Cambios en la base de datos

    Si tienes MySQL general log habilitado, busca:

    • ALTER TABLE – Modificación de estructura de tablas
    • INSERT INTO wp_posts desde IPs raras o a horas inusuales
    • UPDATE wp_options SET option_value – Cambio de configuraciones críticas
    • DROP TABLE – Eliminación destructiva (ransomware)

    Modificaciones de archivos

    Si tu hosting registra cambios de archivos, busca:

    • Archivos PHP nuevos en /wp-content/uploads/ (zona típica para inyectar webshells)
    • Cambios en wp-config.php o .htaccess en fechas sospechosas
    • Plugins o temas con fechas de modificación reciente sin que los hayas actualizado

    Herramientas para automatizar el análisis de logs

    Analizar logs manualmente es tedioso. Estas herramientas lo hacen más fácil:

    WP-CLI con grep

    Si tienes WP-CLI instalado, puedes extraer información rápidamente:

    tail -500 /path/to/wp-content/debug.log | grep «Fatal|Warning|Notice»

    Esto te muestra los últimos 500 líneas del log, filtrando solo errores relevantes.

    Wordfence CLI

    Si tienes Wordfence (gratuito), la herramienta CLI es excelente:

    wordfence-cli firewall view-live

    Te muestra en tiempo real qué está intentando bloquear el firewall.

    MalCare y Sucuri

    Si usas estos plugins de seguridad premium, generan reportes visuales de los logs. Recomiendo especialmente MalCare por su interfaz de análisis forense.

    Google Search Console y Google Analytics

    No son logs técnicos, pero son señales. Si ves un aumento repentino de:

    • Advertencias de malware en GSC
    • Tráfico desde URLs raras
    • Redirecciones no autorizadas

    Eso significa que Google ha detectado algo. Ve a los logs del servidor para confirmarlo.

    Análisis forense: paso a paso

    Aquí está mi metodología cuando encuentro un sitio comprometido:

    Paso 1: Recolecta todos los logs
    Descarga los logs de al menos 30 días atrás (o más, si tienes espacio). El malware puede estar dormido y activarse después.

    Paso 2: Identifica el timeline
    Busca la primera aparición de actividad sospechosa. ¿Cuándo comenzó? ¿Hubo un cambio de plugin, una actualización, un pico de tráfico antes?

    Paso 3: Traza la IP del atacante
    En access.log, filtra por IPs que hayan accedido a wp-admin o uploads justo antes del evento. Algunos atacantes usan proxies, pero otros dejan rastros claros.

    Paso 4: Analiza el payload
    ¿Qué archivos modificaron? ¿Qué parámetros enviaron en POST? Esto te dice qué tipo de malware instalaron.

    Paso 5: Identifica el vector de entrada
    ¿Fue un plugin desactualizado? ¿Una contraseña débil de wp-admin? ¿Una vulnerabilidad de temas? Esto es crítico para evitar que vuelva a pasar.

    Configuración defensiva: logs para el futuro

    Una vez limpies el malware, implementa logging defensivo para detectar futuros ataques rápidamente:

    • Habilita WP_DEBUG_LOG permanentemente
    • Configura rotación de logs (con logrotate en Linux) para que no ocupen demasiado espacio
    • Activa alertas en tu hosting si un archivo .php se crea en wp-content/uploads/
    • Usa un plugin como Activity Log para registrar cambios en WordPress (qué usuario cambió qué, cuándo)
    • Implementa reglas en .htaccess para bloquear acceso directo a archivos sospechosos
    • Monitoriza los logs regularmente (mínimo semanal)

    Si tu sitio es crítico, un Sistema de Detección de Intrusiones (IDS) como Fail2Ban puede bloquear automáticamente IPs que intenten ataques comunes:

    [sshd]
    enabled = true
    port = ssh
    filter = sshd
    logpath = /var/log/auth.log
    maxretry = 5

    Errores comunes que cometen los administradores

    En mi experiencia auditando cientos de sitios, estos son los errores que veo constantemente:

    • No rotar los logs: El debug.log crece infinitamente si no lo limpias. Puedes usar un cron job: 0 0 * * * > /path/to/wp-content/debug.log
    • Ignorar los warnings: «Un warning no es un error grave». Error. Los warnings son a menudo el primer signo de malware.
    • No correlacionar logs: Mirar solo debug.log y no cruzarlo con access.log. Necesitas ver la imagen completa.
    • Acceso inseguro a logs: Si dejas debug.log visible públicamente, los atacantes ven qué plugins tienes. Usa .htaccess: Deny from all
    • No archivar logs antiguos: Después de 30-90 días, descarga los logs a almacenamiento seguro. Los atacantes a menudo los borran para cubrir sus huellas.

    Protegiendo los propios logs

    Un detalle importante: los atacantes intentan borrar logs para no dejar rastro. Protégelos:

    • Hace que wp-content/debug.log no sea legible por el servidor web (permisos 600)
    • Copia los logs regularmente a un almacenamiento remoto (S3, Google Cloud)
    • Usa un servicio de log centralizado como ELK Stack o Splunk para empresas

    Técnicamente, puedes configurar Syslog en WordPress para enviar logs directamente a un servidor syslog remoto, lejos del sitio comprometido:

    define(‘WP_DEBUG_LOG’, ‘/dev/log’);

    Esto envía los logs al demonio syslog en lugar de a un archivo local.

    Integración con herramientas de monitoreo SIEM

    Para sitios empresariales, recomiendo integrar WordPress con un SIEM (Security Information and Event Management). Esto centraliza todos los logs (WordPress, servidor, firewall, base de datos) en un único panel para análisis automático de amenazas.

    Incluso sin SIEM, un simple script bash que revise los logs diariamente y te envíe un resumen es muy útil:

    #!/bin/bash
    LOG_FILE=»/var/www/html/wp-content/debug.log»
    ERRORS=$(grep -i «fatal|error» «$LOG_FILE» | wc -l)
    if [ $ERRORS -gt 10 ]; then
      mail -s «Alerta: $ERRORS errores en WordPress» admin@tudominio.com < «$LOG_FILE»
    fi

    Conclusión: auditoría de logs como hábito de seguridad

    Auditar logs regularmente no es complicado, pero es la diferencia entre detectar un malware en 24 horas o descubrirlo cuando ya ha robado datos de clientes. He visto el daño que causa la negligencia.

    Mi recomendación es sencilla: habilita logging hoy, revisa los logs semanalmente, crea alertas automáticas y archiva logs históricos. Es como un sistema inmunológico para tu WordPress.

    Si descubres actividad sospechosa en los logs y no sabes cómo proceder, o si necesitas una auditoría forense profesional, en ManuelFolgar.com disponemos de herramientas especializadas y experiencia en decenas de casos de compromiso. Contacta conmigo para una auditoría de seguridad completa de tu sitio WordPress.

    Referencias técnicas

    Para más información sobre logging en WordPress y seguridad web:

  • Error 403 Forbidden en WordPress: problema de permisos o malware

    Error 403 Forbidden en WordPress: problema de permisos o malware

    Error 403 Forbidden en WordPress: cuándo es un problema de permisos y cuándo esconde malware

    Cuando accedes a tu sitio WordPress y de repente ves un error 403 Forbidden, lo primero que te pregunta es: «¿Qué he hecho?». En mi experiencia analizando cientos de webs comprometidas, este error es uno de los más engañosos que existen. Puede significar algo tan simple como un permiso de archivo mal configurado, o puede ser la señal de que alguien ha infiltrado un backdoor en tu servidor.

    La realidad es que el error 403 es como un síntoma en medicina: te dice que algo no va bien, pero no te dice qué es. Por eso necesitas un diagnóstico preciso. En este artículo te enseño a diferenciar ambos escenarios y qué hacer en cada caso.

    Qué significa el error 403 Forbidden

    El error 403 Forbidden es una respuesta HTTP que tu servidor web (Apache, Nginx) devuelve cuando un usuario intenta acceder a un recurso para el que no tiene permisos. A diferencia del 404 (página no encontrada), aquí el servidor sí ve el archivo o directorio, pero decide que no deberías poder verlo.

    En WordPress, esto ocurre típicamente cuando:

    • Los permisos de un archivo o carpeta están demasiado restrictivos (p. ej., 000 o 600 cuando deberían ser 644 o 755).
    • El propietario del archivo no es el usuario del servidor web (www-data en Linux).
    • Una regla .htaccess bloquea el acceso deliberadamente.
    • Una directiva Apache o Nginx prohíbe el acceso a ese recurso.
    • Un plugin de seguridad ha bloqueado la IP del visitante.

    Pero aquí viene lo importante: un atacante también puede generar un 403 intencionalmente para ocultarse. Veremos esto más adelante.

    Las 5 causas más comunes del error 403 en WordPress

    1. Permisos de archivos incorrectos (la más habitual)

    En mi experiencia, 7 de cada 10 casos de error 403 que veo son por esto. WordPress necesita que sus archivos y carpetas tengan permisos específicos para que tanto tú como el servidor web puedan leerlos y modificarlos.

    Los permisos correctos son:

    • Carpetas: 755 (rwxr-xr-x)
    • Archivos: 644 (rw-r–r–)
    • wp-config.php: 600 (rw——-) por seguridad

    Si alguien ha cambiado estos permisos (accidentalmente o tras una mala migración), obtendrás 403. Puedes verificarlo vía SSH o tu panel de hosting:

    1. Conecta por SSH o accede al administrador de archivos de tu hosting.
    2. Navega a la raíz de WordPress.
    3. En SSH: ls -la para ver los permisos (columna 1).
    4. Si ves números como 000, 600 (en archivos normales) o 600 (en carpetas), están mal.

    Para corregirlo desde SSH:

    find /ruta/a/wordpress -type f -exec chmod 644 {} ;
    find /ruta/a/wordpress -type d -exec chmod 755 {} ;

    2. Propietario de archivos incorrecto

    Si tras una migración o una instalación manual, los archivos no pertenecen al usuario del servidor web, WordPress no podrá escribir en ellos. Verificar el propietario:

    ls -l /ruta/a/wordpress | head -20

    Deberías ver algo como www-data www-data o nobody nobody (depende de tu hosting). Si ves root o tu usuario de SSH, ahí está el problema. Para corregirlo:

    chown -R www-data:www-data /ruta/a/wordpress

    3. Regla .htaccess que bloquea acceso

    Un archivo .htaccess corrupto o mal configurado puede devolver 403 a todo el mundo. Algunos plugins de seguridad añaden reglas que a veces son demasiado restrictivas.

    Prueba esto: accede a tu hosting y renombra el archivo .htaccess a .htaccess.bak. Si el error desaparece, aquí estaba el culpable. Luego regenera el .htaccess desde WordPress:

    • Ajustes → Enlaces permanentes
    • Haz clic en «Guardar cambios» (sin cambiar nada)

    4. Plugin de seguridad bloqueando tu IP

    Plugins como Wordfence, Sucuri, o iThemes Security pueden bloquear direcciones IP tras detectar múltiples intentos fallidos de login. Si hace poco intentaste acceder con una contraseña incorrecta varias veces, es probable que estés bloqueado.

    Solución: accede a través de una VPN o IP diferente, entra al panel de administración (si puedes) y desbloquea tu IP en el plugin.

    5. Configuración incorrecta de Apache/Nginx

    A veces, el servidor tiene una directiva <Directory> que prohíbe el acceso (Deny from all). Esto es menos común, pero si no encuentras el error en los puntos anteriores, contacta con tu proveedor de hosting.

    ¿Cuándo el error 403 es señal de malware?

    Aquí es donde pongo las antenas en alerta máxima. Un atacante sofisticado puede modificar archivos .htaccess o reglas Nginx para bloquear acceso intencionalmente y ocultarse. Es una técnica de ofuscación.

    Indicadores de que el 403 esconde algo oscuro:

    • El error apareció sin que hayas hecho cambios. Si no migraste, no actualizaste plugins ni tocaste permisos, y de repente aparece 403, es sospechoso.
    • El 403 aparece solo en ciertos directorios. Por ejemplo, ves tu home, pero /wp-admin devuelve 403. Eso puede indicar una regla .htaccess maliciosa que bloquea el acceso administrativo.
    • Hay un .htaccess nuevo o modificado que no creaste. Un atacante a menudo añade reglas como:

      <Files ~ ".php$">
      Deny from all
      </Files>

      Esto bloquea la ejecución de PHP en una carpeta específica para ocultar webshells.
    • Tu Google Search Console muestra un aumento de errores 403. Si Google de repente reporta 100+ URLs con error 403, alguien pudo haber puesto un bloqueo masivo. Entra en Google Search Console y verifica la sección «Problemas de cobertura».
    • Ves archivos PHP raros en directorios que no debería haber. Por ejemplo, /wp-content/uploads/shell.php o /wp-includes/wp-admin.php.

    Paso a paso: diagnóstico profesional del error 403

    Aquí es cómo yo procedo cuando un cliente me llama con este problema:

    Paso 1: Verificar los registros del servidor

    Los logs de Apache o Nginx son la fuente de verdad. Accede a ellos (normalmente en /var/log/apache2/ o /var/log/nginx/):

    tail -100 /var/log/apache2/error.log | grep 403

    Busca patrones. Verás líneas como:

    [client 192.168.1.100] File does not exist: /var/www/html/wp-admin → problema de permisos.
    access to /wp-admin denied by rule → regla .htaccess bloqueando.

    Paso 2: Inspeccionar .htaccess y archivos de configuración web

    Descarga tu .htaccess y revísalo línea a línea. Busca:

    • Directivas Deny from sospechosas.
    • Reglas RewriteRule raras que redirigen al 403.
    • Código ofuscado o comentarios en idiomas extraños.

    Si usas Nginx, revisa /etc/nginx/sites-enabled/default o tu configuración específica.

    Paso 3: Escanear archivos en busca de código malicioso

    Aquí es donde usaría herramientas como:

    • Wordfence CLI (gratuito, desde SSH): detecta backdoors conocidos.
    • WP-CLI con auditoría de archivos: wp plugin list --status=all para ver si hay plugins raros.
    • Sucuri SiteCheck (online): escanea tu dominio en busca de malware conocido.

    Si encuentro un backdoor, es momento de acción inmediata: aislamiento, copia de seguridad íntegra y limpieza.

    Paso 4: Revisar logs de acceso por patrones de ataque

    tail -1000 /var/log/apache2/access.log | grep -i "sql|union|select|xss"

    Esto busca intentos de inyección SQL o XSS. Si encuentras líneas como:

    GET /index.php?id=1 UNION SELECT ... HTTP/1.1

    Confirma que ha habido un intento de explotación.

    Soluciones según el diagnóstico

    Si es problema de permisos:

    1. Corrige los permisos como indiqué anteriormente.
    2. Verifica que el propietario es el usuario del servidor web.
    3. Regenera el .htaccess desde WordPress.
    4. Borra la caché del navegador (Ctrl+Shift+Supr) e intenta acceder.

    Si encontraste código malicioso:

    1. No lo borres aún sin una copia de seguridad limpia. Necesitas una línea de base para comparar.
    2. Identifica la fecha de modificación de archivos maliciosos (ls -la --full-time).
    3. Busca en los logs de acceso qué IP o qué solicitud HTTP lo creó.
    4. Elimina el malware, cambia todas las contraseñas (admin, FTP, bases de datos), y revisa plugins/temas.
    5. Si el backdoor es persistente (se regenera tras borrarlo), necesitas ayuda profesional. No es una tarea para DIY.

    Si hay una regla .htaccess maliciosa:

    Edita el .htaccess y elimina la regla sospechosa. Si tienes un backup de antes de que apareciera el error, compara versiones. Luego valida que la sintaxis es correcta (un error de sintaxis en .htaccess causa 500, pero con ciertos navegadores puede parecer 403).

    Cómo prevenirlo en el futuro

    Una vez resuelto, implementa estas medidas defensivas:

    • Monitoreo de cambios de permisos: configura alertas en tu hosting o usa un plugin como File Monitor para detectar cambios en archivos críticos.
    • Backups regulares: mantén backups automáticos diarios. Si ocurre un ataque, puedes restaurar sin perder semanas de trabajo.
    • Actualiza WordPress y plugins religiosamente. Vulnerabilidades no parcheadas son la puerta de entrada número 1.
    • Usa un plugin de seguridad confiable: Wordfence, Sucuri, o All in One WP Security. Configúralo para bloquear intentos de fuerza bruta y monitorear cambios de archivos.
    • Cambia el prefijo de tablas de WordPress: en lugar de wp_, usa algo como abc123_. Esto dificulta inyecciones SQL.
    • Deshabilita la edición de archivos desde el panel: añade esto a wp-config.php:

      define('DISALLOW_FILE_EDIT', true);
      Así, aunque un atacante entre al panel, no puede editar archivos directamente.
    • Configura autenticación de dos factores (2FA) en wp-login.php. Un atacante sin tu teléfono no puede entrar.
    • Limita intentos de login: usa una regla .htaccess o un plugin para bloquear después de 5 intentos fallidos en 15 minutos.

    Cuándo pedir ayuda profesional

    Si después de seguir estos pasos el error persiste, o si sospechas que hay malware pero no sabes cómo proceder, es momento de contactar a un profesional. En ManuelFolgar.com, realizamos auditorías de seguridad profundas, limpieza de malware certificada y hardening de WordPress. No jugamos a adivinar; usamos herramientas forenses reales y experiencia en miles de casos.

    Un error 403 que persiste puede costar dinero en inactividad de tu sitio, confianza de clientes y, lo peor, exposición de datos. La inversión en diagnóstico profesional se recupera rápidamente.

    Si necesitas ayuda, contacta conmigo aquí. Realizamos evaluación inicial gratuita de tu situación.