Bitrix modules main include php вирус



Чем сайту грозят вирусы? Не только изменением информации или файлов. В большинстве случаев страдает бизнес. Компания МастерКласс узнала о проблемах с сайтом в первую очередь потому, что в 3 раза снизилось количество заявок на ремонтные услуги! Вместо 10 звонков в день поступали 1 - 3. Трафик на сайт снизился до минимума.

Если на вашем сайте проявляется подозрительная активность, описанная в статье, рекомендуем немедленно обратиться в отдел сопровождения сайтов к специалистам для проведения исследования.

Подозрение на вирусы

15 марта — начало истории. Клиент заметил падение трафика и через несколько дней обратился к нам.

Проблема видна невооруженным взглядом по Метрике. С начала марта посещаемость сайта поползла вниз.


Мы нашли подтверждение проблемы в вебмастере — снижение числа проиндексированных страниц в 4 раза. Трафик просел.

Внимательно посмотрев на сайт, обнаружили, что файл настроек адресов страниц urlrewrite.php и конфигурационный файл .htaccess изменились. Из-за этого все страницы каталога поменяли адреса. Поисковик не успел их проиндексировать, а старые удалил.

Тревожным звонком было то, то при первой попытке изменить файл .htaccess, он через несколько минут вернулся в прежнее состояние. Напоминаю, мы грешили на хостинг, и эту проблему устранили настройкой прав доступа к .htaccess.

На тот момент решили, что, возможно, клиент или хостинг случайно поменяли настройки. Мы починили файлы и отчитались клиенту о результате.


Через несколько дней файл сломался вновь, равно как и адреса страниц.

Первая попытка — Разговор дипломатов


Причина падения трафика и выпадения страниц из индекса.

В недрах сайта был специальный php-файл, который делал 2 вещи:

  1. Собрали небольшое семантическое ядро и сгруппировали фразы по категориям каталога.
  2. Проверили и исправили все рекомендации в Яндекс.Вебмастере, добавили сайт в Search Console для ускорения индексации Google и возврата трафика.
  3. Нашли существующие 404-е ошибки, составили список страниц, отдали заказчику на исправление.
  4. Нашли дубли META-информации, настроили шаблоны для меты с помощью SEO-свойств 1С-Битрикс.


  1. Нашли последний рабочий архив (делали после SEO-реанимации).
  2. Развернули на поддомене, проверили, работает.
  3. Заменили сайты.

Прошло несколько дней, проблема повторилась. В этот раз решили провести тщательное исследование.

Артподготовка — Применили тяжелую артиллерию

После сканирования файлов сайта антивирусом AVG было обнаружено 4 файла вирусов-троянов.

Один из файлов отличался размером, после проверки выяснили, что этот файл попал на сайт в то же время, что и не заражённые файлы сайта. Вероятно, этот файл был добавлен ещё в старую версию сайта. Остальные 3 файла были созданы позже. То есть, сайт долгое время был заражен, но это никак не проявлялось.



Отчет антивирусной программы



Содержимое зараженного файла

Далее выполнили ручной анализ в папке /bitrix/admin и найдено еще несколько файлов с вредоносным кодом.

Выполнили поиск по сайту по подстрокам из вирусных файлов, но больше ничего не нашли.



Зараженные файлы находились в ядре битрикса.

Версии возникновения вирусов:

1) в старую версию сайта несколько лет назад был добавлен (вручную или автоматически) файл /bitrix/admin/mobile/bitrixcloud_monitoring_ini.php который использовался злоумышленником для добавления остальных файлов (для спама, рассылки и пр.). Этот файл не является частью ядра 1С-Битрикс.

  1. просканировали файлы (AVG + Касперский) сайта на наличие вирусов;
  2. вручную сделали анализ некоторых подозрительных файлов;
  3. выполнили поиск по подстрокам из зараженных файлов;
  4. удалили все найденные файлы с вредоносным кодом;
  5. усилили безопасность сайта через настройки проактивной защиты;
  6. проверили все файлы tools.php, о котором сообщил сотрудник хостинга (источник рассылки спама):
    /bitrix/modules/catalog/general/tools.php и подобные.
  7. развернули сайт из очищенной резервной копии.
  8. Затаились, стали ждать.

Прошло ровно 5 дней, проблема повторилась. Вирус (или злоумышленник) каждый раз оказывался хитрее нас. На этот раз:

1) в файлы index.php в начало добавляется include файла из /upload, инклудится файл вида favicon- .ico

2) в подключаемом файле после расшифровки оказался код загрузки вирусных плагинов через POST-запрос.

