Что означает эта конструкция
base64_decode превращает закодированную строку обратно в текст, а eval выполняет этот текст как PHP-код. Вместе они позволяют спрятать любой код так, что его не найти поиском по словам вроде system или mail. Легальные плагины почти никогда так не делают — у них нет причин прятать собственный код.
Встречаются и вариации с другими функциями-обёртками:
eval(gzinflate(base64_decode('...')));
eval(str_rot13(gzuncompress(base64_decode('...'))));
$x = "base"."64_"."decode"; eval($x('...'));
preg_replace('/.*/e', '...', ''); // старый трюк для PHP 5
assert($_POST['k']);
@include "\x2e\x2e/\x63\x61\x63\x68\x65/\x69\x6d\x67\x2e\x69\x63\x6f";
Как отличить вредоносный код от легального
Признаки вредоносного кода:
- строка длиной в тысячи символов в одну линию;
- код стоит в самом начале файла перед
<?phpоригинала или после закрывающего тега; - имена переменных из случайных символов:
$O00OO0,$_xz9; - сборка имён функций из кусочков строк или шестнадцатеричных кодов;
- выполнение данных, пришедших из
$_POST,$_GET,$_COOKIEили$_REQUEST; - подключение файлов с расширениями
.ico,.jpg,.txtчерезinclude.
При этом сама по себе функция base64_decode — нормальная: её используют для работы с изображениями, API и шифрованием. Подозрительна именно связка «расшифровать и выполнить».
Как безопасно посмотреть, что делает код
Безопасный способ — заменить eval на вывод текста и выполнить расшифровку отдельно, на локальном компьютере. Например, если код имеет вид eval(gzinflate(base64_decode('...'))), расшифровать его можно так:
<?php
$s = '...'; // строка из вредоносного файла
echo gzinflate(base64_decode($s));
Часто внутри оказывается ещё один слой шифрования — повторяйте, пока не увидите читаемый PHP. Обычно это веб-шелл, загрузчик спам-страниц, редирект или скрипт рассылки.
Как найти все заражённые файлы
Где один заражённый файл, там обычно десятки. Поиск по SSH:
# классические обёртки
grep -rlE "eval\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13)" --include=*.php .
# выполнение пользовательских данных
grep -rlE "(eval|assert)\s*\(\s*(stripslashes\()?\s*\\\$_(POST|GET|REQUEST|COOKIE)" --include=*.php .
# очень длинные строки — типичный признак обфускации
grep -rlE ".{5000,}" --include=*.php . | grep -v "/vendor/"
# include файлов с расширениями картинок
grep -rlE "include.*\.(ico|jpg|png|gif)['\"]" --include=*.php .
Затем отсортируйте найденные файлы по дате изменения — это поможет понять, когда началось заражение и какие ещё файлы изменились в тот же день.
Как вылечить файлы
- Файлы ядра CMS, плагинов и тем — не правьте вручную, замените оригиналами из официального дистрибутива той же версии.
- Ваши собственные файлы — удалите вставку, сравнив с резервной копией или системой контроля версий.
- Файлы, которые целиком вредоносные, — удалите.
После чистки обязательно найдите точку входа и смените все пароли — иначе код вернётся. Пошаговый план — в статье «Взломали сайт на WordPress: что делать».
Частые вопросы
В лицензированном плагине есть base64. Это вирус?
Некоторые коммерческие плагины кодируют свой код для защиты от копирования, обычно с помощью ionCube или похожих систем. Сравните файл с оригиналом из архива, скачанного у разработчика. Если отличается — файл изменён.
Я удалил строку с eval, сайт сломался. Что делать?
Возможно, вы удалили часть легального кода вместе со вставкой. Восстановите файл из оригинального дистрибутива, а не правьте вручную.
Можно автоматически следить за такими вставками?
Да. FYZI Shield каждый день проверяет файлы на подобные конструкции и сообщает о любом изменении файлов ядра, плагинов и тем.