Encuentra el script php que está enviando correos

9

¿Hay alguna manera de encontrar el script php que envía correos electrónicos?

Tengo apache + php (sin mod_suphp ni suexec) en una instalación "estándar", y quiero saber si el script de php de bruja está enviando correos electrónicos, cuando reviso los registros solo veo el uid del usuario que envía los correos electrónicos (en mi caso apache) pero quiero averiguar el script que originó el correo electrónico.

¿Es posible o debo instalar suexec o mod_suphp para mantener el seguimiento de eso?

Gracias por la ayuda.

Adán
fuente

Respuestas:

9

PHP 5.3 se asignó para obtener un mejor seguimiento del correo, pero no estoy seguro de si eso sucedió. (editar: sí, php 5.3 tiene el registro incorporado ahora - php.ini tiene la variable de configuración mail.log que registrará el uso del correo desde el código php).

Resolvimos el problema haciendo que sendmail sea un script de shell envoltorio.

En php.ini establece un nuevo anuncio publicitario. P.ej:

sendmail_path = /usr/local/bin/sendmail-php -t -i

El script sendmail-php simplemente usa el registrador para obtener información y luego llama al sistema sendmail del sistema:

#!/bin/bash

logger -p mail.info -t sendmail-php "site=${HTTP_HOST}, client=${REMOTE_ADDR}, script=${SCRIPT_NAME}, filename=${SCRIPT_FILENAME}, docroot=${DOCUMENT_ROOT}, pwd=${PWD}, uid=${UID}, user=$(whoami)"

/usr/sbin/sendmail -t -i $*

Esto registrará lo que sea que su mail.info esté configurado en el archivo syslog.conf.

Otra sugerencia es instalar la extensión suhosin php para ajustar las lagunas en PHP, a menos que esté ejecutando Debian o Ubuntu donde esto ya es el predeterminado.

labradort
fuente
php 4.x aquí (obtuve algunas aplicaciones antiguas que no son viables a php 5.x)
adam el
No hay problema, este envoltorio hará el truco. Es externo a php. Mencioné php 5.3 simplemente porque esta falta de una función de registro estaba programada para ser reparada para entonces. El contenedor funciona muy bien y pudimos identificar un script defectuoso de un usuario que permitía el spam.
labradort
Gracias, supongo que voy a tomar su enfoque. gracias
adam
1
Hola, no sé por qué, pero el "script = $ {SCRIPT_NAME}, filename = $ {SCRIPT_FILENAME}" no devuelve nada, consulte: 7 20:24:08 gateway logger: sendmail-php: client =, filename =, pwd = / var / www / html / mail, uid = 48, user = apache
adam el
¿Estás seguro de que se configuró correctamente? Si no se conocía como una variable predefinida en su entorno PHP, debería ver también: "script =" en la salida registrada. Verifique lo que configuró nuevamente con mucho cuidado. Puede intentar: $ _SERVER ['SCRIPT_FILENAME'] Es posible que pueda buscar más variables para iniciar sesión desde la documentación de PHP en variables predefinidas: php.net/manual/en/reserved.variables.server.php
labradort
4

La solución a esto realmente requiere unos pocos pasos. La solución anterior de labradort en realidad no funciona, ya que el script del registrador es un script bash, no php, y el script bash no tiene acceso a las variables de php, por lo que los registros quedan en blanco. Básicamente, lo que desee registrar debe guardarse en las variables de entorno en php antes de enviar el correo electrónico para que el registrador tenga acceso a los datos. Como está tratando de detectar los scripts de otros usuarios, no necesariamente los suyos, no tiene control sobre el código php, por lo que debe usar la función auto_prepend_file de PHP para asegurarse de que todo el php ejecutado ejecute su código de inicialización antes que todo lo demás. Antepongo el siguiente código a través de php.ini para asegurarme de que tengo los datos que necesito en el registrador:

<?php
/**
 * This passes all SERVER variables to environment variables, 
 * so they can be used by called bash scripts later
 */
foreach ( $_SERVER as $k=>$v ) putenv("$k=$v");
?>

He preparado un tutorial completo sobre cómo hacer que esto funcione aquí: http://mcquarrie.com.au/wordpress/2012/10/tracking-down-malicious-php-spam-scripts/

Tom McQuarrie
fuente
El script de envoltura funcionó en la implementación de Redhat y Debian Linux de los valores predeterminados de php cuando era php 5.2 y anteriores. Simplemente estoy usando mail.log = /var/log/apache-mail.log en estos días y hace lo que necesito.
labradort
1
Así es como se explota el error shellshock. En serio, no recomiendo hacer las cosas de esta manera.
Ben Hitchcock
Tiene un punto. Ciertamente, podría ejecutar las variables a través de una función de desinfección para eliminar cualquier cosa dañina, como "() {:;};". En realidad, probablemente sea una buena idea prefijar también los nombres de las variables, con algo como "PHP_", en caso de que haya un choque de nombres de variables de entorno.
Tom McQuarrie
2

Hay un parche para PHP que mostrará qué script está generando los correos electrónicos agregando un encabezado al correo electrónico que se envía. No lo he probado ya que no estoy interesado en parchar el núcleo de PHP, pero he escuchado cosas buenas.

WheresAlice
fuente
1
Esto suena como un excelente camino a seguir. +1. Sin embargo, si está administrando un host compartido con varios clientes, es posible que desee informar a esos clientes sobre el encabezado o, en su lugar, redirigir la salida a un archivo de registro.
Pekka
Sí, tal vez sea el camino a seguir, pero en cierto momento puede ser un problema de seguridad, todas las personas ahora van a saber qué script envía un correo electrónico, los script mal hechos solo invitan a ser pirateados. Redireccionar a un registro, tal vez sea mejor
adam
Las secuencias de comandos mal hechas no deberían estar en el servidor en primer lugar, las personas las encontrarán si están allí (particularmente si son parte de un sistema cms popular). Pero entiendo que tal vez haya un caso en contra de esta solución.
WheresAlice
0

Tendrá que seleccionar los registros de acceso para obtener algo que se ajuste al período de tiempo en que se agregaron los mensajes a la cola.

Sales de Richard
fuente
Gracias a la repetición, el problema es que es un alojamiento compartido y para cada dominio es un registro de acceso dedicado.
adam
Sí, desafortunadamente vas a tener que revisarlos todos.
Richard Salts
0

¿Puede ser simplemente buscar en los archivos de origen la subcadena "mail ("?

Dmitry Trukhanov
fuente
A veces vale la pena mirarlo, y en particular mirar el código fuente que lo rodea para detectar cualquier vulnerabilidad que puedan usar los spammers. Pero con muchos scripts PHP complicados que son propiedad de muchas personas en un host compartido, no es la solución para este problema.
WheresAlice
En un entorno de alojamiento compartido, esto podría no precisar el guión exacto o podría dar lugar a múltiples falsos positivos
Eric Kigathi
0

Simplemente habilítelos en su php.ini

mail.add_x_header = On
mail.log = /var/log/phpmail.log

luego cree ese archivo y otorgue el permiso de escritura. Échale un ojo después de eso.

Kevin Nguyen
fuente