У всех измененных файлов дата изменения устанавливается в find ./ -mtime +6 -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

Зачистка — высадили десант

  1. Восстановили сайт из свежей чистой резервной копии.
  2. Поменяли все пароли от всех хостингов, админок, итд.
  3. Оставили только одного пользователя в админах, остальным ограничили доступ к структуре.
  4. Проверили ядро на наличие изменений.
  5. Удалили все сторонние модули.
  6. Руками и глазами проверили все подозрительные места.

Сайт работает без проблем, попросили хостинг включить отправку почты. Трафик удалось удержать. Выдохнули.


  1. Храните пароли как зеницу ока на бумажке под подушкой.
  2. Обновляйте платформу и всегда продлевайте лицензию 1С-Битрикс.
  3. Если даете доступы фрилансерам или подрядчикам, всегда заводите для них временные пароли и ограничивайте доступ.
  4. Храните резервные копии отдельно от сайта.

Благодарим Евгения Молчанова (ООО “МастерКласс”) за терпение и участие в совместном решении проблемы!


Обновление от 07.12.2012: Если ваш сайт сломали, вам сюда .

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

Полагаем, что информация, изложенная в частых вопросах , известна, локально вирус обнаружен и удалён, все пароли доступа сменены.

Для начала нужно найти все файлы, заражённые вирусом. Искать на дальнем хостинге не всегда возможно (нужен доступ ssh и специальные навыки или другие инструменты), скачать весь сайт на локальный компьютер тоже не лучший вариант (особенно если админка битрикса не работает вместе с системой резервного копирования). Но у нас всегда есть php! Поиск текста в файле по сути задача тривиальная, надо только прикрутить рекурсивное сканирование директорий и вот что получается:

Скрипт показывает форму для ввода кода вируса (или иного текста, который надо найти), затем начинает сканировать все файлы с расширением "php" в текущей папке и подпапках. Список найденных файлов сохраняется в filelist.txt , затем он выводится на экран.
Обратите внимание, скрипт написан для php5, на php4 потребуется заменять функцию file_get_contents

Вот как это выглядит у меня:

Но есть одна проблема: на хостинге не получится за один хит прочитать все php файлы сайта ввиду ограничения ресурсов. Чтобы решение было жизнеспособным надо выполнять его по шагам.

1. Уметь продолжать поиск из любого места, для этого нужно иметь точку входа и всякий раз "проматывать" на неё.
2. После выполнения ряда действий проверять лимит по времени, и если он исчерпан - прерывать выполнение, передав текущую точку себе же.
3. Проверить окончание и показать результат.

  • Архитектурно скрипт немного изменится, теперь сверху будет собственно поиск, а форма ниже. До неё мы дойдём только по окончанию операции.
  • В функцию поиска вставим проверку на истечение времени (10 секунд) и определение пути, на котором прервалась операция в константе BREAK_POINT .
  • Если определена константа BREAK_POINT после вызова функции поиска - показываем форму, которая отправляет запрос со значением текущего пути.
  • Для "прокрутки" к последней папке используем такой алгоритм: отбрасывается последний элемент текущего пути, если оставшаяся часть не является началом искомого пути - идём дальше. Проверка делается до тех пор, пока текущий путь не будет совпадать с искомым.

В итоге получился такой код:

После запуска скрипт выглядит также, но добавился важный функционал пошаговой работы.

В результате получим filelist.txt , содержащий список заражённых файлов.

Резонный вопрос: а почему сразу не удалять вирус?
Потому что есть серьёзная опасность автозаменой потерять данные из своих скриптов.

В чистом виде я умышленно не даю такое решение. Вы должны хорошо осознавать возможные последствия автоматического удаления кода. Изменения такие:

    В форму добавьте кнопку

