Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
setup-wordpress-with-security-best-practice — Guía completa para endurecer instalaciones de WordPress: cubre cambios de usuario administrador, aplicación de HTTPS, seguridad de plugins, permisos de archivos y configuración del servidor para sitios corporativos estáticos. | Kitploit
Herramientas/GitHubGitHub/password123456/setup-wordpress-with-security-best-practice
Auditoría de ConfiguraciónSeguridad WebAprendizaje y Educación
GitHubpassword123456/setup-wordpress-with-security-best-practice

setup-wordpress-with-security-best-practice

Guía completa para endurecer instalaciones de WordPress: cubre cambios de usuario administrador, aplicación de HTTPS, seguridad de plugins, permisos de archivos y configuración del servidor para sitios corporativos estáticos.

Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
2943hace 2 añosRevisado por Kitploit
Compartir

Configurar WordPress con Prácticas Recomendadas de Seguridad

Hits

Este documento está redactado con el objetivo de ser adecuado para aplicaciones web desarrolladas con WordPress que no interactúan con usuarios. Está destinado principalmente a páginas corporativas de marca, vistas estáticas diversas, páginas de reclutamiento y sitios similares.

Para sitios web donde los usuarios se registran y usan libremente el sitio, como comunidades abiertas, algunos puntos de este documento pueden no ser aplicables. Tenga esto en cuenta al leer.

Este documento no incluye todo el contenido necesario para asegurar WordPress.

Sin embargo, incluye información general y detallada hasta un nivel que permite realizar evaluaciones de riesgos de seguridad y respuestas a vulnerabilidades basadas en la guía.

Si encuentra esto útil, por favor dé una "estrella"🌟 para apoyar mejoras adicionales.


Tabla de Contenidos

  • 1. Asegurar que el Nombre de Usuario Admin Predeterminado de WordPress ha sido Cambiado
  • 2. Asegurar que los Roles y Permisos de Usuario en WordPress se Gestionen Adecuadamente
