19 de Agosto, 2008

¿Quién envía correos con mail() de PHP?

Es un problema que nos podemos encontrar alguna vez.

Supongamos que tenemos un servidor donde hay alojadas diferentes páginas web, y no podemos mantener al día las versiones del software que mueven las mismas (porque sea un desarrollo a medida, por ejemplo).

Es posible que alguna de esas webs tenga un fallo de programación que se traduzca en un problema de seguridad y que permita, mediante un formulario mal gestionado (lo más habitual), enviar correos arbitrariamente desde nuestro servidor.

Ni que decir tiene que que nos usen para enviar spam no es nada bueno, así que necesitamos detectar qué web es la que causa el problema y borrarla^W corregirlo :D.

La dificultad está en que en los logs habituales no veremos nada ilegal: en los de Apache todo funciona perfectamente (se abusa de una llamada descuidada a mail()), y en los del MTA veremos entregas legítimas desde el usuario de Apache vía 127.0.0.1.

Entonces, ¿qué podemos hacer?

Pues una solución bastante buena que he encontrado por aquí consiste en crear un wrapper que ejecutaremos como si fuera el binario normal de sendmail (que es lo que usa internamente la función de PHP), y que nos proporcionará la información extra que necesitamos, para luego ejecutar el programa de nuestro MTA para que procese el correo normalmente.

Proceso del wrapper
Diagrama con la estrategia

Como wrapper he utilizado el propuesto en el foro antes citado, ya que está hecho en perl y cumple su cometido a la perfección (tengo una copia local: wrapsendmail.pl).

Su instalación es fácil, lo compiamos en /usr/bin/ y en nuestro php.ini indicamos:

sendmail_path = /usr/bin/wrapsendmail.pl -t -i

En wrapsendmail.pl se espera que el binario original se encuentre en /usr/sbin/sendmail, y los logs irán a /var/log/wrapsendmail.log (lo creamos con touch y le damos permisos 777 con chmod, para que sea quien sea el que lo llame... pueda guardar el log).

Solo nos queda reiniciar Apache y obtendremos entradas en el log tal que:

Tue Aug 19 18:26:20 CEST 2008 - /var/www/html/web -  apache x 48 48   Apache /var/www /sbin/nologin

En rojo he marcado lo interesante, y nos permitirá saber de dónde se está enviando supuestamente el spam (tendremos muchas entradas en el log).

Otro detalle a tener en cuenta es que si en lugar de una ruta, como en el ejemplo, vemos lo que parece ser un nombre de fichero aleatorio o que el usuario no es el de Apache, eso puede indicar que estamos ante una intrusión mucho más grave :P.

La solución es bastante sencilla, y viene a suplir la limitación que tiene mail() por la que no podemos saber en los logs habituales qué web manda los correos ;).

Anotación por Juan J. Martínez, clasificada en: security, spam, hack, php.

Hay 1 comentario

Gravatar

pozip, gran truco, anotado queda (por que fijo que me pasara).

por Wu, en 2008-08-19 23:10:53

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.

Algunas anotaciones relacionadas: