Что бы увидеть email и телефон, включите JavaScript.

Следим за функциями или как я боролся со спамом


У одного из моих клиентов, стали банить его электронные адреса, расположенные на хостинге с его сайтом. В качестве причин указывался спам. Первоначально пошли по самому простому пути. Создали ящик на великом и всемогущем Google, который благополучно, также был забанен, как Вы догадались за спам. Клиент начал паниковать, это вирусы, это хакеры и всё в этом роде. И стал я тогда зрить в глубь.

Да забыл сказать, что у клиента интернет-магазин работающий на сцепке WordPress + WooCommerce.

Начал я с отключения возможности отсылки писем по SMTP, переключился на встроенную PHP функцию mail(). Как говорится всемирно известный глюк не отсылки писем этой функцией при сцепке WordPress + WooCommerce, я решил использовать в своих целях. То есть обращение и всё остальное проходит как положено, но письма никуда не уходят, а значит сайт спамом не занимается. Но об этом потом. Так же я поставил вместо плагина Wordfense, плагин S.A.F.

Дальше я сделал бэкапы сайта и БД, скачал к себе на локальную машину. И благополучно прогнал через Касперыча (всё как положено, лицензия есть, не стоит экономить на безопасности). Он, как и ожидалось ничего не нашел, так как судя по логам, спам активировался в определённые промежутку времени, не постоянно. Конечно, я воспользовался рядом онлайн сервисов по проверке сайта. Кстати, будьте осторожны с ними, некоторые в целях снять с Вас деньги могут находить и видеть то чего нет. Был еще опыт и с одним хостингом, где ввели услугу лечения от вирусов и у всех на сайтах вдруг появился файл с вирусом, которого до этого не было. Изучение его на предмет вируса, показало наличие кода, но не законченного и латентного в плане активности. Ну Вы поняли, что это было, бизнес и ничего более.

Так вот, следующим моим действием было использование такого хорошего скрипта как AI-Bolit (берите на вооружение, не стесняйтесь), вещь в хозяйстве нужная и полезная. Были найдены около 3 файлов с подозрительными сигнатурами (красное выделение) и 11 (желтенького характера). Проверив их все выяснилось, что всё в рамках нормы и морали.

Стал копаться в логах и отчёт S.A.F. пришел как нельзя вовремя. Так как при сопоставлении данных из логов и из отчёта. Выяснилось, что происходит подозрительное обращение извне к файлу x.gif, лежащему с изображениями. Весил он целый килобайт, а что это был за файл и как он туда попал, информация отсутствовала. Более того из отчёта S.A.F. следовало, что кто-то благополучно выяснил логин администратора к админ панели, а он к слову сказать был мной установлен и имел вид: "v4Df3G67J1d5", пароль еще сложнее. Удалив x.gif и сменив логин вместе с паролем, я заодно поменял все пароли начиная с редакторов и менеджеров магазина и заканчивая БД, и самим хостингом.

Если у вас есть сложности в работе с паролями, то бишь в их структурированном хранении и быстром использовании, рекомендую Вам программу, которой пользуюсь сам: "KeePass Password Safe 2", поищите в Интерент, она уже давно известна и делает удобной жизнь многим.

Но вернёмся к сайту и нашему спаму. Логи функции PHP mail() показывали, что спам до сих пор рассылается. Но в логах, которые предоставлял хостер было не понятно, откуда приходит вызов функции. И я решил поглядеть, кто и откуда это делает. Для этого пришлось залезть в файл class-phpmailer.php, расположенный в папке wp-include, и изменить одну функцию, вписав код для записи стека вызова функций:

    private function mailPassthru($to, $subject, $body, $header, $params)
    {
        $name = "log_bs_";
		$c = file_get_contents('log_bs_num.txt');
		$name .= $c;
		file_put_contents('log_bs_num.txt', ++$c);
		$name .= ".txt";
		//Check overloading of mail function to avoid double-encoding
        if (ini_get('mbstring.func_overload') & 1) {
            $subject = $this->secureHeader($subject);
        } else {
            $subject = $this->encodeHeader($this->secureHeader($subject));
        }
		if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
			$log = serialize(debug_backtrace());
			$result = @mail($to, $subject, $body, $header);
        } else {
			$log = serialize(debug_backtrace());
			$result = @mail($to, $subject, $body, $header, $params);
        }
		
		$f = fopen($name,'w');
		$r = fwrite($f,$log);
		fclose($f);

        return $result;
    }

Запись в разные файлы по одному стеку, сделал, для своего удобства. После некоторого ожидания, спамер снова проявил себя. И у меня появилось множество файлов. Чтобы было удобно их просматривать, я написал небольшой файл и запустил его на локальной машине:

    echo "
"; echo ""; echo "

"; echo "
"; if (!isset($_POST['file'])) echo "

Где имя файла!

"; else { $file = strip_tags($_POST['file']); if (file_exists($file)){ $f=fopen($file,"r"); if($f){ while (!feof($f)) { $out = unserialize(fread($f,filesize($file))); echo '
';
				    print_r ($out);
				    echo '
'; } fclose($f); }else{ echo 'Ошибка!'; } }else echo "

Указанный файл не существует!

"; }

После просмотра стеков, было выяснено, что китайские товарищи, а это были именно, они, так как спам шел на их языке и на адреса в их стране, не взламывали сам сайт, но использовали для рассылки спама такой компонент для WordPress как JetPack. Стоять бояться, куда! Не надо его удалять, он хороший. Просто там есть модуль "Поделиться". И там есть функция поделиться по E-mail, то есть отправить ссылку на статью кому-либо на электронный адрес. Так вот эти хитрецы с помощью этой функции рассылали спам по 9-14 писем за раз с интервалом 5-10 секунд. При этом всовывая рекламу вместе с адресом получателя, а компонент (это на совести разработчиков) брал и оставляя адрес, остальное перемещал в тело отправляемого письма. Отключив возможность делиться по E-mail, я прекратил спам.

Мораль, если что-то происходит, а Вы пока не можете понять, что и где, не надо рвать волосы у первых встречных и метаться в разные стороны. Просто будьте последовательны и проблема будет решена Вами. Добра Вам!

Теги материала: PHP Спам
Понравилась статья, поделитесь ей с друзьями!
RSS подписка по электронной почте


коммент.

avatar

Денис

- 11 августа 2017, 22:12
Добрый день

а если отправка осуществляется через smpt сервер?
avatar

Роман

- 12 августа 2017, 12:24
Доброго времени суток, Денис!
Не важно через что идёт отправка писем, эта служебная информация, передаётся в $params. Нас же интересовало кто и откуда вызывал эту функцию, а для отслеживания достаточно было вписать в функцию debug_backtrace следящий код, который будет скидывать информацию о том какие функции чего и куда вызвали в данной точке исполнения кода. И вот уже по этим логам можно выследить злоумышленника ну или выяснить еще чего-нибудь интересное.
avatar

Артур

- 06 декабря 2017, 15:11
Доброго дня!
Сделал как у вас в статье. После отправки формы на сайте вручную выдает 500ю ошибку сервера.
В логах ругается на строчку
$c = file_get_contents('/log_bs_num.txt');
Говорит «PHP warning: file_get_contents(log_bs_num.txt): failed to open stream: No such file or directory
».
Не силен в PHP. Подскажите пожалуйста как решить проблему. Я так понимаю он не видит файл «log_bs_num.txt»? У меня обычный shared-хостинг, не VPS.
avatar

Роман

- 06 декабря 2017, 20:17
Доброго времени суток, Артур! Вы правильно думаете, он просто не видит файл, возможно дело в этом знаке "/", я так понимаю у Вас путь получается с двумя "//" и он не может понять где это.
avatar

Артур

- 06 декабря 2017, 20:53
Спасибо за ответ, но я похоже в запарках не ту инфу скинул.
Получается у меня код ровно как у вас:
$c = file_get_contents('log_bs_num.txt');
На этой строке скрипт прерывается. Сервер отдает 500.
В лог ошибок попадает строка
PHP warning: file_get_contents(log_bs_num.txt): failed to open stream: No such file or directory
Файл log_bs_num.txt при этом создается в корне, но в него ничего не записывается — пустой.
Что я могу упускать? Подскажите пожалуйста. Да, кстати, возможно это важно, но я все это в MODX Revo делаю.
avatar

Роман

- 06 декабря 2017, 21:40
А Вы, где именно, в MODX делаете, возможно стоит путь задать так MODX_BASE_PATH.$path.$filename, где $path это путь от корня к файлу, например «assets/», а $filename соответственно имя файла.
avatar

Артур

- 06 декабря 2017, 22:05
Делаю в этом модуле: core/model/modx/mail/phpmailer/class.phpmailer.php
А еще есть подозрение, что в модексе эта конструкция не работает…
serialize(debug_backtrace())
avatar

Артур

- 06 декабря 2017, 22:35
Роман, у меня к вам предложение. Сможете написать рабочий код этой процедуры для MODX Revo? Не бесплатно конечно. Пишите на мою почту. Обсудим условия. Спасибо.
avatar

Stanislav

- 16 марта 2018, 13:17
Спасибо!
очень помог твой код. Два дня я мучился!
Сайт фонда помощи детям, хостер блокирует отправку писем с сайта, по тому что сайт рассылает спам.
у всех паника — сайт взломали
я ищу вирусы, вижу что примерно раз в минуту с сайта отправляется письмо, но не могу посмотреть его содержимое. Сломал себе всю голову

Воспользовался твоим кодом и нашел причину! при каждом донате, отправляется уведомления на почту. А пожертвований совершается примерно 1-2 в минуту и каждый раз отправляется письмо. Хостер думает что это спам и блокирует отправку.
как все оказалось просто :)

Написать комментарий

Ваш email не будет опубликован. Обязательные поля отмечени символом *