Как вылечить php файлы

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

Как происходит заражение

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

Какие файлы заражаются

  1. Заражаются все файлы с именем INDEX (index.php, index.html и т.д.)
  2. Заражаются все файлы JS (java2.js, Js.js и т.п.)
  3. Заражается файл .htaccess
  4. Заражается файл phpshop/inc/footer.inc.php Если на сайте появляются ссылки на сторонние ресурсы, то в него прописывается подключение через функцию include или include_once. Следует удалить эту строку.
  5. Заражается файлы phpshop/templates/имя_шаблона/main/index.tpl (shop.tpl). В конец этих файлов прописывается код @php eval(….); php@. Следует удалить этот код.

Признаки заражения

  1. Неработающая панель администрирования
  2. При загрузке сайта в строке состояния появляется запись загрузки файлов с чужого сайта
  3. Блокировка сайта google.ru
  4. Перенаправление сайта при заходе на него с мобильного телефона и предложение обновить программу на телефоне
  5. Добавление ссылок на сторонние ресурсы

Как лечиться

  1. Проверить свой компьютер и остальные компьютеры, имеющее контакт с сайтом антивирусом. Хотим уточнить, что не все антивирусы находят такие вирусы. PHPShop Software рекомендует использовать антивирус Avira (https://www.avirus.ru/).
  2. Заменить все FTP, SSH пароли от сайта.
  3. Для хранения паролей использовать утилиту KeePass Password Safe (https://keepass.info/).
  4. Для соединения с FTP использовать легальное профессиональное ПО, например CuteFTP (https://www.globalscape.com/products/ftp_clients., хранящая свои пароли в зашифрованном виде.
  5. Не хранить пароли на бесплатных почтах (Mail.ru и т.д.).
  6. Восстановить бекап файлов из архива на хостинге или загрузить файлы PHPShop заново на сервер. Загружать нужно текущую версию, установленную на вашем сайте из архива (дается при покупке ПО).
  7. В случаи перенаправления телефоном достаточно заменить файл .htaccess на оригинальный
  8. Воспользоваться скриптом для поиска вирусов: [Ссылка]
  9. Обновить версию PHP на сервере до 5.3 или выше.
  10. Всегда менять FTP пароли после передачи их третьим лицам, в том числе и технической поддержки. Для третьих лиц использовать отдельные FTP аккаунты для дальнейшего отслеживания возможных путей утечки FTP паролей в логах сервера.
  11. С помощью утилиты SiteLock создать дополнительный пароль на административную панель для защита от кражи и перебора паролей.
  12. Включить режим защиты от использования php кода в шаблонах в файле phpshop/inc/config.ini
    [function]
    guard=”true”;
    allowed=”leftCatal,isset,getElementById,empty”;
    deny=”include,include_once,require,require_once,file,chmod”;

  13. Включить режим защиты в .htaccess

    # Запрет вызовы через браузер сторонних опасных файлов шаблона
    # default – off
    RewriteCond %{REQUEST_URI} ^(/phpshop/templates/(.*))
    RewriteCond %{REQUEST_URI} !((.*).(gif|jpg|swf|png|jpeg|js|css|GIF|JPG|PNG|JPEG))$
    RewriteRule .* – [F]

    # Запрет вызовы через браузер сторонних опасных загружаемых файлов
    # Накладывает ограничение для загрузки файлов с другими расширениями
    # default – off
    RewriteCond %{REQUEST_URI} ^(/UserFiles/(.*))
    RewriteCond %{REQUEST_URI} !((.*).(gif|jpg|swf|png|jpeg|js|css|GIF|JPG|PNG|JPEG|rar|zip))$
    RewriteRule .* – [F]

    # Запрет выполнения php в загружаемых папках
    # default – off
    RewriteCond %{REQUEST_URI} ^((/UserFiles/(.*).(phpd?|phtml))|(/phpshop/templates/(.*).(phpd?|phtml))|(/phpshop/admpanel/csv/(.*).(phpd?|phtml)))$
    RewriteRule .* – [F]

    • Проставить параметры доступа к файлам CHMOD согласно инструкции по установке:

    • Установите опцию CHMOD 777 (UNIX сервера) для папок:

      UserFiles/Image
      UserFiles/File
      phpshop/admpanel/csv
      files/price
      phpshop/admpanel/dumper/backup

    • На все остальные папки права должны стоять CHMOD 755. На все остальные файлы права должны стоять CHMOD 644
  14. 14 Поставить дополнительный пароль на папку авторизации через .htaccess
    1. Для паролирования директорий используется фирменная утилита SiteLock
    2. Для ручного проставления паролей следуйте инструкции:
    3. Создать файл /phpshop/admpanel/.htaccess с содержанием:

      AuthName “Member’s Area”
      AuthType Basic
      AuthUserFile /home/username/username.ru/.htpasswd
      require valid-user

    4. Создать файл /home/username/username.ru/.htpasswd Для генерации логина и пароля воспользуемся онлайн сервисом: htaccesstools.com. Результат записать в файл .htpasswd
    5. На хоcтингах с панелью управления Direct Admin, в том числе и на хостинге PHPShop Host, используется исключительно интерфейс файлового менеджера (находится в личном кабинете клиента (имя_сайта:777). Для паролирования следует через файловый менеджер перейти в папку phpshop/, найти в списке папок “admpanel” и слева от нее нажать ссылку “Protect”, после чего откроется диалог создания логина и пароля для защиты этой папки.

Лечение от ссылок в БД

Если вирус прописал рекламные ссылки в базу данных, то лечение выполняется по инструкции:

Читайте также:  Как вылечить простуду народными средствами ребенку

  1. Определить код вируса в карточке товара. Для примера возьмем код ссылки

    <center><script async src=”//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”></script><!– big –><
    ins class=”adsbygoogle” style=”display:inline-block;width:336px;height:280px”
    data-ad-client=”ca-pub-6920992154252242″ data-ad-slot=”4175090345″></ins><script>
    (adsbygoogle = window.adsbygoogle || []).push({});</script></center>

  2. Определить кол-во символом этого кода, для этого можно воспользоваться vipkontent.ru. Данный код содержит 335 символов. Дальше будем использовать значение 336(335+1)
  3. Обязательно сделать бекап БД (База – Резервные копии). Если чистка кода не удастся, то будет возможность откатить изменения назад.
    1. Выполнить запрос к БД:

    2. Ссылки присутствуют в товарах
      update phpshop_products set content = SUBSTR(content, 336, 100000);

    3. Ссылки присутствуют в каталогах
      update phpshop_page set content = SUBSTR(content, 336, 100000);

    4. Ссылки присутствуют в страницах
      update phpshop_categiries set content = SUBSTR(content, 336, 100000);

    5. Если ссылки присутствуют в самом конце описания:
      update phpshop_products set content = REPLACE(content, ‘содержание ссылок’, ‘ ‘);
  4. Обязательно поменять пароль к MySQL через панель управления хостингом. Новый пароль от MySQL вписать в конфигурационный файл phpshop/inc/config.ini (pass_db=”XXXXX”)
  5. Для очень старых версий PHPShop(до 2008 года) проверить , есть ли выбор языка на странице авторизации /phpshop/admpanel/. В них присутствует уязвимость, дающая возможность получить параметры подключения к БД из config.ini.
  6. Если таковая имеется, то отредактировать файл /phpshop/admpanel/index.php.Заменить строку require(“./language/”.$Lang.”/language.php”); на require(“./language/russian/language.php”);

Способы защиты

  1. Установить обновления для версий Start и Enterprise, включающие в себя модули антивируса. Активировать модуль Guard и поставить в его настройках “Расширенный режим”. Модуль Guard делает базу контрольных сумм файлов и несколько раз в день проверяет файлы на сервере, если какой-то файл изменился не по вашей милости, то следует сразу проверить его на вирусы. После каждого обновления, замены файлов/шаблонов следует делать обновление контрольных сумм файлов для исключения ложного срабатывания антивируса на ваши же изменения.
  2. При обнаружении вируса воспользоваться подсказкой встроенного антивируса и восстановить файлы из созданного антивирусом бекапа.
  3. Использовать сложные комбинации логинов и паролей на фтп. Производить смену паролей каждый месяц.
  4. При появлении на сайте вирусов, особенно ссылок на внешние ресурсы следует провести комплексный анализ всех файлов сервере через утилиту AI-Bolit. В настройках выставить расширенный режим поиска и после его окончания предоставить отчет нашей технической поддержки. Если будут обнаружены вирусы, то поддержка укажет файлы, которые нужно будет удалить с сервера. При расширенном режиме AI-BOLIT будет показывать много подозрительных на его взгляд включений в файлах. В 99.9% случаем это ложное срабатывание на одноименные функции и методы в вирусах. Решение о заражении вирусом может принять только специализированный специалист из нашей поддержки, знакомый с архитектурой ПО и его файловой структурой.

Если не помогает

Если после всех выполненных манипуляциях для защиты, вирус опять появляется, то возможно 2 варианта такой ситуации:

  1. На сервере в этом же аккаунте находятся другие зараженные сайты, имеющие доступ к вашим файлам. Следует перенести проект на отдельный аккаунт.
  2. Злоумышленниками прописан код в ваши файлы, который не может найти антивирус. Тогда следует полностью заменить ваши файлы на заводские из самой последней версии:
    1. Скачать свежую версию из центра загрузки. Требуется версия для разработчиков в виде архива.
    2. Из старых файлов оставить лишь

      UserFiles
      phpshop/templates/имя вашего архива
      phpshop/inc/config.ini (взять параметры подключения к БД)

    3. Загрузить их архива, скаченного на шаге 1 новые файлы.
    4. Добавить в php.ini запрет вызова функции chmod и запрет allow_url_fopen.

    Кто виноват

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

    Ответственность полностью ложится на пользователя и его халатного отношения к антивирусной защите хранилища базы паролей доступа.

Источник

Добрый день, уважаемые Хабраюзеры!

Некоторое время назад, около месяца, на сервере нашей компании появился вирус. На одном из крупных проектов были поражены все *.js файлы. Ситуация обычная — в конец файлов был дописан вредоносный код. Яндекс выдавал предупреждение о заражении сайта и в техотдел пришло задание очистить его. Ситуация разрешилась достаточно быстро, проект был выгружен с чистого репозитория в продакшн, пароли сменили.

Однако вскоре со всех отделов компании в техотдел стали поступать жалобы о заражённых сайтах. Менеджерам жаловались клиенты, сеошники трубили что сайты теряют позиции. Началась настоящая эпидемия. Помимо *.js файлов, заражению подверглись так же *.php файлы, в конец которых был дописан код:

Читайте также:  Как вылечить заложенность носа и насморк в домашних условиях быстро

echo ‘https://somedomain.com/style.js’;

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

Сервер потихоньку стал «выздоравливать» а сайты возвращаться в яндекс. Однако кроме более сотни сайтов клиентов на нашем сервере, есть клиенты использующие сторонние хостинги. Доступ по фтп, никакой командной строки и shell. Практически на всех сайтах используется самописная CMS (написанная N-ое количество лет назад) в связке с fckeditor’om или старыми версиями ckeditor’ов. В файл менеджере ckfinder’e проверка авторизованности реализована простым return true; Используй нехочу. Стоит также упомянуть что Множество заражённых *.js файлов выгрузкой чистого репозитория не излечить. Git на таких сайтах нами не используется, а большая часть бэкапов на хостингах хранится максимум 7 дней. А в виду того что сайты расположенные на сторонних хостингах, нами практически не мониторятся, все бэкапы так же были заражены.

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

=Array.prototype.slice.call(arguments).join(“”),

Он и был выбран для поиска вхождений по файлам. Были проверены Jquery библиотеки 1.6.3 и 1.7.2 и в исходном коде совпадений не было обнаружено. Значит последовательность можно было использовать.

Чтобы не возиться вручную с несколькими десятками *.js файлов на каждом сайте, было решено написать скрипт на php. Он должен сканировать все указанные ему файлы на предмет искомой строки. Для расширения кругозора, так сказать, было решено не использовать exec(), system() команды или, к примеру, библиотеку phpseclib. Алгоритм прост до безобразия: Скрипт сканирует все директории начиная от заданной, в поисках указанной строки в файлах поиска. Перед внесением изменений, скрипт бэкапит файл (ну всё же мало ли чего) и удаляет строку, в которой присутствует искомая подстрока. Построчная работа была выбрана в виду того, что вирус в файл записывался в одну строку.

Приведу пример кода вируса в *.js файле: pastebin.com/J0zRduQw

Разбирать его я не стал, кому интересно — в интернете много примеров разбора обфусцированного кода. Поэтому перейду сразу к коду сканера.

<?
/*
———————————————————————————-
dScaner Class – START
———————————————————————————-
*/

/*
*
* Класс – dScaner для сканирования директорий на наличие вредоносного кода в
* указанных типах файлов
*
* Разработчик: Денис Ушаков
* Дата разработки: 03-04-2012
* Версия разработки: 0.0.3
*
*/

Class dScaner {

// преобразуем входной параметр в массив
// $get_str – список параметров
// $separator – разделитель параметров в списке
function request($get_str, $separator)
{
if (isset($get_str) && !empty($get_str))
{
// эксплоадим строку в массив и возвращаем его
$obj = explode($separator, $get_str);
return $obj;
}
else
{
return false;
}
}

/*
*
* Функция поиска в файлах вхождения заданной строки:
*
* $this->find($path, $files_allowed, $requested_string);
*
* $path – путь до директории, от которой отталкиваться при сканировании
* $files_allowed – список файлов, которые подвергаются сканированию
* $requested_string – строка поиска
*
*/
function find($path = ‘./’, $files_allowed, $requested_string)
{
// исключаемые ссылки на директории и файлы, которые будут игнорироваться
$dir_disallow = array(‘.’, ‘..’, ‘.htaccess’, ‘.git’);

if(is_dir($path))
{
$temp = opendir($path);
while (false !== ($dir = readdir($temp)))
{
if ((is_dir($path . $dir)) &&
(!in_array($dir, $dir_disallow)) )
{
// если директория – сканируем её
$sub_dir = $path . $dir . ‘/’;
$this->find($sub_dir, $files_allowed, $requested_string);
}
elseif ((is_file($path . $dir)) &&
(!in_array($dir, $dir_disallow)) &&
(strpos($dir, $files_allowed) == true) &&
(strpos($dir, ‘_BACKUP’) == false) )
{
// Если файл
// получаем полный путь до него
$in_dir_file = $path . $dir;
// считываем файл в строку
$temporary_file = file_get_contents($in_dir_file);
// флаг найденного вхождения искомой строки
$file_founded = false;

// разбиваем файл на строки
$tf_strings = explode(“n”, $temporary_file);
// обрабатываем каждую отдельно
foreach ($tf_strings AS $item)
{
$item = strval($item);
// если в строке есть вхождения искомого запроса
if (strpos($item, $requested_string) !== false)
{
$file_founded = true;
}
}
// если в файле найдена строка
if ($file_founded)
{
// выводим путь до файла в котором найдено вхождение
print “<span style=’display:block;
padding:5px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:-15px;’>” . $in_dir_file . ” – в файле обнаружена искомая строка.<br>
</span><br>”;
}
}
}
closedir($temp);
}
}

Читайте также:  Таблетки как вылечить цистит

/*
*
* Функция сканирования вредоносного кода:
*
* $this->scan($path, $files_allowed, $requested_string);
*
* $path – путь до директории, от которой отталкиваться при сканировании
* $files_allowed – список файлов, которые подвергаются сканированию
* $requested_string – строка, по которой определяется наличие вредоносного кода
*
*/
function scan($path = ‘./’, $files_allowed, $requested_string)
{
// исключаемые ссылки на директории и файлы
$dir_disallow = array(‘.’, ‘..’, ‘.htaccess’, ‘.git’);

if(is_dir($path))
{
$temp = opendir($path);
while (false !== ($dir = readdir($temp)))
{
if ((is_dir($path . $dir)) &&
(!in_array($dir, $dir_disallow)) )
{
// если директория – сканируем её
$sub_dir = $path . $dir . ‘/’;
$new_parent_dir = $path . $dir;
$this->scan($sub_dir, $files_allowed, $requested_string, $new_parent_dir);
}
elseif ((is_file($path . $dir)) &&
(!in_array($dir, $dir_disallow)) &&
(strpos($dir, $files_allowed) == true) &&
(strpos($dir, ‘_BACKUP’) == false) )
{
// Если файл
// получаем полный путь до него
$in_dir_file = $path . $dir;
// считываем файл в строку
$temporary_file = file_get_contents($in_dir_file);
// флаг бекапа файла
$create_backup = false;

// разбиваем файл на строки и считываем каждую отдельно
$tf_strings = explode(“n”, $temporary_file);
// индекс строки файла
$str_index = 0;
// каждую строку обрабатываем отдельно
foreach ($tf_strings AS $item)
{
$item = strval($item);
if (strpos($item, $requested_string) !== false)
{
// если в строке есть вхождения искомого запроса
// флаг бекапа файла, в котором найден вредоносный код
$create_backup = true;
// удаляем всю строку с вредоносным кодом
unset($tf_strings[$str_index]);
}
$str_index++;
}

// создаём бэкап
if ($create_backup)
{
// меняем права в папке в которой находимся чтобы иметь возможность писать в неё
chmod($path, 0777);
// формируем имя БЭКАПа файла
$temp_file_backup = $in_dir_file.’_BACKUP’;
// сохраняем БЭКАП файла рядом с исходным
file_put_contents($temp_file_backup, $temporary_file);
// собираем очищенный файл в строку
$scanned_file = implode(“n”, $tf_strings);
// сохраняем очищенный файл
if (file_put_contents($in_dir_file, $scanned_file))
{
// перезаписали удачно
print “<span style=’display:block;
padding:5px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:-15px;’>” . $in_dir_file . ” – Файл очищен. (+ BACKUP) <br>
</span><br>”;
}
else
{
// перезапись не удалась
print “<span style=’display:block;
padding:5px;
border:1px solid #822121;
background-color:#ea7575;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:-15px;’>”.$in_dir_file .” – Файл НЕ очищен.
</span><br>”;
}
// меняем права в папке в которой находимся обратно на 755
chmod($path, 0755);
}
}
}
closedir($temp);
}
}

/*
*
* Функция восстановления БЭКАПОВ файлов
*
* $this->restore_backups($path, $files_allowed);
*
* $path – путь до директории, от которой отталкиваться при восстановлении
* $files_allowed – список файлов, которые подвергаются восстановлению
*
*/
function restore_backups($path = ‘./’, $files_allowed)
{
// исключаемые ссылки на директории и файлы
$dir_disallow = array(‘.’, ‘..’, ‘.htaccess’, ‘.git’);
if(is_dir($path))
{
$temp = opendir($path);
while (false !== ($dir = readdir($temp)))
{
if ((is_dir($path . $dir)) &&
(!in_array($dir, $dir_disallow)) )
{
// если директория – сканируем её
$sub_dir = $path . $dir . ‘/’;
$this->restore_backups($sub_dir, $files_allowed);
}
elseif ((is_file($path . $dir)) &&
(!in_array($dir, $dir_disallow)) &&
(strpos($dir, $files_allowed) == true) )
{
// Если файл
// получаем полный путь до него
$in_dir_file = $path . $dir;
if (is_file($in_dir_file.’_BACKUP’))
{
// БЭКАП существует, получаем его содержимое
$temporary_file_from_backup = file_get_contents($in_dir_file.’_BACKUP’);
// восстанавливаем бэкап файла
if (file_put_contents($in_dir_file, $temporary_file_from_backup))
{
// удаляем бэкап
unlink($_SERVER[‘DOCUMENT_ROOT’].’/’.$in_dir_file.’_BACKUP’);
// бэкап восстановили
print “<span style=’display:block;
padding:5px;
border:1px solid #1f4f18;
background-color:#d5f5ce;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:-15px;’>”.$in_dir_file .” – восстановлен.
</span><br>”;
}
else
{
// бэкап НЕ восстановили
print “<span style=’display:block;
padding:5px;
border:1px solid #822121;
background-color:#ea7575;
font-size:12px;
line-height:16px;
font-family:tahoma, sans-serif;
margin-bottom:-15px;’>”.$in_dir_file .” – НЕ восстановлен.
</span><br>”;
}
}
}
}
closedir($temp);
}
}
}

/*
———————————————————————————-
dScaner Class – END
———————————————————————————-
*/

?>

Код класса довольно подробно закоментирован, вопросов возникнуть не должно.
Пример использования (первый параметр — стартовая директория поиска, второй — тип файлов, учавствующих в поиске, третий — строка поиска):

Создаём экземпляр сканера.

$dron = new dScaner;

Прежде чем что-то перезаписывать, стоит посмотреть, есть ли файлы удовлетворяющие условиям поиска.

$dron->find(‘./’, ‘.js’, ‘=Array.prototype.slice.call(arguments).join(“”),’);

Запускаем зачистку.

$dron->scan(‘./’, ‘.js’, ‘=Array.prototype.slice.call(arguments).join(“”),’);

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

$dron->restore_backups(‘./’, ‘.js’);

Сканер был протестирован на многих сайтах и отрабатывает как нужно, единственная проблема которая возникла у нас на сервере — права владельца файла. Нужно чтобы owner’om файла был www:www. В среднем, на один сайт с нескольким десятком *.js файлов уходило от 5-10 до 20 секунд. И привожу список хостингов, на которых скрипт был успешно протестирован: infobox, agava, jino, mchost, hc. Из всех, самым замедленным был mchost, на остальных всё работало достаточно шустро.

P.S. Скрипт не претендует на панацею от вирусов, разработан под конкретный случай заражения и под каждый последующий требует доработки. Однако с поставленной задачей отлично справляется. Надеюсь, кому-то будет полезен.
Бест регардс!

Источник