Однажды пришло письмо от хостера, у которого арендуется сервер с несколькими сайтами, что рассылается спам. Сайты на хостинге старые, не обновляются, так что уязвимость вполне могла быть в одном из плагинов или в самой CMS.
Нюанс в том, что удалять\обновлять сайты возможности нет, они просто должны работать (уж не спрашивайте почему), поэтому для начала пришлось просто разобраться, что же происходит и найти, откуда идёт рассылка.
Первоначально посмотрел очередь почтовых писем в используемом MTA (exim4 в данном случае):
exim -bp | wc -l
Кол-во писем было около 130к. Чистим:
exipick -i | xargs exim -Mrm
Далее различные варианты отлова зловредов. По заголовку письма посмотреть его содержимое:
exim -Mvh 1hvdPZ-00013V-PF # 1hvdPZ-00013V-PF - ID письма в очереди
Если повезет, то будет видно что-то подобное:
X-PHP-Originating-Script: 112:pwned.php
Но в моём случае такой строки вообще не было. Далее следующий вариант – в конфиг php.ini добавить:
mail.add_x_header = On
mail.log = /var/log/php-mail.log
Рестартовать и проверить, не появились ли в данном файле какие-нибудь записи, из которых можно найти зловреда.
В моём случае снова неудача, ибо файл был пуст. Сложности и путаницы добавляло то, что часть сайтов работала на php-fpm, часть – apache, приходилось в каждый закидывать файлик с phpinfo() и проверять, где какой конфиг php.ini используется и с какими параметрами.
Бывает так, что скрипты шифруются через base64. В директории с сайтами выполнил:
grep -r "base64_decode"
На выходе куча портянок, в которых через PHP Decoder смог что-то расшифровать, но ничего криминального не увидел.
Также пробежался по файлам с битами выполнения в правах:
find -type f -perm -110
Получил список странных файлов, датированных 1980 годом. Подозрительные файлы выпилил, но спам продолжал идти.
Проверил крон от имени пользователя веб-сервера:
sudo -u www-data crontab -e
Там нашлась подозрительная строчка,
*/10 * * * * perl /var/tmp/TaYFgW >/dev/null 2>&1
которую я закомментировал. Тем не менее, спам всё ещё рассылался.
Далее были применены весьма радикальные меры к сайтам. Может, это не совсем верно на продакшене, но для диагностики самое то + была возможность так сделать без последствий. Подойдет такой вариант не всем. Если отключить exim4 (остановить), то через какое-то время он запускался снова. И тогда я просто в конфигах php прописал:
php_admin_value[disable_functions] = dl,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,mail,
php_admin_value[sendmail_path] = "tee /tmp/mail.out > /dev/null"
То есть просто запретил выполнение функций, в т.ч. самой нужной в данном случае – mail, а до кучи и прописал “левый” путь до sendmail и сделал так во всех конфигурационных файлах с php, ибо непонятно было, откуда черти лезут.
Тем не менее, анализатором трафика я посмотрел, что спам сыпется с сервера даже после проделанных манипуляций выше:
tcpdump -i eth0 -nn port 25
Вывод напрашивался такой: почта отправляется не через функции php, а к примеру, из консоли, т.к. проанализировав трафик из tcpdump в wireshark, случайно обнаружил строки вида: command line: MAIL FROM
В процессах ps aux затесалась пара непонятных наименований вида “sin” и “xid” от имени веб-сервера. Убив их, поток в tcpdump значительно убавился, но не прекратился. Что это было, я так не разобрался до конца.
Резюмируя немного сумбурное описание действий выше, наиболее хорошим способом проверки будет запуск сканера, например, ai-bolit или альтернативного, который сразу покажет, где проблема и куда копать. Способы поиска зараженных скриптов тоже эффективны, но не всегда, как в моей ситуации – время было потрачено, а воз и ныне там. И в результате 8 часового сканирования, было найдено более 800 зараженных скриптов (древние сайты с дырявыми плагинами).