En resumen: Cuando el servidor envía spam, casi siempre hay una de tres causas: un script PHP inyectado o utilizado de forma abusiva, un buzón con contraseña robada o un servidor de correo mal configurado. Asegure algunos de los correos en espera, lea sus cabeceras y el log de correo, y en la mayoría de los casos encontrará el origen. Después, detenga el envío, cierre la causa y solo entonces solicite la exclusión de las listas de bloqueo.
Cuando los clientes encuentran sus facturas en la carpeta de spam
Rara vez empieza con un aviso de seguridad. Normalmente se ponen en contacto clientes que ya no reciben sus ofertas, o el buzón se llena de avisos de rebote de correos que nadie ha escrito. A veces el hoster bloquea el envío y cita como motivo un tráfico de correo llamativo.
Para la empresa, eso tiene pronto consecuencias perceptibles. Si la dirección del servidor figura en una lista de bloqueo, otros servidores de correo rechazan también sus correos legítimos: facturas, confirmaciones de pedido, enlaces de contraseña de la tienda. La reputación del dominio sufre y el daño crece con cada hora que continúa el envío.
El envío de spam es una de las consecuencias conocidas de un compromiso. Tras PHP2Shell, las vulnerabilidades CVE-2026-109618 y CVE-2026-109619 con ejecución de código sin inicio de sesión, es un motivo más para mirar con más detalle. Pero el spam no es un indicio específico de PHP2Shell; no hay indicadores de compromiso confirmados. Otros indicios generales los describe ¿Ya estoy comprometido?.
Tres causas típicas cuando el servidor envía spam
| Causa | Imagen típica | Dónde mirar |
|---|---|---|
| Script PHP inyectado | correos sin autenticación, entregados localmente mediante sendmail |
cabeceras, log de correo de PHP, archivos PHP nuevos |
| Formulario utilizado de forma abusiva | correos mediante un formulario de contacto o de recomendación a destinatarios ajenos | log de acceso del formulario, cabeceras |
| Buzón secuestrado | envío con autenticación válida en el servidor de correo | log de correo con nombre de inicio de sesión, lugares de inicio de sesión |
| Servidor de correo abierto | remitentes ajenos usan su servidor como reenviador | configuración del servidor de correo, comprobación externa |
Las dos primeras causas afectan al sitio web, la tercera a las cuentas de correo, la cuarta a la configuración del servidor. La distinción es importante porque las contramedidas son completamente distintas.
Leer la cola de correo
En servidores con Postfix, la cola muestra lo que está a punto de enviarse. Los siguientes comandos solo leen:
# Mostrar el contenido de la cola (equivale a mailq)
postqueue -p | tail -30
# Mostrar las cabeceras de un correo concreto (insertar el ID de cola de la lista)
sudo postcat -q -h QUEUE-ID
# Inicios de sesión correctos en el servidor de correo con nombre de usuario
sudo grep 'sasl_username=' /var/log/mail.log | awk -F'sasl_username=' '{print $2}' | sort | uniq -c | sort -rn | head
Las cabeceras suelen revelar ya el origen. Si el correo procede de un buzón autenticado, el nombre de inicio de sesión aparece en el log de correo. Si allí se acumula una sola cuenta con inicios de sesión desde países extranjeros, es muy probable que la contraseña de ese buzón se haya conocido. Si el correo, en cambio, se entregó localmente, suele venir de un script del servidor.
Si en su servidor funciona otro servidor de correo, por ejemplo Exim, los comandos se llaman de otra forma, pero el principio es el mismo: ver la cola, leer las cabeceras, contar los inicios de sesión en el log. En un alojamiento compartido sin acceso shell, pida por escrito al hoster un extracto del log de correo y algunos correos de ejemplo con las cabeceras completas. Muchos hosters facilitan estos datos si se les pide, porque ellos mismos tienen interés en acabar con el envío.
Asegure algunos correos completos antes de detener o vaciar la cola. Son pruebas para el análisis posterior y para conversaciones con el hoster o los operadores de listas de bloqueo.
Encontrar el script PHP responsable
Si el envío pasa por PHP, ayuda la configuración de correo de PHP. Según el manual de PHP, mail.log registra cada llamada a la función mail() con la ruta completa del script, el número de línea, el destinatario y las cabeceras. mail.add_x_header escribe además en cada correo una cabecera X-PHP-Originating-Script con el identificador de usuario y el nombre del archivo.
; En php.ini o en el pool de FPM; después reiniciar todos los workers
mail.add_x_header = On
mail.log = /var/log/php/mail.log
El archivo de registro debe poder escribirlo el proceso de PHP. La cabecera revela un nombre de archivo a los destinatarios; desactívela tras el análisis si no quiere mantenerla de forma permanente.
Si como remitente aparece un archivo desconocido, por ejemplo en la carpeta de subida o de caché, es un indicio de una webshell. Cómo clasificar tales archivos lo describe Reconocer y eliminar webshells. Si en cambio se trata de un formulario de contacto conocido, probablemente se ha utilizado de forma abusiva, por ejemplo porque destinatarios o cabeceras se toman de entradas del formulario. Es un error en el código, no una intrusión, pero debe corregirse igual de rápido.
No todo spam usa la función mail(). El código malicioso también puede establecer directamente una conexión con servidores de correo ajenos. Entonces el envío no aparece ni en la cola ni en el log de correo de PHP, pero sí como conexiones salientes al puerto 25. Cómo revisarlas figura en Comprobar las conexiones salientes de un servidor.
Detener el envío y volver a arrancar con limpieza
Una vez encontrado el origen, la limpieza sigue este orden:
- Detener el envío: bloquear el camino afectado, es decir, desactivar el script, bloquear el buzón o detener la cola. Asegurar como prueba los correos en espera.
- Cerrar la causa: en el caso de una webshell, llevar PHP a un nivel corregido (8.5.12, 8.4.27, 8.3.36, 8.2.35 o backport confirmado), reiniciar todos los workers y limpiar el sitio web. En el de un formulario, corregir el código. En el de un buzón, cambiar la contraseña y revisar el dispositivo del usuario.
- Buscar otras huellas: quien envía spam mediante una webshell suele haber creado otras puertas traseras.
- Limitar la salida: permitir las conexiones salientes al puerto 25 solo para el servidor de correo, no para el usuario del servidor web.
- Limpiar las listas de bloqueo: solo ahora solicitar la exclusión a los operadores de las listas de bloqueo y describir brevemente lo que se ha corregido.
Aproveche la ocasión para revisar SPF, DKIM y DMARC de su dominio. Estas entradas DNS determinan qué servidores pueden enviar en nombre de su dominio y dificultan que terceros abusen de su dirección de remitente.
¿Cómo ayuda PHP SOS en concreto?
- Analizamos la cola, las cabeceras y los logs de correo y determinamos si la causa es un script, un formulario, un buzón o la configuración.
- Detenemos el envío de forma controlada y aseguramos pruebas para el hoster y las listas de bloqueo.
- Limpiamos el sitio web en el marco de la eliminación de malware y cerramos la puerta de entrada.
- Limitamos el tráfico de correo saliente a nivel de servidor y acompañamos la exclusión de las listas de bloqueo.
Preguntas frecuentes
¿Cómo noto que mi servidor envía spam?
Son típicos los avisos de rebote de correos que nadie ha escrito, los avisos del hoster, una cola de correo llena y clientes que de pronto encuentran sus correos en la carpeta de spam. También son una señal clara las entradas de la dirección de su servidor en listas de bloqueo públicas.
¿Cómo encuentro el script PHP que envía spam?
PHP puede registrar cada llamada a la función mail() con la ruta del script si se ha fijado mail.log. Con mail.add_x_header, PHP escribe además el nombre del script en la cabecera de cada correo. En correos ya enviados o en espera ayuda una mirada a las cabeceras.
¿Debo vaciar la cola de correo de inmediato?
No antes de haber asegurado algunos correos como prueba. Las cabeceras suelen mostrar qué script o qué buzón ha desencadenado el envío. Detener suele ser mejor que borrar mientras no se conozca el origen.
¿Cómo salgo de nuevo de las listas de bloqueo?
Primero eliminar la causa y después solicitar la exclusión a los operadores de cada lista de bloqueo. La mayoría exige una explicación de lo que se ha corregido. Quien lo solicita demasiado pronto y sigue enviando spam, vuelve a ser incluido.