Найдите скрипт php, который отправляет письма

9

Есть ли способ для меня, чтобы найти PHP-скрипт, который отправляет электронные письма.

У меня есть apache + php (без mod_suphp и suexec) в «стандартной» установке, и я хочу узнать, что php-скрипт ведьмы отправляет электронные письма, когда я проверяю логи, я просто вижу uid пользователя, отправляющего электронные письма (в мой случай apache) но я хочу выяснить сценарий, который создал письмо.

Это возможно, или я должен установить suexec или mod_suphp, чтобы отслеживать это?

Спасибо за помощь.

Адам
источник

Ответы:

9

PHP 5.3 был выделен для улучшения отслеживания почты, но я не уверен, что это произошло. (edit: yes В php 5.3 встроено ведение журналов - в php.ini есть переменная config mail.log, которая будет регистрировать использование почты из кода php.)

Мы решили проблему, сделав sendmail сценарием оболочки оболочки.

В php.ini установлен новый почтовик. Например:

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

Сценарий sendmail-php просто использует logger для получения информации, а затем вызывает системный sendmail:

#!/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 $*

Это приведет к регистрации того, что задано для mail.info в файле syslog.conf.

Еще одно предложение - установить расширение suhosin php, чтобы сократить количество лазеек в PHP, если вы не используете Debian или Ubuntu, где это уже используется по умолчанию.

labradort
источник
php 4.x здесь (есть несколько старых приложений, которые не переносятся на php 5.x)
adam
Нет проблем, эта обертка сделает свое дело. Это внешнее по отношению к php. Я упомянул php 5.3 только потому, что к этому времени было исправлено отсутствие функции ведения журнала. Оболочка работает очень хорошо, и мы смогли определить некорректный скрипт пользователем, который разрешал спам.
Лабрадорт
спасибо, я думаю, что я собираюсь принять ваш подход. спасибо
Адам
1
Привет, не знаю почему, но "script = $ {SCRIPT_NAME}, filename = $ {SCRIPT_FILENAME}" не возвращает ничего, см. var / www / html / mail, uid = 48, user = apache
adam
Вы уверены, что он был настроен правильно? Если она была неизвестна как предопределенная переменная в вашей среде PHP, вы также должны увидеть: «script =» в зарегистрированном выводе. Проверьте, что вы настроили снова очень тщательно. Вы можете попробовать: $ _SERVER ['SCRIPT_FILENAME'] Вы можете найти больше переменных для регистрации в документации PHP по предопределенным переменным: php.net/manual/en/reserved.variables.server.php
labradort
4

Решение этого на самом деле требует нескольких шагов. Приведенное выше решение labradort на самом деле не работает, так как скрипт logger - это скрипт bash, а не php, а скрипт bash не имеет доступа к переменным php, поэтому журналы выходят пустыми. По сути, все, что вы хотите зарегистрировать, необходимо сохранить в переменных среды в php до отправки электронного письма, чтобы регистратор имел доступ к данным. Поскольку вы пытаетесь обнаружить сценарии других пользователей, не обязательно ваши собственные, вы не можете контролировать код php, поэтому вам нужно использовать функцию PHP auto_prepend_file, чтобы гарантировать, что все исполняемые php запускают ваш код инициализации перед всем остальным. Я добавил следующий код через php.ini, чтобы убедиться, что у меня есть данные, которые мне нужны в логгере:

<?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");
?>

Я собрал полное руководство о том, как заставить это работать здесь: http://mcquarrie.com.au/wordpress/2012/10/tracking-down-malicious-php-spam-scripts/

Том МакКуарри
источник
Скрипт-обертка работал над реализацией php по умолчанию в Redhat и Debian Linux, когда он был php 5.2 и более ранних. Я просто использую mail.log = /var/log/apache-mail.log в эти дни, и он делает то, что мне нужно.
Лабрадорт
1
Именно так эксплуатируется ошибка с ракушкой. Я серьезно не рекомендую делать вещи таким образом.
Бен Хичкок
У вас есть пункт. Конечно, вы можете запустить переменные через функцию очистки, чтобы убрать что-нибудь вредное, например "() {:;};". На самом деле, возможно, хорошей идеей будет префикс имен переменных, например, «PHP_», на случай, если есть конфликт имен переменных среды.
Том МакКуарри
2

Существует патч для PHP, который показывает, какой скрипт генерирует электронные письма, добавляя заголовок к отправляемому письму. Я не проверял это, так как я не увлечен исправлением ядра PHP, но я слышал хорошие вещи.

WheresAlice
источник
1
Это звучит как отличный способ пойти. +1. Однако, если вы управляете общим хостом с несколькими клиентами, вы можете сообщить этим клиентам о заголовке или вместо этого перенаправить вывод в файл журнала.
Пекка
Да, может быть, это и есть путь, но в определенный момент это может быть проблемой безопасности, все люди теперь собираются, какой сценарий отправляет электронную почту, плохо сделанный сценарий просто приглашает взломать. Перенаправить в журнал, может быть, и лучше
Адам
Плохо созданные скрипты не должны быть на сервере в первую очередь, люди найдут их, если они там есть (особенно если они являются частью популярной системы cms). Но я понимаю, что, возможно, есть дело против этого решения.
WheresAlice
0

Вам нужно будет найти в журналах доступа что-то, соответствующее времени, когда сообщения были добавлены в спул.

Ричард Солтс
источник
Спасибо за повтор, проблема в том, что это общий хостинг, и для каждого домена есть выделенный журнал доступа.
Адам
Да, к сожалению, вам придется разобраться со всеми из них.
Ричард Солтс
0

Может быть, просто искать в исходных файлах подстроку «mail (»)?

Дмитрий Труханов
источник
Это иногда стоит посмотреть и, в частности, посмотреть на исходный код, который его окружает, на наличие уязвимостей для использования спамерами. Но с большим количеством сложных php-скриптов, принадлежащих многим людям на общем хосте, это не решение этой проблемы.
WheresAlice
В среде с общим хостингом это может не указывать точный сценарий или может привести к множеству ложных срабатываний
Эрик Кигати
0

Просто включите их на своем php.ini

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

затем создайте этот файл и дайте разрешение на запись. Посмотрите на это после этого.

Кевин Нгуен
источник