Определение функции Mark замените на

  • Добавьте соответственно второй аргумент в вызов этой функции

  • Теперь по нажатию кнопки "CURE!" введённый текст будет автоматически удаляться начиная с папки, где лежит сам скрипт, и ниже. Исходные файлы сохраняются с расширением "orig".
    В текстовое поле надо будет ввести паразитный код целиком, иначе он удалится только частично и проблема только усугубится. Будьте предельно внимательны при выполнении такой операции, не забудьте сделать полную резервную копию!

    Немного изменённый скрипт из сообщения можно скачать по ссылке: find_text.php
    По умолчанию автозамена отключена. Чтобы включить - закомментируйте или удалите вторую строчку:

    define('DisableReplace',true);

    Добавил возможность отката автозамены.


    Обновление от 04.09.2012

    Всем добрый день, надеюсь что хоть тут разгадают тайну моего сайта

    Помогите разобраться с этой мифической историей

    13.11.2018, 10:23

    Волшебное исчезновение или падение стилей подвала главной страницы( только главной)
    Почти сутки уже пытаюсь решить эту загадку. возможно ответ очевиден, но мозг у меня уже не.

    Появление/исчезновение элементов и исчезновение при клике на другой
    Привет. Есть такое меню (картинка ниже). Нужно чтобы при клике на ссылку, появлялись текст и.

    Исчезновение данных
    Здравствуйте, Уважаемые специалисты и любители, помогите решить проблему, пожалуйста Ситуация: .

    13.11.2018, 14:49 2

    Вариантов не много.
    Либо кто-то базу поломал какими то действиями. (возможно у вас есть скрипт дырявый)
    Либо жестким дискам на сервере приходит кирдык.

    Бывало такое, когда базу разворачивали руками от одной версии, а файлы от другой. Но b_option таблица старая - так что вероятность этого пренебрежительно мала

    14.01.2019, 11:06 3

    Здравствуйте! А хостер у вас случайно не mtw.ru?
    Просто ситуация аналогичная в то же время.

    14.01.2019, 12:00 4 14.01.2019, 12:12 5 14.01.2019, 12:24 6

    Можно, например:
    1. Сбой восстановления базы из скрипта
    2. Файлы таблиц хранятся в отдельных файлах - к файлу этой таблицы нет доступа пользователю от имени которого работает mysql
    3. Файл таблицы может быть удален.
    4. А вы уверены, что остальные таблицы битрикс там есть?

    Если бы проблема была в паролях, то у вас не было бы права выполнить запрос. И вам бы не выдало ошибку раскрывающую структуру базы данных. Если у вас, конечно, не самопальная сборка mysql сервера. У вас бы была ошибка типа "Access denied for user . "

    Добавлено через 5 минут
    Провел ради интереса эксперимент, подключил битрикс к БД не битриксной. Точна такая же ошибка. Отсюда еще один пример, как такое могло произойти:

    Грохнули БД, потом создали новую пустую

    Что делать?:
    Востанавливать сайт из резервной копии. По хорошему вы (или ваш админ) должны были настроить автоматическое резервное копирование. В идеале (если лицензия активна) в облако.

    Если копии нет - разбираться с хостером на предмет куда делась БД. Я так понимаю у вас виртуальный хостинг. А значит в админке должно что то типа доступа к БД через phpMyAdmin - посмотрите там, хотябы 10 первых таблиц там какие?

    14.01.2019, 14:13 7 14.01.2019, 14:51 8

    Если хостер делает бэкапы - тогда проще. Может есть более актуальная.


    А вообще есть специальный скрипт.

    Помещаете его в корень, и туда же архив. Обращаетесь через браузер к этому скрипты и дальше в режиме мастера внимательно восстанваливаете из архива. Только учтите, что все файлы будут заменены файлами из архива - можете на всякий случай сделать резервную копию средствами хостинга.

    Есть у нас несколько сайтов под управлением всеми любимой CMS Битрикс (так получилось). Работали они себе, никому не мешали. И тут понадобилось добавить в кратчайшие сроки небольшое взаимодействие с внешними сервисами, написанными на Си++.

    Чтобы не возиться с осваиванием новых технологий мы решили воспользоваться модулем Веб-Сервисы (SOAP от Битрикса), входящим в нашу дорогущую редакцию за несколько сотен тысяч рублей (Бизнес Веб Кластер с несколькими сайтами, активно продвигаемый во всех тематических СМИ некоторое время назад) По нему и документация вроде бы была, и пара примеров в интернете.

    Прочитали, скопировали пример, поправили код под наши нужды — заработало. Проблема решена — начальство довольно.

    Недавно нам понадобилось добавить еще одно взаимодействие, несколько более сложное, но по сути тоже элементарное. Клиент должен был отправить нам XML с данными, которые нужно было некоторым образом обработать, а в ответ должна была вернуться информация о результатах обработки. С отправкой XML на сайт проблем не возникло, а вот с ответом ситуация сложилась печальная.

    Вот что написано в документации по поводу используемых типов данных:

    Методы веб-сервиса Методы веб-сервисов всегда: принадлежат классу, реализующему веб-сервис; полностью описывают свои исходящие и входящие параметры; строго соблюдают типы входящих\исходящих данных согласно их описанию. Типы данных Типы данных используемые методами веб-сервиса могут быть двух типов: Простые типы — string, bool, boolean, int, integer, double, float, number; Сложные типы — массивы, структуры (сериализуются в ассоциативные массивы), классы (сериализуются в экземпляры классов); Описываются с помощью structTypes, classTypes. Типы данных описываются в трёх местах в описателе веб-сервиса CWebServiceDesc:

    Для нашей задачи подходил либо массив/структура, либо строка с текстом ответной XML(если с массивом не получилось).

    Для того чтобы вернуть массив, нужно описать его методом structTypes(), опишем.

    Далее напишем пустой метод с одним входящим параметром, возвращающий ассоциативный массив описанной ранее структуры.

    И сразу натыкаемся на костыль: оказывается, чтобы добавить в корневой элемент XML несколько дочерних элементов с одинаковым именем, нужно сформировать массив следующим образом:

    Где $i — счетчик элементов, а ELEMENT_NAME — имя элемента. Нигде в документации об этом не написано. Мало того, на форуме также никакой информации.

    Ну да ладно, это можно пережить. Написали мы, значит, такой тестовый метод и пробуем его протестировать средствами, которые нам предоставляет битрикс. Выглядят они примерно вот так:


    Пример с сайта Битрикса

    Вводим наш фиктивный параметр и в ответ получаем xml нужного нам формата. Казалось бы, всё хорошо.


    Но разработчики приложения на C++ почему-то говорят что ничего не приходит. Не беда, попробуем обратиться сами к себе написав простенькую страничку для теста:

    Здесь используется битриксовая функция mydump, которая является аналогом var_dump, только возвращает строку.

    Нажимаем на кнопочку тест и получаем следующее:

    Т.е. реально ничего не пришло. Пробуем воспользоваться fiddler’ом на стороне разработчиков клиента на C++ и получаем подтверждение нашим догадкам. Вот ответная XML от веб сервиса:

    Ладно, может у нас где-то ошибка. попробуем начать с простого — вернём строку.

    Для возврата строки упростим всё до максимума.

    При тестировании через средства битрикса опять всё хорошо, но разработчики клиента опять жалуются на проблемы — теперь им приходит только первый символ из строки.

    Пробуем обратиться сами к себе (код тестовой странички менять не нужно) Получаем:

    Т.е. проблема подтверждается и мы реально можем получить только первый символ из строки.

    Можно, это хорошо. Далее идёт долгое обсуждение того же что я написал вверху (только код был от рабочего метода). В итоге после моего сообщения:

    Попробовал обратиться сам к себе через битриксовый клиент SOAP и получил ту же проблему. Если поменять тип возвращаемого значения на string, то можно получить только один первый символ из всей строки. При этом integer, передать удаётся. p.s. Ошибки получаются нормально, текст и коды читаются.

    Получаем следующий ответ:

    Добрый день! Обсуждали вопрос с разработчиками. Модуль представляет из себя набор классов, которые были разработаны для расширения внутренних механизмов продукта. Они обособлены в виде модуля чтобы разработчики могли сами расширять текущую реализацию. Что теперь и происходит. Фактически, мы можем оказывать поддержку на уровне стандартного функционала продукта, где используется этот модуль. Ваша задача является частной разработкой и, к сожалению, мы не сможем более погружаться в этот вопрос. Вам необходимо продолжить разработку собственными силами используя наш модуль, библиотеку php_soap или альтернативные решения.

    Немного обалдев, я уточнил:

    Т.е. модуль веб сервисов от битрикса не подразумевает, что методы могут возвращать текстовые данные? Так? Проблема как раз в том, как работает ваш модуль SOAP. В том коде, что я предоставил, нет ничего выходящего за рамки изложенного в документации примера

    Ответ был удручающим:

    Как мы говорили выше, мы не поддерживаем решения, которые выходят за рамки работы стандартного функционала нашего модуля. Рекомендации по дальнейшим действиям мы привели в предыдущем сообщении, с сожалению больше ничего предложить в рамах ТП не можем.

    После последней попытки задать вопрос:

    Покажите мне участок кода, в котором не используется стандартный функционал? Вы не можете объяснить почему ваш SOAP не может вернуть строку?

    Был получен еще более печальный ответ:

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

    Раз уж это поведение является нормальным, я попросил следующее:

    Тогда поправьте документацию. В ней написано, что простые типы могут быть возвращены методами класса.

    После чего был получен вот такой ответ:

    Автоматическое сообщение о создании заявки в разработку На основе информации из данного обращения была создана заявка в отдел разработок. Категория: Ошибки. Критичность: Нормальная. Номер обращения в разработку: 25208.

    Заявка повисела недельку и была закрыта без изменений

    Т.е. долбайтесь сами с нашим SOAP, мы вам ничем не поможем.

    Сейчас я всё переписываю на php soap. А про разработчиков битрикса могу только нехорошее сказать.

    2 комментария

    Нужно будет протестить. С массивом я так пробовал — не получилось. Посмотрим как со строкой будет.

    Рассмотрим ситуацию, к примеру на сайт необходимо добавить блок или код выданный счетчиком поисковой системой, или к примеру код для подключения вывода объявлений из систем контекстных объявлений Yandex.Директ или Google.Adsense.

    Для этого в Bitrix существует специальный функционал: bitrix main include, а именно Компонент включаемой области.

    Рассмотрим функционал bitrix main include


    Для того чтобы изменить данный телефон из примера, достаточно авторизоваться и перейти в режим правки сайта:


    Вход в админку битрикс


    Шаг 3. Переходим в режим правки:



    Шаг 4.

    Шаг 6.

    НО, существует задача к примеру ДОБАВИТЬ такую область, а не изменить, тут предстоит поправить шаблон сайта или конкретной страницы.

    Задача №1. Добавить область для конкретной страницы и чтоб в этой области была определенная информация, меняя которую в одном месте, автоматически она менялась на всех страницах где эта область подключена. Такого рода задачи бывают в том случае, к примеру когда необходимо вывести информацию об акции на разных страницах сайта и даже на разных его разделах. Изменяя текст в одном месте он меняется везде, к примеру в тексте во включаемой области содержится период проведении акции и необходимо изменить его интервал, таким образом, если бы не включаемая область, то пришлось бы везде где прописана эта акция, проходить и менять интервал к примеру с 1 января по 31 января на с 1 февраля по 28 (29)февраля на каждой странице, а не в одном месте. Итак для этого нам понадобится собственно настроить и внедрить на страницу компонент включаемой области bitrix:main.include.





    После этого область появится у вас в текстовом редакторе и автоматически выведется область настроек данного компонента:


    Для того чтобы, как я и писал ранее, вывести определенный текст этим компонентом, в меню настроек мы должны выбрать:

    Показывать включаемую область: Из файла

    Путь к файлу области ( для удобства все файлы для включаемых областей я рекомендую складывать в одном месте, если это не относится непосредственно к шаблону сайта, поэтому я создаю в админ-интерфейсе папку include и в ней уже находятся все файлы используемые для подключения к страницам ):/include/inc_area_example.php

    Шаблон области по умолчанию:[standard.php] Стандартная страница


    После этого нажимаем кнопку сохранить. Включаемая область готова. остается только ее наполнить содержимым. Т.е. текстом. Для этого наводим на красную точку в квадратике (это как раз и есть наша включаемая область) и в выпадающем меню нажимаем «Добавить область«.


    После этого автоматически создается и папка и включаемый файл с такими названиями как мы указали в настройках, т.е. папка: include с файлом inc_area_example.php. Откроется редактор включаемой области доступный для правки.


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


    Таким образом вы добавили область текста на странице сайта.

    Задача 2. Добавить включаемую область на сайт в шаблон слева под левым меню, как показано на примере:

    • О нас → История
    • О нас →Документы
    • О нас →Реквизиты
    • О нас →Сотрудники
    • О нас →Вакансии

    В структуре сайта это будет выглядеть так:

    • /o_nas/history/
    • /o_nas/licenses/
    • /o_nas/requisites /
    • /o_nas/staff/
    • /o_nas/vacancy/

    Для того чтобы вывести определенный контент в заданном месте шаблона сайта во всех этих разделах, нам необходимо пройти в режим правки шаблона сайта, это можно сделать через систему администрирования сайта, или если есть доступ к FTP серверу, то можно и через него. Остановимся на первом варианте.

    Итак переходим в режим администратора и включаем режим правки как я уже это описывал ранее по шагам (Шаги выше 1,2 и 3).

    Далее переходим в режим правки шаблона сайта и делаем это очень аккуратно, чтобы не повредить верстку сайта.



    В области … мы видим подключение компонента вывода левого меню и только его, нам необходимо просто добавить под это меню свою включаемую область, т.е. код для ее вывода. Для этого открываем наш сайт в другой вкладке браузера

    Заходим на любую страницу сайта. Переходим в режим редактирования страницы сайта


    Далее также выводим настройки включаемой области




    В настройках компонента включаемой области bitrix:main.include выбираем пункты:

    Показывать включаемую область: для раздела

    Суффикс имени файла включаемой области: inc_area_right

    Рекурсивное подключение включаемых областей разделов: галочка



    Вы можете отсюда скопировать данный код или создать свой как описано выше.

    Читайте также:

    Пожалуйста, не занимайтесь самолечением!
    При симпотмах заболевания - обратитесь к врачу.