``` ### 8.9. Asegurar que el Servidor Web Solo Responda a Cabeceras de Host Basadas en Dominio Para asegurar tu servidor web, es esencial asegurarse de que solo responda a solicitudes dirigidas a tu nombre de dominio y no a solicitudes realizadas directamente a la dirección IP del servidor.
  • 3. Asegurar que el Registro de Usuarios esté Deshabilitado
  • 4. Asegurar que el Editor de Archivos de Plugins esté Deshabilitado
  • 5. Asegurar que los Plugins No Utilizados e Innecesarios estén Desactivados
  • 6. Asegurar que WordPress esté Configurado para Usar Solo HTTPS, Incluyendo el Admin de WordPress
  • 7. Asegurar que se Apliquen Restricciones de Acceso por IP (ACL)
    • 7.1. Asegurar que se apliquen restricciones de acceso por IP al admin de WordPress.
    • 7.2. Restringir el Acceso por IP o Deshabilitar la Función JSON REST API
    • 7.3. Deshabilitar la Función XML-RPC API
    • 7.4. Deshabilitar WP-Cron o Restringir la Función
  • 8. Configuración del Sistema para un WordPress Seguro.
    • 8.1. Asegurar el Uso de Versiones de WordPress y PHP que No Estén al Final de su Vida Útil (EOL)
    • 8.2. Asegurar que Solo las Extensiones PHP Necesarias para WordPress estén Habilitadas
    • 8.3. Asegurar la Seguridad de los Plugins con Funciones de Carga de Archivos
    • 8.4. Asegurar que las Funciones y Configuraciones de PHP estén Configuradas Adecuadamente
    • 8.5. Asegurar que el Servidor Web se Ejecute Como un Usuario No Root - Usuario y Grupo Único y Sin Privilegios para la Aplicación del Servidor
    • 8.6. Asegurar que PHP-FPM se Ejecute Como un Usuario No Root - Usuario y Grupo Único y Sin Privilegios para la Aplicación del Servidor
    • 8.7. Asegurar una Configuración Segura del Directorio de Inicio de WordPress
    • 8.8. Asegurar que la Ejecución de PHP esté Deshabilitada en Directorios con Permisos de Escritura
    • 8.9. Asegurar que el Servidor Web Solo Responda a Cabeceras de Host Basadas en Dominio
    • 8.10. Configuración Completa del Servidor Web
  • 9. Asegurar las Actualizaciones de Seguridad de WordPress
  • 10. Asegurar Revisiones Regulares de Vulnerabilidades de Seguridad para WordPress

  • 1. Asegurar que el Nombre de Usuario Admin Predeterminado de WordPress ha sido Cambiado

    Al instalar WordPress, el nombre de usuario admin predeterminado es "admin" a menos que lo cambie durante el proceso de instalación. El nombre de cuenta "admin" es ampliamente conocido, por lo que debe cambiarse por un nombre diferente. Si continúa usando "admin" como su nombre de usuario admin, un atacante podría intentar un ataque de fuerza bruta usando "admin" para obtener acceso a su sitio WordPress.

    Si un atacante obtiene acceso a la cuenta de administrador de WordPress, tendrá control total sobre el sitio web. El nombre de usuario admin predeterminado de WordPress debe cambiarse por un nombre diferente.

    Auditoría:

    • Verificar si el nombre de usuario admin predeterminado de WordPress sigue siendo "admin".

    Remediación:

    • Si el nombre de usuario es "admin", cámbielo inmediatamente por un nombre de usuario menos predecible.
    1. Inicie sesión en su panel de administración de WordPress usando la cuenta admin.
    2. Vaya al área "Usuarios" desde su panel y haga clic en "Añadir nuevo usuario".
    3. Complete el formulario y elija "administrador" en el menú desplegable "Rol" (recuerde usar una contraseña web segura y también use el indicador de fortaleza de contraseña proporcionado para confirmar que su nueva contraseña sea lo suficientemente fuerte).
    4. Cuando termine, haga clic en el botón "Añadir nuevo usuario".
    5. Inicie sesión nuevamente con su nuevo nombre de usuario admin de WordPress.
    6. Vuelva a navegar al área "Usuarios".
    7. En la lista de usuarios, seleccione el nombre de usuario anterior "admin" y elija "Eliminar" en el menú desplegable.
    8. Al eliminar el admin anterior, se le preguntará acerca de los artículos publicados bajo el nombre de usuario anterior "admin".
      • Seleccione la opción "atribuir todas las entradas y enlaces a:" y seleccione su nuevo administrador.
      • Cuando todo esté listo, haga clic en "Confirmar eliminación".

    Nota:

    • Siempre use un "nombre para mostrar" diferente del nombre de usuario. Si el nombre de usuario real se usa como nombre para mostrar del autor del contenido, un hacker identificará fácilmente el nombre de usuario y atacará la cuenta.

    2. Asegurar que los Roles y Permisos de Usuario en WordPress se Gestionen Adecuadamente

    Por defecto, WordPress tiene cinco roles de usuario: "Administradores", "Editores", "Autores", "Colaboradores", "Suscriptores"

    Estos roles le permiten controlar qué tareas pueden realizar los usuarios en su sitio web asignando permisos apropiados. Si los roles y permisos de usuario no se gestionan adecuadamente, los usuarios podrían obtener acceso innecesario a funcionalidades críticas, representando un riesgo de seguridad significativo.

    Auditoría:

    • Verificar que los roles y permisos de usuario de WordPress estén ajustados a las necesidades de su sitio web.
    • Revisar todos los roles de usuario para asegurarse de que estén alineados con las políticas operativas actuales de su sitio web.

    Remediación:

    • Asignar y gestionar los roles de usuario según las necesidades de su sitio web.
    • Generalmente, WordPress debe operarse con un Administrador, un Editor, un Autor.
    • Eliminar cuentas admin innecesarias o reducir permisos cuando sea necesario.
    • Revisar periódicamente los usuarios y sus roles para asegurarse de que estén actualizados con cualquier cambio.
    noRolDescripciónPersonal Administrativo
    1AdministradorTiene acceso completo a todas las funciones de WordPress y puede gestionar todo el contenido del sitio.Administradores del Sistema
    2EditorPuede gestionar y publicar las entradas de otros usuarios, así como editar y publicar contenido.Gestores de Servicios Operativos, Colaboradores de Contenido Interno
    3AutorPuede escribir y publicar sus propias entradas, y tiene permiso para editar sus propias entradas.Colaboradores de Contenido Interno
    4ColaboradorPuede escribir contenido pero no puede publicarlo. Las entradas son revisadas y publicadas por un administrador.Colaboradores de Contenido Interno
    5SuscriptorPuede iniciar sesión en el sitio y gestionar su perfil personal, pero no puede escribir ni editar contenido.Colaboradores de Contenido Interno

    Nota:

    • En la mayoría de los casos, para sitios web orientados a servicios como blogs corporativos, páginas de reclutamiento, sitios de marca y sitios promocionales donde los usuarios interactúan mínimamente y el contenido se muestra principalmente, roles como "Administradores", "Editores" y "Autores" son suficientes.

    3. Asegurar que el Registro de Usuarios esté Deshabilitado

    WordPress incluye una función de registro de usuarios incorporada. Esta función está deshabilitada por defecto, pero un administrador puede activarla.

    Si esta función está habilitada, cualquiera puede registrarse y potencialmente acceder al panel de administración de WordPress, lo que puede provocar problemas de seguridad. Para la mayoría de los sitios web que no están destinados a operar como comunidades abiertas, la función de registro de usuarios es innecesaria y debe permanecer deshabilitada.

    Auditoría:

    • Verificar que el registro de usuarios esté deshabilitado. Puede comprobarlo intentando acceder a la página de registro de usuarios.
    1. Usando un navegador web

      • Vaya a https://yourwordpress.com/wp-login.php?action=register
      • Si el registro de usuarios está deshabilitado, verá "El registro de usuarios no está permitido actualmente". 3.1!
    2. Usando curl

      • Si el registro de usuarios está deshabilitado, redirigirá a la página deshabilitada.```

    curl -i -k "https://yourwordpress.com/wp-login.php?action=register"

    (response) HTTP/1.1 302 Moved Temporarily cache-control: no-cache, no-store, must-revalidate, max-age=0 content-type: text/html; charset=UTF-8 server: Apache content-length: 0 ... location: https://yourwordpress.com/wp-login.php?registration=disabled

    root@kitploit:~
    **Remediación:**
    - Si el registro de usuarios está habilitado, desactívalo.
    - Desmarca “Anyone can register”
    ![3.2!](https://assets.kitploit.com/production/public/readmes/6586/46991061b1bec392d06e00e986f048c6369b8db2c9e5a6b30f4f66dbc9b862d1.png)
    
    
    ## 4. Asegúrate de que el Editor de Archivos de Plugins esté Desactivado
    Si un atacante accede a una cuenta de Administrador de WordPress, puede tomar el control total de tu sitio web. 
    Pueden editar el código de tu tema y plugins a través de la función integrada "Editor", cargar scripts maliciosos, desfigurar tu sitio, enviar spam a tus usuarios y más.
    
    Los hackeos comunes a través de estos editores incluyen inyecciones SQL, hackeos de spam SEO y spam SEO japonés.
    
    **Auditoría:**
    - Verifica que el editor de archivos esté desactivado. 
    - Comprueba si puedes acceder al editor a través de Apariencia > Editor o Plugins > Editor de Plugins.
    
    **Remediación:**
    - Si el editor de archivos está habilitado, desactívalo siguiendo estos pasos:
    
    1. Accede a tu archivo wp-config.php usando el Administrador de Archivos o FTP
    2. Abre el archivo wp-config.php para editarlo.
    3. Desplázate hasta la parte inferior del archivo (si usas el wp-config.php predeterminado).
    4. Localiza la siguiente línea:
    `
    /* That’s all, stop editing! Happy publishing. */
    `
    5. Sobre esta línea, añade el siguiente código:
    `
    define('DISALLOW_FILE_EDIT', true);
    `
    6. Guarda los cambios y cierra el editor.
    7. Vuelve a tu panel de WordPress y confirma que las opciones del editor ya no están disponibles.
    
    
    ## 5. Asegúrate de que los Plugins No Utilizados e Innecesarios estén Desactivados
    Muchas vulnerabilidades en WordPress provienen de problemas de seguridad en los plugins. 
    Los plugins son de código abierto, lo que facilita que los atacantes encuentren y exploten vulnerabilidades. 
    Es crucial mantener los plugins que utilizas actualizados y desactivar cualquier plugin no utilizado para evitar una posible explotación.
    
    **Auditoría:**
    - Comprueba que los plugins no utilizados e innecesarios estén desactivados. 
    - Verifica que los plugins no utilizados e innecesarios estén desactivados.
    
    **Remediación:**
    - Desactiva cualquier plugin no utilizado e innecesario siguiendo estos pasos:
    
    **Usa Plugin Check - PCP:**
    - PCP: https://wordpress.org/plugins/plugin-check
    1. Instala y Activa Plugin Check (PCP):
       - Ve al panel de administración de WordPress
       - Navega a Plugins > Añadir nuevo.
       - Busca "Plugin Check" e instálalo, actívalo.
    
    2. Ejecuta una revisión de plugins:
       - En el panel de WordPress, ve al menú de Plugin Check.
       - Selecciona los plugins que deseas revisar y ejecuta el escaneo.
    
    3. Analiza los resultados del escaneo:
       - PCP analizará el código del plugin y proporcionará un informe, que incluye:
         - Cumplimiento de estándares de código: Qué tan bien el plugin se adhiere a los estándares de codificación de WordPress.
         - Problemas de seguridad: Posibles vulnerabilidades o código malicioso.
         - Problemas de rendimiento: El impacto en el rendimiento del sitio web.
         - Problemas de compatibilidad: Si el plugin es compatible con otros plugins y temas.
    
    4. Identifica plugins problemáticos:
       - Si el informe destaca vulnerabilidades de seguridad significativas, código malicioso o numerosas violaciones de estándares de codificación, es probable que el plugin sea "sospechoso".
       - Ten cuidado con los plugins que realizan solicitudes externas innecesarias o ejecutan consultas de base de datos excesivas.
    
    5. Resuelve los problemas:
       - Soluciona los problemas identificados actualizando o encontrando los problemas en las páginas de los plugins.
       - Evita usar plugins con problemas de seguridad graves. Encuentra plugins alternativos cuando sea necesario.
    
    **Gestión de Plugins:**
    1. Selección de Plugins:
       - Usa repositorios oficiales, revisa valoraciones y opiniones, verifica la credibilidad del desarrollador
       - No uses plugins desconocidos o no verificados
    
    2. Actualizaciones periódicas
       - Mantén los plugins actualizados para asegurarte de tener los últimos parches de seguridad.
    
    3. Desactivar y Eliminar Plugins No Utilizados
       - Incluso los plugins inactivos pueden suponer un riesgo de seguridad, así que elimínalos si no se usan.
       - Minimiza los plugins: Usa solo los esenciales
    
    
    ## 6. Asegúrate de que WordPress esté Configurado para Usar Solo HTTPS, Incluyendo el Administrador de WordPress
    Hoy en día, la mayoría de los sitios web están configurados para funcionar sobre SSL (HTTPS).
    Sin embargo, algunos servidores web aún pueden estar configurados erróneamente para manejar conexiones HTTP y HTTPS.
    Esto puede permitir el acceso a WordPress a través de ambos protocolos, lo que supone un riesgo de seguridad. WordPress, incluido el Administrador de WordPress, debe forzarse a usar exclusivamente HTTPS.
    
    **Auditoría:**
    - Verifica que WordPress, incluido el administrador de WordPress, esté configurado para ser accesible solo a través de HTTPS.
    - Comprueba la configuración de VirtualHost del servidor web para asegurarte de que no haya VirtualHosts HTTP configurados.
    
    **Remediación:**
    - Si es posible el acceso HTTP, primero revisa y modifica la configuración del servidor web.
    - Si el servidor tiene VirtualHosts HTTP, redirígelos a HTTPS o elimina los VirtualHosts HTTP.
    - Si es necesario, habilita la función "FORCE_SSL_ADMIN" para forzar el acceso HTTPS al Administrador de WordPress.
    
    **Pasos para Habilitar FORCE_SSL_ADMIN:**
    1. Accede a tu archivo wp-config.php usando el Administrador de Archivos o FTP. 
    2. Abre el archivo wp-config.php para editarlo. 
    3. Desplázate hasta la parte inferior del archivo (si usas el wp-config.php predeterminado). 
    4. Localiza la siguiente línea:
    `
    /* That’s all, stop editing! Happy publishing. */
    `
    5. Sobre esta línea, añade el siguiente código:
    `
    define('FORCE_SSL_ADMIN', true);`
    `
    6. Guarda los cambios y cierra el editor.
    Vuelve a tu panel de WordPress e inicia sesión de nuevo para asegurarte de que el Administrador de WordPress solo sea accesible a través de HTTPS.
    
    **Redirigir HTTP a HTTPS en el Servidor Web:**
    1. Para Apache:
        ```
        <VirtualHost *:80>
            ServerName yourwordpress.com
        
            RewriteEngine On
            RewriteCond %{HTTPS} off
            RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
        </VirtualHost>
        ```
    2. Para Nginx:
        ```
        server {
            listen 80;
            server_name yourwordpress.com;
        
            location / {
                return 301 https://$host$request_uri;
            }
        }
        ```
    Al asegurarte de que WordPress y el Administrador de WordPress solo sean accesibles a través de HTTPS, puedes mejorar significativamente la seguridad de tu sitio web, protegiendo datos y evitando accesos no autorizados.   
    
    ## 7. Asegúrate de que las Restricciones de Acceso por IP (ACL) estén Aplicadas
    Verifica que las restricciones de acceso por IP estén aplicadas
    
    Para operar WordPress de forma segura, es esencial aplicar restricciones de acceso por IP a ciertas URLs, incluido el Administrador de WordPress, para evitar que usuarios, computadoras y bots no deseados accedan. Esto implica permitir el acceso solo desde direcciones IP permitidas, como las IP de los administradores. Además, es necesario desactivar funciones no utilizadas para minimizar las superficies de ataque.
    
    Las URLs a asegurar incluyen el Administrador de WordPress, el registro de usuarios (wp-signup.php), la API REST JSON y la función XML-RPC.
    
    Esta guía de seguridad está dirigida a sitios web orientados a servicios como blogs corporativos, páginas de reclutamiento, sitios de marca y sitios promocionales donde la interacción del usuario es mínima y el contenido se exhibe principalmente.
    
    Al implementar restricciones de acceso por IP, puedes reducir significativamente el riesgo de acceso no autorizado y mejorar la seguridad general de tu sitio web.
    
    
    ### 7.1. Asegúrate de que las restricciones de acceso por IP estén aplicadas al administrador de WordPress.
    La ruta de acceso al administrador de WordPress es fija en forma de wp-login.php o /wp-admin, lo que facilita el acceso a usuarios no autorizados.
    Asegúrate de que se aplique una restricción de acceso por IP para evitar el acceso no autorizado a la página de administración.
    
    **Auditoría:**
    - Verifica que las restricciones de acceso por IP estén aplicadas para el administrador de WordPress.
    - En la mayoría de los casos, esto se configura en el servidor web (Apache, Nginx).
    
    **Remediación:**
    - Si las restricciones de acceso por IP no están aplicadas, impleméntalas.
    - A continuación se muestran métodos para aplicar restricciones de acceso por IP usando los servidores web Apache y Nginx.
    
    **Aplicar Restricción de Acceso por IP al Administrador de WordPress:**
    - /wp-admin, wp-login.php 
    
    1. Para Apache:
        ```
       # Files Directive 
        <Files "wp-login.php">
            Require ip 10.10.77.49  # Replace with your IP address
        </Files>
        
        # FilesMatch Directive
        <FilesMatch "^wp-login\.php$">
            Require all granted
        </FilesMatch>
    
       # Directory, Files Mixing Directive
        <Directory /www/vhosts/yourwordpress>
            Require all granted
            AllowOverride None
            <Files "wp-login.php">
                Require ip 10.10.77.49  # Replace with your IP address
            </Files>
        </Directory>
       
       # Location Directive
        <Location "/wp-admin">
            Require ip 10.10.77.49  # Replace with your IP address
        </Location>
        
        <Location "/wp-login.php">
            Require ip 10.10.77.49  # Replace with your IP address
        </Location>
        ```
    2. Para Nginx:
        ```
        location /wp-admin {
            allow 10.10.77.49;  # Replace with your IP address
            deny all;
        }
        
        location ~* \wp-login.php {
            allow 10.10.77.49;  # Replace with your IP address
            deny all;
        }
        ```
    
    
    ### 7.2. Restringe el Acceso por IP o Desactiva la Función de la API REST JSON
    WordPress proporciona dos funcionalidades REST (xmlrpc, json rest api) y están habilitadas por defecto al instalar WordPress. 
    La API REST proporciona endpoints para los tipos de datos de WordPress, permitiendo la interacción remota con el sitio para tareas como consultar entradas o datos, modificar recursos, editar y eliminar.
    
    Para la mayoría de los WordPress, la función de la API REST no es esencial. 
    Habilitarla puede exponer WordPress a ataques DDoS y podría resultar en consumo de recursos y ralentización del sitio.
    
    **Auditoría:**
    - Verifica que la función de la API REST JSON esté habilitada. (Por defecto: Habilitada)```
    # curl -i -k https://yourwordpress.com/wp-json
    
    (response)
    HTTP/1.1 200 OK
    cache-control: no-cache, no-store, must-revalidate, max-age=0
    content-type: text/html; charset=UTF-8
    ...
    Server: Apache
    
    {"name":"mywordress","description":"".......................
    

    Remediación:

    • Si la API REST no es necesaria, desactívala. Es posible deshabilitarla mediante la instalación de un plugin simple.
    • Si se utiliza la API REST, aplica restricciones de acceso por IP para permitir el acceso únicamente desde IPs autorizadas.

    Instalar el plugin "Disable REST API" y activarlo:

    1. Ve al panel de administración de WordPress
    2. Navega a Plugins > Añadir nuevo.
    3. Busca "Disable REST API" e instálalo, actívalo.
    4. Una vez activado, el plugin debería deshabilitar automáticamente la funcionalidad de la API REST en tu sitio WordPress.

    Restricción de acceso por IP para la API REST JSON:

    1. Para Apache:
      root@kitploit:~
      <Location "/wp-json">
          Require ip 10.10.77.49  # Reemplaza con tu dirección IP
      </Location>
      
    2. Para Nginx:
      root@kitploit:~
      location ~ ^/wp-json/ {
          allow 10.10.77.49;   # Reemplaza con tu dirección IP permitida
          deny all;
      }
      

    7.3. Deshabilitar la función de la API XML-RPC

    De manera similar a la API REST JSON, es recomendable deshabilitar la API XML-RPC, ya que no es necesaria para la mayoría de las instalaciones de WordPress.

    Si la API REST es necesaria, se recomienda utilizar la API REST JSON en su lugar.

    XML-RPC tiene dos debilidades principales:

    Ataques de fuerza bruta:

    • Los atacantes intentan iniciar sesión en WordPress usando xmlrpc.php con tantas combinaciones de nombre de usuario/contraseña como puedan ingresar.
    • Un método dentro de xmlrpc.php permite al atacante usar un solo comando (system.multicall) para adivinar cientos de contraseñas.

    Ataques de denegación de servicio a través de Pingback:

    • En 2013, los atacantes enviaron solicitudes de Pingback a través de xmlrpc.php de aproximadamente 2500 sitios WordPress.
    • Esto le da a cualquier atacante un conjunto prácticamente ilimitado de direcciones IP para distribuir un ataque de denegación de servicio a través de una red de más de 100 millones de sitios WordPress, sin tener que comprometerlos.

    Si XML-RPC está habilitado, aún puede ser explotado para tales ataques.

    Auditoría:

    • Verificar que la función de la API XML-RPC esté habilitada. (Por defecto: Habilitada)```

    curl -i -k https://yourwordpress.com/xmlrpc.php

    (response) HTTP/1.1 405 Method Not Allowed Date: Mon, 25 Jun 2018 08:30:24 GMT Server: Apache Allow: POST Content-Length: 42 Content-Type: text/plain; charset=UTF-8

    XML-RPC server accepts POST requests only.

    root@kitploit:~
    **Remediación:**
    - Desactivar la función XML-RPC usando un plugin
    
    **Instalar el plugin "Disable XML-RPC-API", Activar:**
    1. Ve al panel de administración de WordPress.
    2. Navega a Plugins > Añadir nuevo.
    3. Busca "[Disable XML-RPC-API](https://wordpress.org/plugins/disable-xml-rpc-api/)" e instálalo, actívalo.
    4. XML-RPC-API ahora está desactivado.
    
    **Acerca de los ataques de pingbacks XML-RPC:**
    
    1. Verificar que XML-RPC está habilitado
        ```
        # curl -i -k https://yourwordpress.com/xmlrpc.php
        
        (response)
        HTTP/1.1 405 Method Not Allowed
        Date: Mon, 25 Jun 2018 08:30:24 GMT
        Server: Apache
        Allow: POST
        Content-Length: 42
        Content-Type: text/plain; charset=UTF-8
         
         
        XML-RPC server accepts POST requests only.
        ```
    2. Buscar métodos XML-RPC disponibles
        ```
        (request)
        POST /xmlrpc.php HTTP/1.1
        Host: yourwordpress.com
        Content-Length: 135
        
        <?xml version="1.0" encoding="utf-8"?>
        <methodCall>
            <methodName>system.listMethods</methodName>
            <params></params>
        </methodCall>
        
        
        (response)
        HTTP/1.1 200 OK
        cache-control: no-cache, no-store, must-revalidate, max-age=0
        ...
        Server: Apache
        Content-Length: 4272
        Content-Type: text/xml; charset=UTF-8
        
        <?xml version="1.0" encoding="UTF-8"?>
        <methodResponse>
            <params>
                <param>
                    <value>
                        <array><data>
                            <value><string>system.multicall</string></value>
                            <value><string>system.listMethods</string></value>
                            <value><string>system.getCapabilities</string></value>
                            <value><string>demo.addTwoNumbers</string></value>
                            <value><string>demo.sayHello</string></value>
                            <value><string>pingback.extensions.getPingbacks</string></value>
                            <value><string>pingback.ping</string></value>
                            <value><string>mt.publishPost</string></value>
                            ...
                            <value><string>wp.getUsersBlogs</string></value>
                        </data></array>
                    </value>
                </param>
            </params>
        </methodResponse>
        
        ```
    3. Realizar pingbacks
        - El éxito de un ataque de pingback y los métodos específicos de verificación no se describen.
        ```
        (request)
        POST /xmlrpc.php HTTP/1.1
        Host: yourwordpress.com
        Content-Length: 303
        
        <?xml version="1.0" encoding="UTF-8"?>
            <methodCall>
            <methodName>pingback.ping</methodName>
                <params>
                    <param>
                        <value><string>call-back url for pingback result</string></value>
                    </param>
                    <param>
                        <value><string>https://yourwordpress.com/</string></value>
                </param>
            </params>
        </methodCall>
        
        
        (response)
        HTTP/1.1 200 OK
        ...
        Server: Apache
        Content-Length: 370
        Content-Type: text/xml; charset=UTF-8
        
        <?xml version="1.0" encoding="UTF-8"?>
        <methodResponse>
          <fault>
            <value>
              <struct>
                <member>
                  <name>faultCode</name>
                  <value><int>0</int></value>
                </member>
                <member>
                  <name>faultString</name>
                  <value><string></string></value>
                </member>
              </struct>
            </value>
          </fault>
        </methodResponse>
        ```
    
    
    ### 7.4. Deshabilitar WP-Cron o restringir la función
    En WordPress, WP-Cron (wp-cron.php) se utiliza para automatizar tareas como la publicación programada de entradas, las comprobaciones de actualizaciones de plugins/temas y el envío de correos de notificación.
    
    WP-Cron funciona esencialmente revisando la lista de tareas programadas cada vez que se carga una página.
    El problema surge cuando hay una carga pesada de páginas.
    
    Como las tareas de WP-Cron se realizan con cada carga de página, múltiples accesos repetidos resultan en invocaciones correspondientes de WP-Cron. En consecuencia, los recursos del sistema pueden escasear, causando que el sitio se vuelva lento o incluso se detenga.
    Esto es una ocurrencia real y se explota frecuentemente en ataques de vulnerabilidad dirigidos a WordPress.
    
    Si WP-Cron no es necesario, es recomendable desactivarlo.
    Si es necesario, restringir el acceso solo a hosts locales.
    
    
    **Auditoría:**
    - Verificar que WP-Cron está habilitado. (Predeterminado: Habilitado)```
    # curl -i -k https://yourwordpress.com/wp-cron.php
    
    (response)
    HTTP/1.1 200 ok
    Date: Mon, 25 Jun 2018 08:30:24 GMT
    Server: Apache
    Allow: POST
    Content-Length: 42
    Content-Type: text/plain; charset=UTF-8
    

    Remediación:

    • Deshabilitar WP-Cron si no se utiliza.
    • Si se utiliza, aplicar una de las siguientes opciones adecuadamente:
      1. Activar "ALTERNATE_WP_CRON" y restringir el acceso por IP a wp-cron.php.
      2. Usar cron del sistema (crontab) u otros métodos alternativos para la ejecución de tareas cron.

    Pasos para deshabilitar WP-Cron:

    1. Accede a tu archivo wp-config.php usando el Administrador de Archivos o FTP.
    2. Abre el archivo wp-config.php para editarlo.
    3. Desplázate hasta la parte inferior del archivo (si usas el wp-config.php por defecto).
    4. Localiza la siguiente línea: /* That’s all, stop editing! Happy publishing. */
    5. Encima de esta línea, añade el siguiente código: define('DISABLE_WP_CRON', true);
    6. Guarda los cambios y cierra el editor.
    7. Aplica restricciones de acceso por IP usando los servidores web Apache y Nginx.
      1. Para Apache:
        root@kitploit:~
        # Files Directive 
        <Files "wp-cron.php">
            Require ip 127.0.0.1  # localhost only
        </Files>
        
        # FilesMatch Directive
        <FilesMatch "^wp-cron\.php$">
            Require ip 127.0.0.1  # localhost only
        </FilesMatch>
        
        # Location Directive
        <Location "/wp-cron.php">
            Require ip 127.0.0.1  # localhost only
        </Location>
        
      2. Para Nginx:
        root@kitploit:~
         location = /wp-cron.php {
             allow 127.0.0.1;
             deny all;
             access_log off;
             log_not_found off;
         }
        

    Pasos para activar "ALTERNATE_WP_CRON":

    1. Accede a tu archivo wp-config.php usando el Administrador de Archivos o FTP.
    2. Abre el archivo wp-config.php para editarlo.
    3. Desplázate hasta la parte inferior del archivo (si usas el wp-config.php por defecto).
    4. Localiza la siguiente línea: /* That’s all, stop editing! Happy publishing. */
    5. Encima de esta línea, añade el siguiente código: define( 'ALTERNATE_WP_CRON', true );
    6. Guarda los cambios y cierra el editor.
    7. Aplica restricciones de acceso por IP usando los servidores web Apache y Nginx.
      1. Para Apache:
        root@kitploit:~
        # Files Directive 
        <Files "wp-cron.php">
            Require ip 127.0.0.1  # localhost only
        </Files>
        
        # FilesMatch Directive
        <FilesMatch "^wp-cron\.php$">
            Require ip 127.0.0.1  # localhost only
        </FilesMatch>
        
        # Location Directive
        <Location "/wp-cron.php">
            Require ip 127.0.0.1  # localhost only
        </Location>
        
      2. Para Nginx:
        root@kitploit:~
         location = /wp-cron.php {
             allow 127.0.0.1;
             deny all;
             access_log off;
             log_not_found off;
         }
        

    Ejemplo: Usando cron del sistema (crontab):

    • Antes de aplicar, deshabilita WP-Cron primero.```

    vim /etc/crontab

    .. ... */10 * * * * curl http://yourwordpress.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

    */10 * * * * cd /var/www/yourwordpress.com/htdocs; php /var/www/yourwordpress.com/htdocs/wp-cron.php?doing_wp_cron > /dev/null 2>&1

    Also can use WP-Cli

    */10 * * * * cd /var/www/example.com/htdocs; wp cron event run --due-now > /dev/null 2>&1

    root@kitploit:~
    **Acerca de realizar un ataque DoS usando wp-cron.php:**
    - Enviar un volumen extenso de solicitudes a wp-cron.php
    - Esto provoca que el script consuma una cantidad excesiva de recursos, eventualmente sobrecargando el servidor
    ![7.4.1!](https://assets.kitploit.com/production/public/readmes/6586/b1647fd6883b8d7b3178e7f042290fada6614e9de11a4e6e256f435902b12633.png)
    ![7.4.2!](https://assets.kitploit.com/production/public/readmes/6586/07d6a5d1794a3ba03177b78f63631eb5fb8f8f6092d6156965535847636d2769.png)
    
    ## 8. Configuración del Sistema para un WordPress Seguro.
    Garantizar el funcionamiento seguro de WordPress requiere una configuración adecuada del servidor web y el fortalecimiento de los componentes del backend.
    Aquí hay varios elementos esenciales que deben verificarse e implementarse.
    
    ### 8.1. Asegurar el uso de versiones de WordPress y PHP que no estén al final de su vida útil (EOL)
    Para mantener una instalación segura de WordPress, es esencial utilizar versiones de WordPress y PHP que no estén al final de su vida útil (EOL).
    Las versiones EOL ya no reciben soporte ni actualizaciones de seguridad, lo que deja su sitio web vulnerable a problemas de seguridad sin parches.
    
    El uso de versiones compatibles garantiza que cualquier vulnerabilidad descubierta sea abordada rápidamente, protegiendo su sitio de posibles ataques.
    Esto es lo que necesita hacer para verificar y actualizar sus versiones de WordPress y PHP:
    
    **Auditoría:**
    - Verifique que sus versiones actuales de WordPress y PHP no sean EOL.
    
    **Remediación:**
    - Instale y ejecute versiones de WordPress y PHP que no sean EOL.
    - A partir de mayo de 2024, la versión compatible de WordPress es 6.5 y superiores. Las versiones compatibles de PHP son 8.1, 8.2 y 8.3.
    - Si utiliza un servicio de alojamiento web, aproveche sus funciones de cambio de versión para asegurarse de ejecutar versiones compatibles tanto de WordPress como de PHP.
    
    **Estado EOL a partir de mayo de 2024**
     1. PHP: [supported-versions](https://www.php.net/supported-versions.php)
        - Versiones actualmente compatibles: 8.1, 8.2, 8.3
     2. WordPress: [current-releases](https://wordpress.org/download/releases/)
        - Versiones actualmente compatibles: serie 6.5
    
    **Ejemplo: PHP en RockyLinux 8.5**
    - En RockyLinux 8.5, las versiones predeterminadas de PHP disponibles son 7.2, 7.3 y 7.4.
        ```
        # dnf module list php
        Rocky Linux 8 - AppStream
        Name         Stream          Profiles                           Summary                       
        php          7.2 [d]         common [d], devel, minimal         PHP scripting language        
        php          7.3             common [d], devel, minimal         PHP scripting language        
        php          7.4             common [d], devel, minimal         PHP scripting language        
        
        Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
        
        # dnf module enable php:7.4
        ==============================================================================================
         Package               Architecture         Version               Repository             Size
        ==============================================================================================
        Enabling module streams:
         httpd                                      2.4                                              
         php                                        7.4                                              
        
        Transaction Summary
        ==============================================================================================
        
        Is this ok [y/N]: y
        Complete!
        ```
    - PHP 7 ya ha llegado al final de su vida útil (EOL); se recomienda actualizar a PHP 8.
    - PHP 8 se puede instalar desde el repositorio REMI.
    - Aquí hay un ejemplo de cómo habilitar e instalar PHP 8.2 usando REMI:
        ```
        # Install PHP 8.2 in Rocky Linux 8
        
        # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
        # dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
        # dnf -y install yum-utils
        # dnf module reset php
        # dnf module install php:remi-8.2
        Last metadata expiration check: 0:00:39 ago on Tue 13 Dec 2022 07:19:26 AM UTC.
        Dependencies resolved.
        =======================================================================================================================================
         Package                       Architecture        Version                                             Repository                 Size
        =======================================================================================================================================
        Installing group/module packages:
         php-cli                       x86_64              8.2.0-1.el8.remi                                    remi-modular              5.4 M
         php-common                    x86_64              8.2.0-1.el8.remi                                    remi-modular              1.3 M
         php-fpm                       x86_64              8.2.0-1.el8.remi                                    remi-modular              1.9 M
         php-mbstring                  x86_64              8.2.0-1.el8.remi                                    remi-modular              574 k
         php-xml                       x86_64              8.2.0-1.el8.remi                                    remi-modular              254 k
        Installing dependencies:
         httpd-filesystem              noarch              2.4.37-51.module+el8.7.0+1059+126e9251              appstream                  41 k
         libxslt                       x86_64              1.1.32-6.el8                                        baseos                    249 k
         oniguruma5php                 x86_64              6.9.8-1.el8.remi                                    remi-safe                 212 k
        Installing weak dependencies:
         nginx-filesystem              noarch              1:1.14.1-9.module+el8.4.0+542+81547229              appstream                  23 k
        Installing module profiles:
         php/common
        Enabling module streams:
         httpd                                             2.4
         nginx                                             1.14
         php                                               remi-8.2
        
        Transaction Summary
        =======================================================================================================================================
        Install  9 Packages
        
        # dnf update
        # dnf install php
        Last metadata expiration check: 0:00:23 ago on Tue 13 Dec 2022 07:29:55 AM UTC.
        Dependencies resolved.
        =======================================================================================================================================
         Package                       Architecture       Version                                               Repository                Size
        =======================================================================================================================================
        Installing:
         php                           x86_64             8.2.0-1.el8.remi                                      remi-modular             1.8 M
        Installing dependencies:
         apr                           x86_64             1.6.3-12.el8                                          appstream                128 k
         apr-util                      x86_64             1.6.1-6.el8.1                                         appstream                104 k
         httpd                         x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                1.4 M
         httpd-tools                   x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                108 k
         libsodium                     x86_64             1.0.18-2.el8                                          epel                     162 k
         mailcap                       noarch             2.1.48-3.el8                                          baseos                    38 k
         mod_http2                     x86_64             1.15.7-5.module+el8.6.0+823+f143cee1                  appstream                153 k
         rocky-logos-httpd             noarch             86.3-1.el8                                            baseos                    24 k
        Installing weak dependencies:
         apr-util-bdb                  x86_64             1.6.1-6.el8.1                                         appstream                 23 k
         apr-util-openssl              x86_64             1.6.1-6.el8.1                                         appstream                 26 k
         php-opcache                   x86_64             8.2.0-1.el8.remi                                      remi-modular             633 k
         php-pdo                       x86_64             8.2.0-1.el8.remi                                      remi-modular             166 k
         php-sodium                    x86_64             8.2.0-1.el8.remi                                      remi-modular             105 k
        
        Transaction Summary
        =======================================================================================================================================
        Install  14 Packages
        
        Total download size: 4.8 M
        Installed size: 14 M
        Is this ok [y/N]: y
        
        # php -v
        PHP 8.2.0 (cli) (built: Dec  6 2022 14:26:47) (NTS gcc x86_64)
        Copyright (c) The PHP Group
        Zend Engine v4.2.0, Copyright (c) Zend Technologies
            with Zend OPcache v8.2.0, Copyright (c), by Zend Technologies
        ```
    **Nota:**
    - Para obtener instrucciones detalladas sobre cómo instalar PHP desde el repositorio REMI: [rpms.remirepo.net](https://rpms.remirepo.net/)
    - Documentación sobre compatibilidad de WordPress y PHP: [php-compatibility-and-wordpress-versions](https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/)
    
    ### 8.2. Asegurar que Solo las Extensiones de PHP Necesarias para WordPress Estén Habilitadas
    Asegúrese de que solo las extensiones de PHP necesarias para su sitio de WordPress estén habilitadas.
    Las extensiones innecesarias pueden aumentar la superficie de ataque de su sitio web y pueden exponer WordPress a vulnerabilidades de seguridad.
    
    Al habilitar solo las extensiones requeridas, puede minimizar los riesgos potenciales y mejorar la seguridad general.
    
    A continuación se indican las necesarias para que un sitio de WordPress funcione correctamente. **(No es una lista con fines de fortalecimiento de seguridad)**
    
    | Extensión | Descripción                                                                                                                                                                                                                                        |
    |-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | json      | Se utiliza para la comunicación con otros servidores y el procesamiento de datos en formato JSON.                                                                                                                                                     |
    | mysqli    | Se conecta a MySQL para interacciones con la base de datos.                                                                                                                                                                                       |
    | curl      | Realiza operaciones de solicitudes remotas.                                                                                                                                                                                                        |
    | dom       | Se utiliza para validar el contenido de los widgets de texto y para configurar automáticamente IIS7+.                                                                                                                                             |
    | exif      | Trabaja con metadatos almacenados en imágenes.                                                                                                                                                                                                      |
    | fileinfo  | Se utiliza para detectar el tipo MIME de las cargas de archivos.                                                                                                                                                                                    |
    | hash      | Se utiliza para hashing, incluyendo contraseñas y paquetes de actualización.                                                                                                                                                                       |
    | igbinary  | Aumenta el rendimiento como reemplazo directo del serializador PHP estándar.                                                                                                                                                                      |
    | imagick   | Proporciona una mejor calidad de imagen para las cargas de medios. Consulte WP_Image_Editor para más detalles. Redimensionamiento de imágenes más inteligente (para imágenes más pequeñas) y soporte de miniaturas PDF, cuando Ghost Script también está disponible. |
    | intl      | Habilita operaciones sensibles a la configuración regional, incluyendo pero no limitado a formato, transliteración, conversión de codificación, operaciones de calendario, cotejo conforme, localización de límites de texto y trabajo con identificadores de configuración regional, zonas horarias y grafemas. |
    | mbstring  | Se utiliza para manejar correctamente texto UTF8.                                                                                                                                                                                                 |
    | openssl   | Conexiones basadas en SSL a otros hosts.                                                                                                                                                                                                            |
    | pcre      | Aumenta el rendimiento de la coincidencia de patrones en búsquedas de código.                                                                                                                                                                    |
    | xml       | Se utiliza para el análisis XML, como el de un sitio de terceros.                                                                                                                                                                                  |
    | zip       | Se utiliza para descomprimir plugins, temas y paquetes de actualización de WordPress.                                                                                                                                                              |
    | bc        | Para matemáticas de precisión arbitraria, que admite números de cualquier tamaño y precisión de hasta 2,147,483,647 dígitos decimales.                                                                                                            |
    | filter    | Se utiliza para filtrar de forma segura la entrada del usuario.                                                                                                                                                                                    |
    | image     | Si Imagick no está instalado, se utiliza la Biblioteca de Gráficos GD como un reemplazo funcionalmente limitado para la manipulación de imágenes.                                                                                                |
    | iconv     | Se utiliza para convertir entre conjuntos de caracteres.                                                                                                                                                                                            |
    | shmop     | Shmop es un conjunto de funciones fáciles de usar que permite a PHP leer, escribir, crear y eliminar segmentos de memoria compartida de Unix.                                                                                                       |
    | simplexml | Se utiliza para el análisis XML.                                                                                                                                                                                                                    |
    | sodium    | Valida firmas y proporciona bytes aleatorios seguros.                                                                                                                                                                                          |
    | xmlreader | Se utiliza para el análisis XML.                                                                                                                                                                                                                    |
    | zlib      | Compresión y descompresión Gzip.                                                                                                                                                                                                                    |
    
    Las extensiones esenciales se pueden encontrar aquí: [WordPress Hosting Handbook: PHP Extensions](https://make.wordpress.org/hosting/handbook/server-environment/#php-extensions)
    
    **Auditoría:**
    - Verifique que solo las extensiones de PHP necesarias para su sitio de WordPress estén habilitadas.
    
    **Remediación:**
    - Elimine cualquier extensión innecesaria. A veces, las extensiones se instalan junto con los plugins, que pueden no ser necesarias para su sitio.
    - Para verificar las extensiones de PHP actualmente habilitadas, puede revisar el archivo **php.ini** o usar la función **phpinfo()** para listar todas las extensiones activas.
    
    ![8.2!](https://assets.kitploit.com/production/public/readmes/6586/1e270a242227b8dc8fa965765c69b7927b170de108acdbe1fad91455e484e615.png)
    
    - Ciertas extensiones, si no son necesarias, deben deshabilitarse para evitar posibles problemas de seguridad.
    - Por ejemplo, extensiones como exif, fileinfo, imap, soap, pdo_sqlite y opcache podrían ser explotadas si se dejan habilitadas sin un uso adecuado.
    - Si está utilizando un servicio de alojamiento web, muchos proveedores ofrecen interfaces fáciles de usar para cambiar la configuración de PHP, incluyendo habilitar o deshabilitar extensiones de PHP. Usando estas funciones, puede gestionar las extensiones de manera efectiva.
    
    ### 8.3. Asegurar la Seguridad de los Plugins con Funciones de Carga de Archivos
    Los plugins con capacidades de carga de archivos pueden ser un riesgo de seguridad significativo si no están debidamente protegidos. Las vulnerabilidades en las funciones de carga de archivos pueden permitir a los atacantes cargar webshells, lo que potencialmente lleva a un compromiso total del sistema. Por lo tanto, es crucial asegurarse de que cualquier funcionalidad de carga de archivos incluya mecanismos de validación y saneamiento.
    
    ¿Por qué es esto importante?
    1. Validación de extensión:
       - El servidor debe validar las extensiones de archivo contra una lista blanca de tipos permitidos para evitar la carga de archivos maliciosos.
    
    2. Verificación de tipo MIME:
       - Se debe verificar el tipo MIME del archivo para asegurar que coincida con el tipo esperado, agregando una capa adicional de seguridad.
    
    3. Restricciones de ruta de carga:
       - Asegúrese de que no haya rutas expuestas que permitan el acceso directo a archivos cargados sin validación.
    
    Las vulnerabilidades de carga de archivos son particularmente peligrosas porque proporcionan una ruta directa para que los atacantes carguen código ejecutable y ejecuten comandos arbitrarios. Las vulnerabilidades de carga de archivos suelen ser más fáciles de identificar y explotar en comparación con otras fallas de seguridad como la inyección SQL.
    
    **Auditoría:**
    - Identifique los plugins con funcionalidad de carga de archivos en su sitio de WordPress.
    - Verifique que estos plugins implementen comprobaciones de validación adecuadas para los archivos cargados, incluyendo la validación de extensión y tipo MIME.
    
    **Remediación:**
    - Si un plugin con funcionalidad de carga de archivos carece de una validación adecuada, mejore su seguridad o elimine el plugin.
    - A continuación se muestran ejemplos de plugins populares de WordPress con funciones de carga de archivos y cómo manejan la validación de archivos.
    
    **Ejemplo: Plugins populares de WordPress con manejo de carga de archivos**
    
    1. Contact Form 7
       - Contact Form 7 es uno de los plugins de formularios más utilizados en WordPress. Incluye funcionalidad básica de carga de archivos con validación de extensión y tipo MIME.**Código para extensiones permitidas y verificación de tipo MIME:**
    

    function wpcf7_allowed_file_extensions() { // Default allowed file extensions $allowed_file_extensions = array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'rtf', 'html', 'zip' ); return $allowed_file_extensions; }

    function wpcf7_handle_upload( $file ) { $allowed_mime_types = wpcf7_allowed_file_extensions(); $file_type = wp_check_filetype( $file['name'] );

    root@kitploit:~
     // Check if the file type is allowed
     if ( ! in_array( $file_type['ext'], $allowed_mime_types ) ) {
         return new WP_Error( 'wpcf7_upload_failed', __( 'File type is not allowed.', 'contact-form-7' ) );
     }
    
     // Handle the file upload
     $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
    
     // Check if the upload was successful
     if ( isset( $upload['error'] ) ) {
         return new WP_Error( 'wpcf7_upload_failed', $upload['error'] );
     }
    
     return $upload;
    

    }

    root@kitploit:~
    En Contact Form 7, la función `wpcf7_allowed_file_extensions()` devuelve una lista de extensiones de archivo permitidas, y la función `wpcf7_handle_upload()` verifica si la extensión del archivo está en esta lista antes de proceder con la carga.
    
    2. WPForms
       - WPForms maneja las cargas de archivos verificando los tipos de archivo permitidos.
    
       **Código de ejemplo para WPForms:**
    
    root@kitploit:~
    function wpforms_get_file_types() {
     // Return an array of allowed file types
     return array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
    

    }

    function wpforms_process_file_upload( $file ) { $allowed_file_types = wpforms_get_file_types(); $file_type = wp_check_filetype( $file['name'] );

    root@kitploit:~
     if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
         return new WP_Error( 'wpforms_upload_failed', __( 'File type is not allowed.', 'wpforms' ) );
     }
    
     $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
    
     if ( isset( $upload['error'] ) ) {
         return new WP_Error( 'wpforms_upload_failed', $upload['error'] );
     }
    
     return $upload;
    

    }

    root@kitploit:~
    
    3. WooCommerce
      - WooCommerce también define y verifica las extensiones de archivo permitidas directamente en su código de manejo de cargas.
    
      **Código de ejemplo para WooCommerce:**
       ```
       function woocommerce_handle_upload( $file ) {
           $allowed_file_types = array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
           $file_type = wp_check_filetype( $file['name'] );
    
           if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
               return new WP_Error( 'woocommerce_upload_failed', __( 'File type is not allowed.', 'woocommerce' ) );
           }
    
           $upload = wp_handle_upload( $file, array( 'test_form' => false ) );
    
           if ( isset( $upload['error'] ) ) {
               return new WP_Error( 'woocommerce_upload_failed', $upload['error'] );
           }
    
           return $upload;
       }
       ```
    
    **Ejemplo: Plugin de carga de archivos malicioso**
    - Un plugin malicioso puede parecer inocente pero explotar la extensión fileinfo para eludir las verificaciones de seguridad:
       ```
       <?php
       /*
       Plugin Name: Simple Malicious Upload
       Description: A plugin with hidden malicious file upload capability.
       Version: 1.0
       */
       
       function simple_file_upload_menu() {
           add_menu_page('File Upload', 'File Upload', 'manage_options', 'file-upload', 'simple_file_upload_page');
       }
       
       add_action('admin_menu', 'simple_file_upload_menu');
       
       function simple_file_upload_page() {
           ?>
           <h1>File Upload</h1>
           <form method="post" enctype="multipart/form-data">
               <input type="file" name="uploaded_file" />
               <input type="submit" name="upload_file" value="Upload" />
           </form>
           <?php
       
           if (isset($_POST['upload_file'])) {
               simple_handle_file_upload();
           }
       }
       
       function simple_handle_file_upload() {
           if (!empty($_FILES['uploaded_file']['tmp_name'])) {
               $file_tmp = $_FILES['uploaded_file']['tmp_name'];
               $file_name = basename($_FILES['uploaded_file']['name']);
       
               // Using fileinfo to check MIME type
               $finfo = finfo_open(FILEINFO_MIME_TYPE);
               $mime_type = finfo_file($finfo, $file_tmp);
               finfo_close($finfo);
       
               // Insecure handling: allows any PHP files to be uploaded
               if ($mime_type === 'text/plain' || $mime_type === 'application/x-php') {
                   $upload_dir = wp_upload_dir();
                   $upload_file = $upload_dir['path'] . '/' . $file_name;
       
                   // Move the uploaded file to the uploads directory
                   if (move_uploaded_file($file_tmp, $upload_file)) {
                       echo "File uploaded successfully.";
                   } else {
                       echo "File upload failed.";
                   }
               } else {
                   echo "Invalid file type.";
               }
           }
       }
       ?>
       ```
    **Explicación del Exploit:**
    - El plugin malicioso permite cargar archivos PHP si su tipo MIME es `application/x-php.`
    - Un atacante puede cargar un shell web PHP usando esta funcionalidad.
    - Una vez cargado, el atacante accede a la URL del archivo y ejecuta comandos arbitrarios.
    
    **Ejemplo: Código de Shell Web PHP**```
    <?php
    if (isset($_GET['cmd'])) {
       echo "<pre>";
       system($_GET['cmd']);
       echo "</pre>";
    }
    ?>
    

    Demostración del Ataque

    1. Subir el Web Shell:
      • El atacante sube webshell.php a través del formulario de carga del plugin.
    2. Acceder y Usar el Web Shell:
      • El atacante accede al web shell en http://yourwordpress.com/wp-content/uploads/webshell.php.
      • Al navegar a http://yourwordpress.com/wp-content/uploads/webshell.php?cmd=ls, el atacante puede ejecutar comandos arbitrarios.

    Nota:

    • El ejemplo tiene como objetivo explicar cómo se puede hacer un mal uso del plugin con funciones de carga de archivos.
    • Garantizar una validación y desinfección adecuadas puede prevenir una posible explotación y mantener la seguridad de tu sitio WordPress.
    • Los códigos de plugin anteriores son solo con fines educativos.

    8.4. Asegurarse de que las funciones y configuraciones de PHP estén correctamente configuradas

    Asegurarse de que las funciones y configuraciones de PHP estén correctamente configuradas puede mejorar significativamente la seguridad de tu sitio WordPress. Las configuraciones incorrectas pueden exponer tu sitio a diversas vulnerabilidades, incluyendo ejecución remota de código, divulgación de información y secuestro de sesiones. Es crucial endurecer PHP deshabilitando o configurando adecuadamente estas funciones.

    ¿Por qué es importante?

    1. Ejecución Remota de Código:

      • Configuraciones como allow_url_fopen y funciones como exec pueden habilitar la ejecución remota de código, lo que lleva a un posible compromiso del sistema.
    2. Divulgación de Información:

      • Opciones como display_errors y expose_php pueden filtrar información sensible sobre tu configuración del servidor, facilitando que los atacantes encuentren vulnerabilidades.
    3. Seguridad de Sesiones:

      • La gestión adecuada de las configuraciones de sesión, como session.cookie_secure y session.cookie_httponly, protege las cookies de sesión para que no sean accedidas mediante scripts del lado del cliente ni transmitidas a través de canales inseguros.

    Auditoría:

    • Verificar que las funciones y configuraciones inseguras de PHP listadas a continuación estén configuradas y endurecidas adecuadamente.

    Remediación:

    • Revisar las siguientes configuraciones y funciones de PHP, y ajustarlas para garantizar tanto la operación segura de tu sitio WordPress como su funcionalidad.
    1. allow_url_fopen:

      • Permite que las funciones abran y lean archivos a través de URL.
      • Cuando está habilitado, funciones como file_get_contents(), fopen(), include(), y require() pueden recuperar datos de ubicaciones remotas a través de FTP o HTTP.
      • WordPress y muchos plugins de WordPress pueden requerir allow_url_fopen para varias funciones.
      • Sin embargo, no es necesario mantener esta configuración habilitada en todo momento.
      • Es mejor habilitarla solo cuando sea necesario por razones de seguridad.
        root@kitploit:~
        ; (Opcional) Deshabilitar allow_url_fopen, si no es necesario
        
         allow_url_fopen = Off
        
    2. display_errors:

      • Determina si los errores de PHP deben imprimirse en la pantalla como parte de la salida.
      • Mostrar errores puede revelar información sensible sobre tu entorno de servidor y aplicación, que puede ser utilizada por atacantes para explotar vulnerabilidades.
        root@kitploit:~
        ; Deshabilitar que los errores de PHP se muestren en tu sitio web WordPress
        
        display_errors = Off
        
    3. expose_php:

      • Controla si PHP anuncia su presencia y versión en los encabezados HTTP.
      • Revelar esta información puede ayudar a los atacantes a identificar versiones vulnerables de PHP.
        root@kitploit:~
        ; Evitar exponer la versión de PHP en los encabezados de respuesta HTTP
        
        expose_php = Off
        session.cookie_secure
        
    4. session.cookie_secure:

      • Asegura que las cookies de sesión solo se transmitan a través de conexiones HTTPS seguras, protegiéndolas de ser interceptadas durante la transmisión.
        root@kitploit:~
        ; Asegurar que las cookies de sesión se envíen a través de HTTPS
        
        session.cookie_secure = On
        session.cookie_httponly
        
    5. session.cookie_httponly:

      • Hace que las cookies de sesión sean inaccesibles para JavaScript, mitigando el riesgo de ataques de cross-site scripting (XSS).
        root@kitploit:~
        ; Hacer que las cookies de sesión sean inaccesibles para JavaScript
        
        session.cookie_httponly = On
        
    6. open_basedir:

      • Restringe la capacidad de PHP para acceder a archivos dentro de directorios especificados.
      • Esto puede evitar que los atacantes accedan a archivos sensibles en el servidor.
        root@kitploit:~
        ; Restringir el acceso a archivos de PHP al directorio especificado
        open_basedir = "/ruta/a/la/raíz/de/tu/web"
        

      Ejemplo:

      • Si tu raíz web es /var/www/html, establece open_basedir de la siguiente manera:
        root@kitploit:~
        open_basedir = "/var/www/html:/tmp"
        
        Esta configuración permite que PHP acceda solo a los archivos dentro del directorio /var/www/html y al directorio temporal /tmp.
        
    7. disable_functions:

      • Funciones de PHP que son comúnmente explotadas en ataques.
      • Deshabilitar estas funciones puede mitigar el riesgo de varios tipos de ataques, incluyendo inyección de comandos y ejecución remota de código.
        root@kitploit:~
        ; Deshabilitar funciones peligrosas de PHP
        
        disable_functions = "system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail"
        

      Explicación de las Funciones Deshabilitadas:

      • system, exec, shell_exec, passthru:

        • Permiten la ejecución de comandos del sistema, lo que puede ser explotado para ataques de inyección de comandos.
      • mysql_list_dbs:

        • Recupera una lista de bases de datos de un servidor MySQL, lo que puede utilizarse para recopilar información para futuros ataques.
      • ini_alter:

        • Cambia la configuración de PHP en tiempo de ejecución, alterando potencialmente las configuraciones de seguridad.
      • dl:

        • Carga dinámicamente una extensión de PHP, lo que puede utilizarse para introducir código malicioso.
      • symlink, link:

        • Crean enlaces simbólicos o duros, que pueden ser explotados para manipular archivos y directorios de manera inapropiada.
      • chgrp:

        • Cambia la propiedad de grupo de un archivo, alterando potencialmente los permisos de acceso.
      • leak:

        • Se utiliza para probar fugas de memoria, pero puede ser explotado para consumir recursos del servidor.
      • popen:

        • Abre una tubería a un proceso, que puede ser explotada para la ejecución de comandos.
      • apache_child_terminate:

        • Termina un proceso de Apache, interrumpiendo potencialmente el servicio.
      • virtual:

    Ejemplo: A continuación se muestra una Lista de Funciones PHP Deshabilitadas en un WordPress Real``` system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail

    root@kitploit:~
    ### 8.5. Asegurar que el Servidor Web se Ejecute Como un Usuario No Root - Usuario y Grupo Únicos y Sin Privilegios para la Aplicación del Servidor
    En la mayoría de los casos, los servidores web se ejecutan como usuarios como "www-data" (Debian/Ubuntu) o "apache" (RHEL/CentOS).
    
    Estos usuarios son cuentas de servicio dedicadas sin privilegios especiales en el servidor y se utilizan para designar el usuario y grupo que asumirán los procesos trabajadores del servidor web.
    
    Si estos usuarios tienen privilegios de sistema o se están ejecutando como root, deben ser cambiados.
    
    **Auditoría:**
    - Verificar el usuario que ejecuta el proceso del servidor web. (Específicamente, es el proceso trabajador del servidor web.)
    
    1. Para Apache:
        ```
        # ps -ef | grep httpd
        root     2257     1  0 Apr08 ?        00:00:01 /usr/local/apache/bin/httpd -k start
        apache   5678  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
        apache   5679  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
        apache   5680  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
        apache   5681  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
        ```
    
    2. Para Nginx:
        ```
        # ps -ef | grep nginx
        root      626653       1  0 Apr08 ?        00:00:00 nginx: master process /usr/sbin/nginx
        nginx     626654  626653  0 Apr08 ?        00:00:00 nginx: worker process
        nginx     626655  626653  0 Apr08 ?        00:00:00 nginx: worker process
        nginx     626656  626653  0 Apr08 ?        00:00:00 nginx: worker process
        nginx     626657  626653  0 Apr08 ?        00:00:00 nginx: worker process
        ```
    
    **Remediación:**
    - El servidor web debe ejecutarse como una cuenta dedicada y sin privilegios.
    - En la mayoría de los casos, se utiliza una de estas cuentas de uso común como "www-data", "apache", "nginx", "nobody" o "daemon".
    
    1. Para Apache:
        ```
        # vim /etc/httpd/httpd.conf
        ..
        ...
        User www-data
        Group www-data
        ..
        ...
        ```
    
    2. Para Nginx:
        ```
        # vim /etc/nginx/nginx.conf
        ..
        ...
        user daemon;
        ```
    
    **Nota:**
    - Los usuarios de proceso del servidor web no deben tener privilegios de inicio de sesión de shell.  ```
      # cat /etc/passwd | grep -i www-data
      www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
    

    8.6. Asegúrate de que PHP-FPM se ejecute como un usuario no root - Usuario y grupo único y no privilegiado para la aplicación del servidor

    WordPress está construido con PHP, por lo que una configuración correcta del sistema es necesaria para ejecutar el código PHP adecuadamente.

    La ejecución del código PHP en WordPress es gestionada por PHP-FPM, un Gestor de Procesos FastCGI. Para garantizar el funcionamiento seguro de PHP-FPM, debe ejecutarse bajo una cuenta de servicio dedicada y no privilegiada.

    Generalmente, la cuenta del proceso del servidor web y la cuenta de PHP-FPM se configuran como la misma cuenta. Sin embargo, para una mayor seguridad, es mejor ejecutarlos bajo cuentas separadas.

    Aquí hay dos razones:

    1. Aislamiento de Procesos:

      • Ejecutar el servidor web y PHP-FPM bajo cuentas separadas aísla los procesos.
      • Esto reduce el riesgo de que un compromiso en un servicio afecte al otro.
      • Si un atacante obtiene acceso al proceso del servidor web, no necesariamente tendrá acceso a PHP-FPM, y viceversa.
    2. Principio de Mínimo Privilegio:

      • Al usar cuentas dedicadas y no privilegiadas para cada servicio, te adhieres al principio de mínimo privilegio.
      • Esto limita los permisos y el acceso que tiene cada servicio, minimizando el daño potencial de vulnerabilidades o brechas de seguridad.

    Auditoría:

    • Verifica la cuenta que ejecuta el proceso de PHP-FPM.```

    ps -ef | grep php-fpm

    root 1234 1 0 12:00 ? 00:00:01 php-fpm: master process (/etc/php-fpm.conf) php-fpm 5678 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5679 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5680 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5681 1234 0 12:00 ? 00:00:00 php-fpm: pool www

    root@kitploit:~
    **Mitigación:**
    - PHP-FPM debería ejecutarse como una cuenta dedicada no privilegiada.
    - En la mayoría de los casos, la cuenta utilizada es "php-fpm".
    
    **Cambiando la cuenta del proceso para PHP-FPM:**```
    # vim /etc/php-fpm.d/www.conf # Adjust the path based on your PHP version
    ...
    user = php-fpm
    group = php-fpm
    listen.owner = php-fpm 
    listen.group = php-fpm 
    

    La cuenta del proceso PHP-FPM no debería tener privilegios de inicio de sesión de shell.```

    cat /etc/passwd | grep php-fpm

    php-fpm❌999:999:PHP-FPM:/run/php:/usr/sbin/nologin

    root@kitploit:~
    **Nota:**
    - Usar cuentas de usuario diferentes para los procesos de PHP-FPM y los procesos del servidor web es preferible desde una perspectiva de seguridad.
    - Cuando se pregunte cuál es mejor para la seguridad, deben ser diferentes. Evite usar la misma cuenta de ejecución en este contexto.
    
    
    ### 8.7. Asegurar la Configuración Segura del Directorio de Inicio de WordPress
    
    Para operar un servidor web de forma segura, es crucial configurar adecuadamente la propiedad y los permisos del directorio de inicio de WordPress
    
    En la mayoría de los casos, la propiedad y los permisos de los archivos y directorios de WordPress se establecen para coincidir con la cuenta de proceso del servidor web. 
    Esta configuración permite que el servidor web acceda a los archivos en la raíz web y funcione sin errores.
    
    Sin embargo, esta configuración es insegura.
    
    Por ejemplo, si el proceso del servidor web es 'apache' y tanto el directorio raíz web como los archivos son propiedad de 'apache', podría provocar vulnerabilidades graves. 
    Los atacantes podrían explotar estas vulnerabilidades para obtener acceso no autorizado a archivos y directorios críticos dentro del directorio de inicio de WordPress.
    
    **Ejemplo común de vulnerabilidad:**
    - Si tanto la cuenta de proceso del servidor web como el directorio de inicio (raíz web) y los archivos son propiedad de 'apache':
    - En caso de vulnerabilidades en el sitio web y acceso externo al sistema (como webshell), los atacantes pueden realizar varias acciones dentro de la raíz web:
      1. Crear, modificar o eliminar archivos o directorios dentro de la raíz web.
      2. Manipular los registros de acceso web, incluyendo modificación, eliminación o creación. (excepto en algunos entornos)
      3. Puede obtener acceso a las cookies de sesión activas de usuarios conectados. (en entornos particularmente vulnerables)
    
    Para mitigar estos riesgos, es crucial ajustar adecuadamente la propiedad y los permisos del directorio de inicio de WordPress
    
    **Mitigación:**
    - Establecer el propietario del directorio de inicio (raíz web) y los archivos a 'root:root'. (Evite establecerlo igual que la cuenta de proceso del servidor web)
    - El UMASK predeterminado para directorios y archivos es 022. (Directorios: 755, Archivos: 644)
    - Para directorios que requieren acceso de escritura como la carga de archivos por el servicio web, establezca el propietario de esos directorios a la cuenta de proceso del servidor web.
    
    **Directorios que generalmente requieren permisos de escritura en WordPress:**```
    /wp-content/uploads
    /wp-content/cache
    /wp-content/wflogs (when using security plugins like Wordfence)
    /wp-content/upgrade (used during the WordPress upgrade process)
    

    Después de configurar la propiedad y los permisos del directorio raíz de acuerdo con las medidas de remediación anteriores, la salida del directorio raíz de WordPress es la siguiente:

    Ejemplo: Directorio raíz de WordPress``` drwxr-xr-x 5 root root 4096 May 27 2024 . drwxr-xr-x 3 root root 4096 May 27 2024 .. -rw-r--r-- 1 root root 418 May 27 2024 index.php -rw-r--r-- 1 root root 19935 May 27 2024 license.txt -rw-r--r-- 1 root root 7346 May 27 2024 readme.html -rw-r--r-- 1 root root 7106 May 27 2024 wp-activate.php drwxr-xr-x 9 root root 4096 May 27 2024 wp-admin -rw-r--r-- 1 root root 351 May 27 2024 wp-blog-header.php -rw-r--r-- 1 root root 2328 May 27 2024 wp-comments-post.php -rw-r--r-- 1 root root 4973 May 27 2024 wp-config-sample.php -rw-r--r-- 1 root root 2755 May 27 2024 wp-config.php drwxr-xr-x 8 root root 4096 May 27 2024 wp-content -rw-r--r-- 1 root root 3940 May 27 2024 wp-cron.php drwxr-xr-x 25 root root 12288 May 27 2024 wp-includes -rw-r--r-- 1 root root 2496 May 27 2024 wp-links-opml.php -rw-r--r-- 1 root root 3300 May 27 2024 wp-load.php -rw-r--r-- 1 root root 51556 May 27 2024 wp-login.php -rw-r--r-- 1 root root 8403 May 27 2024 wp-mail.php -rw-r--r-- 1 root root 24568 May 27 2024 wp-settings.php -rw-r--r-- 1 root root 30869 May 27 2024 wp-signup.php -rw-r--r-- 1 root root 4620 May 27 2024 wp-trackback.php -rw-r--r-- 1 root root 3065 May 27 2024 xmlrpc.php

    root@kitploit:~
    **En caso de que las cuentas de proceso de php-fpm y del servidor web sean diferentes (Permisos separados)**
    
    Si la cuenta de proceso del servidor web es "apache" y la cuenta de proceso de php-fpm es "php-fpm".
    
    Cambie los permisos de los directorios que requieren acceso de escritura en WordPress (por ejemplo, /wp-content/uploads).
    - Propietario: php-fpm
    - Grupo: apache
    - Permisos de directorio: 775 (755 si es necesario)
    
    **Estructura de archivos y directorios**
    
    Establezca los permisos de escritura para los directorios necesarios de modo que ambas cuentas, "php-fpm" y "apache", puedan escribir.```
    ex) /service/wordpress/www
    ├── index.php             (root:root, 644)
    ├── license.txt           (root:root, 644)
    ├── readme.html           (root:root, 644)
    ├── wp-activate.php       (root:root, 644)
    ├── wp-admin/             (root:root, 755)
    ├── wp-blog-header.php    (root:root, 644)
    ├── wp-comments-post.php  (root:root, 644)
    ├── wp-config-sample.php  (root:root, 644)
    ├── wp-config.php         (root:root, 644)
    ├── wp-content/           (root:root, 755)
    │   ├── plugins/          (root:root, 755)
    │   ├── themes/           (root:root, 755)
    │   ├── uploads/          (php-fpm:apache, 775)
    │   │   ├── 2024/         (php-fpm:apache, 775)
    │   │   └── ...           (php-fpm:apache, 775)
    │   └── ...               (root:root, 755)
    ├── wp-cron.php           (root:root, 644)
    ├── wp-includes/          (root:root, 755)
    ├── wp-links-opml.php     (root:root, 644)
    ├── wp-load.php           (root:root, 644)
    ├── wp-login.php          (root:root, 644)
    ├── wp-mail.php           (root:root, 644)
    ├── wp-settings.php       (root:root, 644)
    ├── wp-signup.php         (root:root, 644)
    ├── wp-trackback.php      (root:root, 644)
    └── xmlrpc.php            (root:root, 644)
    

    Resumen

    1. Cuenta del proceso worker del servidor web: "www-data" o "apache" o "nginx"
    2. Cuenta del proceso PHP-FPM: "php-fpm"
    3. Ajustes de directorios de WordPress:
      • Directorio principal:
        • Propietario: root:root
        • Permisos de directorio: 755
        • Permisos de archivo: 644
      • Directorios que requieren escritura
        • Propietario: "php-fpm:www-data"
        • Permisos de directorio: 775 (o 755 si es necesario)

    Configurándolo de esta manera, puedes separar los permisos del servidor web y PHP-FPM, aplicar correctamente la propiedad y los permisos del directorio principal, y mejorar la seguridad.

    Este método se aplica no solo a WordPress, sino a cualquier estructura de servidor web que sirva contenido web.

    8.8. Asegurar que la ejecución de PHP esté deshabilitada en directorios con permisos de escritura

    Asegurar que la ejecución de PHP esté deshabilitada en los directorios donde se puedan subir archivos es crucial para mantener un entorno seguro.

    Los directorios de subida con permisos de escritura son objetivos potenciales para que atacantes suban scripts maliciosos, como webshells, que pueden ejecutarse para comprometer el servidor.

    ¿Por qué es importante?

    1. Mitigar ataques de webshells:

      • Al evitar la ejecución de scripts PHP en directorios de subida, se mitiga el riesgo de ataques de webshells que pueden llevar a un compromiso total del servidor.
    2. Reducir la superficie de ataque:

      • Deshabilitar la ejecución de PHP en directorios donde se puedan escribir archivos reduce la superficie de ataque, dificultando que los atacantes exploten vulnerabilidades.
    3. Cumplimiento de las mejores prácticas de seguridad:

      • Garantizar permisos y configuraciones de ejecución adecuados se alinea con las mejores prácticas de seguridad, proporcionando una capa adicional de defensa.

    Auditoría:

    • Verificar que los directorios con permisos de escritura (por ejemplo, directorios de subida) estén configurados para evitar la ejecución de scripts PHP.

    Remediación:

    • Configurar tu servidor web (Apache o Nginx) para deshabilitar la ejecución de PHP en directorios con permisos de escritura, como el directorio /wp-content/uploads.

    Pasos de configuración

    1. Establecer que los archivos se descarguen en directorios de subida
      • Para Apache:
        root@kitploit:~
        <Location "/wp-content/uploads">
            SetHandler application/octet-stream
        </Location>
        
      • Para Nginx:
        root@kitploit:~
        location /wp-content/uploads {
            default_type application/octet-stream;
        }
        
    2. Deshabilitar la ejecución de PHP en directorios de subida
      • Para Apache:
        root@kitploit:~
        <Location "/wp-content/uploads">
            php_flag engine off
            # o alternativamente
            php_value engine 0
        </Location>
        
         <Location "/wp-content/uploads">
             <FilesMatch "\.php$">
                 SetHandler none
                 Require all denied
             </FilesMatch>
         </Location>
         
         <Directory "/var/www/html/yourwordpress/wp-content/uploads">
             # Deshabilitar la ejecución de PHP
             <FilesMatch "\.php$">
                 SetHandler none
                 Require all denied
             </FilesMatch>
         </Directory>
        
      • Para Nginx:
        root@kitploit:~
        location /wp-content/uploads {
            location ~ \.php$ {
                fastcgi_pass off;
            }
        }
        
         location /wp-content/uploads {
             location ~ \.php$ {
                 deny all;
             }
         }
        

    Estas configuraciones aseguran que incluso si se sube un archivo PHP al directorio /wp-content/uploads, no se pueda ejecutar, previniendo así posibles ataques.

    Explicación de las directivas de configuración

    1. SetHandler application/octet-stream:

      • Obliga a que los archivos se traten como flujos binarios, lo que provoca que se descarguen en lugar de ejecutarse.
    2. php_flag engine off / php_value engine 0:

      • Deshabilita el motor de PHP en el directorio especificado, evitando que los scripts PHP se ejecuten.
    3. SetHandler none:

      • Elimina el manejador para los archivos coincidentes, asegurando que no se procesen como PHP.

    Nota:

    • Las configuraciones anteriores no afectan la visualización de archivos de imagen.
    • Por ejemplo, un archivo de imagen en el directorio /wp-content/uploads seguirá siendo accesible y se mostrará correctamente usando una etiqueta :
      root@kitploit:~
      <img src="https://example.com/wp-content/uploads/image.jpg" alt="Imagen de ejemplo">
      
    Example Image

    Esto se puede lograr mediante una configuración adecuada de las directivas VirtualHost.

    En la mayoría de los casos, los servicios web se acceden a través de un nombre de dominio, como https://yourwordpress.com. El servidor web recibe esta solicitud y sirve el contenido apropiado. Para reforzar este comportamiento, necesitamos configurar el servidor web para que solo responda a solicitudes con la cabecera Host correcta.

    Riesgos de Seguridad Potenciales al Permitir el Acceso Basado en IP

    1. Enumeración de Servicios:
      • Los atacantes pueden usar direcciones IP para enumerar servicios que se ejecutan en el servidor, aumentando el riesgo de descubrir y explotar vulnerabilidades.
    2. Exposición de Información Sensible:
      • Servidores mal configurados podrían exponer directorios, archivos u otra información sensible al acceder vía IP, que no debería ser accesible públicamente.
    3. Evasión de Controles de Seguridad:
      • El acceso basado en IP podría eludir medidas de seguridad que solo se aplican para acceso basado en dominio, lo que potencialmente conduce a acceso no autorizado.

    Auditoría:

    • Verificar que el servidor web esté configurado para responder solo a solicitudes basadas en dominio y no al acceso directo a la dirección IP.

    Remediación:

    • Configurar el servidor web para manejar solicitudes solo según el dominio especificado y denegar o redirigir otras solicitudes adecuadamente.

    Pasos de Configuración

    1. Configuración del VirtualHost Predeterminado

      • Crear un VirtualHost predeterminado que capture todas las solicitudes no especificadas y devuelva un 403 Prohibido o las redirija.

        Para Apache:

        root@kitploit:~
         <VirtualHost _default_:80>
             DocumentRoot /var/www/html/yourwordpress
             ...
             <Location />
                 Require all denied
             </Location>
        
         <VirtualHost _default_:443>
             DocumentRoot /var/www/html/yourwordpress
             ...
             SSLEngine on
             SSLCertificateFile /path/to/ssl/certificate.crt;
             SSLCertificateKeyFile /path/to/ssl/private.key;
             ...
             <Location />
                 Require all denied
             </Location>
         </VirtualHost>     
        

        Para Nginx:

        root@kitploit:~
        server {
            listen 80 default_server;
            return 403;
        }
        
        server {
            listen 443 ssl default_server;
            ...
            ssl_certificate /path/to/ssl/certificate.crt;
            ssl_certificate_key /path/to/ssl/private.key;
            ...
            return 403;
        }
        
    2. Configuración del VirtualHost Basado en Dominio

      • Asegúrate de tener un VirtualHost configurado para tu dominio.

      Para Apache:

      root@kitploit:~
      <VirtualHost *:80>
          ServerName yourwordpress.com
          ...
          Redirect permanent / https://yourwordpress.com/
      </VirtualHost> 
      
      <VirtualHost *:443>
          ServerName yourwordpress.com
          DocumentRoot /var/www/html/yourwordpress
          ...
          SSLEngine on
          SSLCertificateFile /etc/httpd/to/ssl/certificate.crt;
          SSLCertificateKeyFile /etc/httpd/to/ssl/private.key;
          ...
      </VirtualHost>    
      

      Para Nginx:

      root@kitploit:~
      server {
          listen       443 ssl;
          server_name  yourwordpress.com;
          root         /var/www/html/wordpress;
          ...
          ssl_certificate /path/to/ssl/certificate.crt;
          ssl_certificate_key /path/to/ssl/private.key;
          ... 
      
    3. Pruebas

      • Aquí está la creación del VirtualHost Predeterminado y el VirtualHost Basado en Dominio para yourwordpress.com.
      • Después de crear el VirtualHost Predeterminado y el VirtualHost Basado en Dominio para yourwordpress.com, se deniega el acceso (error 403) para solicitudes que no están basadas en dominio (https://ip), lo que resulta en una pantalla de error 403.
      root@kitploit:~
       $ curl -i -k http(s)://10.10.66.88
         
       HTTP/1.1 403 Forbidden
       Server: nginx
       Date: Mon, 03 Jun 2024 23:23:13 GMT
       Content-Type: text/html
       Content-Length: 162
       Connection: keep-alive
          
       <html>
       <head><title>403 Forbidden</title></head>
       <body bgcolor="white">
       <center><h1>403 Forbidden</h1></center>
       <hr><center>nginx</center>
       </body>
       </html>
      
         
       $ curl -i -k https://yourwordpress.com
       HTTP/1.1 200 OK
       Server: nginx
       Date: Mon, 03 Jun 2024 23:32:12 GMT
       Content-Type: text/html; charset=utf-8
       Content-Length: 9
       Connection: keep-alive
          
       Hello, yourwordpress.com
      
      • Si es necesario tener comunicación entre servidores o comunicación dentro de la misma subred IP, puedes configurar el VirtualHost Predeterminado para permitir el acceso desde direcciones IP específicas.

    Al implementar estas configuraciones, el servidor web solo responde a solicitudes dirigidas a tu dominio.

    8.10. Configuración Completa del Servidor Web

    Aquí hay un ejemplo de una configuración completa del servidor web que incluye las pautas de seguridad. Ajusta y utiliza esta configuración según tu entorno de servidor web WordPress.

    1. Apache
      root@kitploit:~
      <VirtualHost _default_:80>
          DocumentRoot /var/www/html/yourwordpress
      
          ErrorLog /var/log/httpd/http.ip.error.log
          CustomLog /var/log/httpd/http.ip.access.log combined
      
          <Location />
              Require all denied
          </Location>
      
      <VirtualHost _default_:443>
          DocumentRoot /var/www/html/current/public
      
          ErrorLog /var/log/httpd/https.ip.error.log
          CustomLog /var/log/httpd/https.ip.access.log combined
      
          # SSL Configuration
          SSLEngine on
          SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
          SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
          SSLSessionTimeout 1d
          SSLSessionCache shared:MozSSL:10m
          SSLSessionTickets off
      
          SSLProtocol TLSv1.2 TLSv1.3
          SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
          SSLHonorCipherOrder off
      
          <Location />
              Require all denied
          </Location>
      </VirtualHost>    
      
      <VirtualHost *:80>
          ServerName yourwordpress.com
          Redirect permanent / https://yourwordpress.com/
      </VirtualHost> 
      
      <VirtualHost *:443>
          ServerName yourwordpress.com
          Protocols h2 http/1.1
          DocumentRoot /var/www/html/current/public
      
          ErrorLog /var/log/httpd/https.yourwordpress.com.error.log
          CustomLog /var/log/httpd/https.yourwordpress.com.access.log combined
      
          # SSL Configuration
          SSLEngine on
          SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
          SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
          SSLSessionTimeout 1d
          SSLSessionCache shared:MozSSL:10m
          SSLSessionTickets off
      
          SSLProtocol TLSv1.2 TLSv1.3
          SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
          SSLHonorCipherOrder off
      
          <Directory /var/www/html/current/public>
              Options -Indexes FollowSymLinks
              AllowOverride All
              Require all granted
          </Directory>
      
          # Deny PHP execution in uploads directory
          <Directory "/var/www/html/current/public/wp-content/uploads">
              <FilesMatch "\.php$">
                  SetHandler none
                  Require all denied
              </FilesMatch>
          </Directory>
      
          # PHP Serving 
          ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost/var/www/html/current/public
          #ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/current/public
      
          # Favicon
          <Location "/favicon.ico">
              ErrorDocument 404 "Not Found"
              SetEnvIf Request_URI "^/favicon\.ico$" no_log
          </Location>
      
          # Robots.txt
          <Location "/robots.txt">
              Require all granted
              SetEnvIf Request_URI "^/robots\.txt$" no_log
          </Location>
      
          # Restrict access to wp-cron.php
          <Files "wp-cron.php">
              Require all denied
              Require ip 127.0.0.1
          </Files>
      
          # Restrict access to wp-json
          <Location "/wp-json/">
              Require all denied
              Require ip 127.0.0.1 
              Require ip 10.10.77.49
              Require ip 10.10.71.20
          </Location>
      
          # Restrict access to wp-admin
          <Location "/wp-admin">
              Require all denied
              Require ip 10.10.77.49
              Require ip 10.10.71.20
          </Location>
      
          <Files "wp-login.php">
              Require all denied
              Require ip 10.10.77.49
              Require ip 10.10.71.20
          </Files>
      
          # Deny access to hidden files
          <FilesMatch "^\.">
              Require all denied
          </FilesMatch>
      </VirtualHost>
      
    2. Nginx
      root@kitploit:~
      server {
          listen       80 default_server;
          listen       443 default_server ssl http2;
      
          error_log    /var/log/nginx/http.ip.error.log;
          access_log   /var/log/nginx/http.ip.access.log  main;
      
          ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
          ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
          ssl_session_timeout 1d;
          ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
          ssl_session_tickets off;
      
          ssl_protocols TLSv1.2 TLSv1.3;
          ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
          ssl_prefer_server_ciphers off;
      
          location / {
               deny all;
          }
      }
      
      server {
          listen       443 ssl http2;
          server_name  yourwordpress.com;
          root         /var/www/html/wordpress;
      
          error_log    /var/log/nginx/https.yourwordpress.com.error.log;
          access_log   /var/log/nginx/https.yourwordpress.com.access.log  main;
      
          ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
          ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
          ssl_session_timeout 1d;
          ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
          ssl_session_tickets off;
      
          ssl_protocols TLSv1.2 TLSv1.3;
          ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
          ssl_prefer_server_ciphers off;
      
      
          location = /favicon.ico {
              log_not_found off;
              access_log off;
          }
      
          location = /robots.txt {
              allow all;
              log_not_found off;
              access_log off;
          }
      
          # Restrict to access Wordpress Cron
          location = /wp-cron.php {
              allow 127.0.0.1;
              deny all;
              access_log off;
              log_not_found off;
          }
      
         # Restrict to access json rest-api
         location ~ ^/wp-json/ {
              allow 127.0.0.1;    		# Allow localhost
              allow 10.10.77.49;		    # Allow myip
              allow 10.10.71.20;       # Allow myip
              deny all;
              access_log off;
              log_not_found off;
          }
      
          # Restrict to access Wordpress Admin
          location = /wp-admin {
              allow 10.10.77.49;		    # Allow myip
              allow 10.10.71.20;       # Allow myip
              deny all;
          }
          
          location ~* \wp-login.php {
              allow 10.10.77.49;		    # Allow myip
              allow 10.10.71.20;       # Allow myip
              deny all;
          }
      
          # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
          # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
          location ~ /\. {
              deny all;
          }
      
          # Deny access to any files with a .php extension in the uploads directory
          location /wp-content/uploads {  
              location ~ \.php$ {
                  deny all;
              }
          }
          # Other example
          # location ~* /(?:uploads|files)/.*\.php$ {
          # 		deny all;
          # }
      
          # Rewrite rules, sends everything through index.php and keeps the appended query string intact
          location / {
              try_files $uri $uri/ /index.php$is_args$args;
          }
      
          # Serving PHP
          location ~ \.php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+\\.php)(/.+)$;
              # fastcgi_pass   127.0.0.1:9000; 					 # With php-cgi (or other tcp sockets):
              fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;   # With php-fpm (or other unix sockets):
              fastcgi_index index.php;
              include /etc/nginx/fastcgi_params;
              fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
          }
      
          location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
              expires max;
              log_not_found off;
          }
      
      }
      

    9. Asegurar las Actualizaciones de Seguridad de WordPress

    WordPress aborda las vulnerabilidades de seguridad lanzando nuevas actualizaciones de versión cuando se descubren vulnerabilidades.

    Por ejemplo, si se encuentra una vulnerabilidad de seguridad en WordPress 6.5.2, se abordará y distribuirá en la versión 6.5.3.

    Dado que las actualizaciones de seguridad no se gestionan versión por versión, son necesarias actualizaciones regulares de versión para abordar las vulnerabilidades de seguridad.

    Consulta la información oficial de lanzamientos de WordPress para actualizaciones: WordPress Releases

    Remediación:

    • Actualiza WordPress regularmente.
    • WordPress no gestiona las actualizaciones (incluyendo actualizaciones de seguridad) versión por versión.
    • A partir del 20 de mayo de 2024, solo la versión 6.5 está en mantenimiento.

    Nota:

    • Las versiones Beta, Nightly y otros checkouts de Subversion no son compatibles.
    • Evita usar productos bifurcados o versiones que no sean lanzamientos oficiales de WordPress.
    • Documentación para versiones compatibles: Supported Versions

    10. Asegurar Revisiones Regulares de Vulnerabilidades de Seguridad para WordPress

    WordPress es un software de sistema de gestión de contenidos (CMS). Dado que es un software empaquetado, las vulnerabilidades de seguridad ocurren principalmente en sus componentes (archivos del núcleo, plugins, temas, etc.).

    A diferencia de las aplicaciones web desarrolladas a medida para requisitos específicos, la identificación y solución de vulnerabilidades de seguridad debe hacerse utilizando métodos adecuados para WordPress.

    Si un sitio web construido con WordPress no ha sido personalizado extensamente y conserva la naturaleza de WordPress, las vulnerabilidades de seguridad se pueden verificar fácilmente usando WPScan.

    WPScan es un software parcialmente de pago, pero el nivel gratuito básico no tiene limitaciones funcionales. Permite revisiones y respuestas regulares a las vulnerabilidades de seguridad de WordPress.

    Remediación:

    • Realiza revisiones de vulnerabilidades regulares usando WPScan (o herramientas similares que puedan escanear WordPress).
    • Si se encuentran vulnerabilidades, verifica y realiza las acciones necesarias para eliminarlas. En la mayoría de los casos, esto se resuelve mediante actualizaciones.
    • Consulta la documentación de usuario de WPScan.
    • Más información sobre vulnerabilidades comunes que se encuentran a menudo en WordPress: Extending WordPress Common Security Vulnerabilities

    WPScan:```


    root@kitploit:~
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|
    
         WordPress Security Scanner by the WPScan Team
                         Version 3.8.22
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
    

    [+] URL: https://yourwordpress.com/ [192.168.10.100] [+] Started: Fri May 24 14:39:06 2024

    Interesting Finding(s):

    [+] Headers .. ... | - content-security-policy: upgrade-insecure-requests | Found By: Headers (Passive Detection) | Confidence: 100%

    .. ... [+] XML-RPC seems to be enabled: https://yourwordpress.com/xmlrpc.php | Found By: Link Tag (Passive Detection) | Confidence: 30% | References: | - http://codex.wordpress.org/XML-RPC_Pingback_API | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/ | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/ | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/ | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

    .. ...

    [+] Finished: Fri May 24 14:39:48 2024 [+] Requests Done: 187 [+] Cached Requests: 7 [+] Data Sent: 56.32 KB [+] Data Received: 605.595 KB [+] Memory used: 276.602 MB [+] Elapsed time: 00:00:42

    root@kitploit:~
    ---
    ### Leer a continuación
    - [Configurar proxy Squid con mejores prácticas de seguridad](https://github.com/password123456/setup-squid-proxy-with-security-best-practice)
    
    Descargar herramienta
    • Específico de Apache y puede utilizarse para incluir otras URL, lo que representa un riesgo de seguridad.
  • mb_send_mail:

    • Envía un correo electrónico, que puede ser explotado para spam.