Почему важна безопасность?
На определённом этапе своего развития любой сайт в интернете сталкивается с проблемами безопасности: это может быть внезапный "взлом" с хищением данных с целью получения денежной компенсации от владельца сайта; может быть бот-атака с намерением заразить сайт вирусом; возможен резкий всплеск спама и т.д. Только за 2022 год количество кибератак на российские сайты выросло на 80%.
По нашим наблюдениям, практически сразу же после открытия сайта в интернете на него начинают поступать вредоносные атаки. Их легко можно обнаружить в логе доступа вашего веб-сервера (т.н. access log). Эти запросы представляют собой бесконечное непрекращающееся сканирование на предмет обнаружения какой-либо уязвимости. И как только это произойдёт – на сайт будет загружен вирус, ждущий своей активации. До момента этой активации может пройти достаточно долгое время (вплоть до полугода-года и более). Расчёт тут, на наш взгляд, состоит в том, чтобы у владельца сайта не осталось "хороших" резервных копий, сделанных до момента заражения.
Для наглядности приведём лишь небольшой список запросов, которые совершают скрипты, ищущие уязвимости на вашем сайте:
GET /.git/config GET /s/733323e293e2930313e22363/_/;/META-INF/maven/com.atlassian.jira/jira-webapp-dist/pom.properties GET /info.php GET /.env GET /server-status GET /.vscode/sftp.json GET /config.json GET /test.php POST /phpinfo GET /index.php?s=/Index/\\x5Cthink\\x5Capp/invokefunction&function=call_user_func_array&vars[0]=md5&vars[1][]=HelloThinkPHP21 GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php Gh0st\\xAD\\x00\\x00\\x00\\xE0\\x00\\x00\\x00x\\x9CKS``\\x98\\xC3\\xC0\\xC0\\xC0\\x06\\xC4\\x8C@\\xBCQ\\x96\\x81\\x81\\x09H\\x07\\xA7\\x16\\x95e&\\xA7*\\x04$&g+\\x182\\x94\\xF6\\xB000\\xAC\\xA8rc\\x00\\x01\\x11\\xA0\\x82\\x1F\\x5C`&\\x83\\xC7K7\\x86\\x19\\xE5n\\x0C9\\x95n\\x0C;\\x84\\x0F3\\xAC\\xE8sch\\xA8^\\xCF4\'J\\x97\\xA9\\x82\\xE30\\xC3\\x91h]&\\x90\\xF8\\xCE\\x97S\\xCBA4L?2=\\xE1\\xC4\\x92\\x86\\x0B@\\xF5`\\x0CT\\x1F\\xAE\\xAF] GET /?XDEBUG_SESSION_START=phpstorm … и др.
Если скрипту-сканеру удаётся понять, на основе какой системы создан сайт, то он может оптимизировать свою активность, адаптировав свои запросы конкретно под неё.
Например, 26 мая 2022 компания 1С-Битрикс сделала рассылку по своим клиентам с рекомендацией установить последние обновления системы безопасности, т.к. в одном из модулей была найдена (и оперативно устранена сотрудниками компании) уязвимость. Однако проверка наличия этой уязвимости была включена в базу подобных скриптов-сканеров. И сайт, не установивший обновления, может быть подвергнут атаке.
Какое есть решение?
Отметим, что построение многоуровневой защищённой системы с различными контурами – достаточно ёмкая и дорогая задача из области информационной безопасности. Но один из её уровней – это межсетевой экран для веб-приложений (т.н. web application firewall). Это один из первых рубежей защиты (если сравнивать, например, с веб-антивирусами), на котором происходит фильтрация входящего на сайт трафика: отделение "хорошего" от "плохого" и блокировка последнего.
В общем случае межсетевой экран располагается перед основной логикой приложения – и чем на более ранних этапах вредоносный запрос будет заблокирован, тем лучше:
Рис. 1. Общая схема работы межсетевого экрана
Что может сделать межсетевой экран и чего не может?
Может:
✔️ Обнаружить новый вредоносный запрос к сайту;
✔️ Заблокировать такой запрос;
✔️ Обнаружить новое спам-сообщение (отправляемое в форму на сайте);
✔️ Заблокировать его;
✔️ "Парализовать" деятельность вируса, живущего на сайте и получающего команды извне;
✔️ Собрать информацию об атаках на сайт для последующего анализа другими службами (об этом мы расскажем в конкретном кейсе чуть дальше).
Не может:
❌ Просканировать сайт на наличие уже проникших на него когда-либо вирусов;
❌ Удалить с уже заражённого сайта вирус;
❌ Защитить от DDOS-атаки.
Наш вариант: двухступенчатый межсетевой экран
Часто сталкиваясь с внешними атаками на сайты наших клиентов, мы задумались о создании "легковесного", простого в установке и, меж тем, эффективного межсетевого экрана веб-приложений. Для того, чтобы он срабатывал как можно раньше в контексте http-запроса пользователя и "отсеивал" вредоносный запрос до того, как он достигнет своей цели, было решено реализовать первый уровень firewall\'а как дополнение к веб-серверу nginx: небольшому перечню легко подключаемых конфигурационных файлов.
Первая версия стартовала с минимальным набором сигнатур и была ориентирована, главным образом, на противодействие конкретным атакам. Позже этот набор пополнялся и пополнялся (несколько лет) всё более универсальными правилами обработки запросов, пока не достиг состояния стабильной работы на достаточно крупных атаках.
В итоге firewall стал состоять из двух ступеней: 1) дополнение к nginx; 2) дополнение к php (позволяющее заблокировать более сложные вредоносные запросы). Схематично наш вариант можно пояснить на схеме так:
Рис. 2. Общая схема работы нашей реализации межсетевого экрана (зелёные стрелки означают обычные http-запросы, красные – вредоносные).
При отсутствии подобного межсетевого экрана все вредоносные запросы доходили бы до Apache и ядра 1С-Битрикс, что с определённой вероятностью всегда несёт в себе опасность.
Несколько поясним далее, как устроена каждая ступень.
Первая ступень: дополнение к nginx
Из всех возможных реализаций для nginx мы выбрали, пожалуй, самый простой (с точки зрения структуры) вариант: git-репозиторий с всего двумя конфигурационными файлами. Для установки достаточно склонировать репозиторий и подключить эти файлы.
Один из подключаемых conf-файлов содержит правила фильтрации запросов (по сути, сигнатуры в виде обычных регулярных выражений). Сигнатуры в нём выглядят примерно так:
"~*(?:wget|shell_exec|passthru|popen|proc_open|wlwmanifest|xmlrpc|(?<!assets_)webpack)" 1; "~*(?:style|moduless|boom|wpindex|larva|th3_err0r|alfa|alfaindex|alfindex|cindex)\\.php" 2;
Второй же файл нужен для определения реакции на вредоносный запрос.
Важно то, что проверка запросов осуществляется с помощью ngx_http_map_module, который есть практически в каждой сборке nginx и входит, например, в состав веб-окружения 1С-Битрикс. Это значит, что не нужно устанавливать никакого дополнительного ПО или "пересобирать" веб-сервер.
В итоге даже такое простое решение позволяет эффективно отсеивать наибольшее количество вредоносных GET-запросов. В том числе тех, например, которые направлены эксплуатацию уязвимостей Apache (что хорошо дополняет проактивный фильтр и веб-антивирус 1С-Битрикс, не имеющих подобной функциональности из-за срабатывания на более поздних этапах). Также, поскольку эти http-запросы отсекаются на ранних этапах, они не нагружают PHP.
Вторая ступень: дополнение к php
Так как ряд атак на сайт осуществляется с помощью отправки на него специально сконфигурированных POST-запросов, "тело" которых веб-сервер не может проанализировать без установки доп. модулей, мы реализовали обработку этих запросов на уровне PHP – так и появилась вторая ступень межсетевого экрана. Подключается она либо в первых строках точки входа в ваше php-приложение, либо через директиву "auto_prepend_file" в .htaccess или php.ini на вашем сайте.
Написанный нами код этой части firewall\'а мы обернули в пакет для composer – уже ставшего де-факто стандартным менеджером пакетов в PHP-сообществе. Установка через composer даёт ряд преимуществ, в частности, кросс-платформенную универсальность: установить и использовать этот код можно на любом сайте и любой платформе, использующей PHP (это может быть не только 1С-Битрикс, но и любой сайт на wordpress, laravel, yii2 и т.д.).
Код данной ступени позволяет конфигурировать правила блокировки запросов уже с большей гибкостью и функциональностью. Правила группируются в профили, представляющие собой простые ini-файлы, разбитые на секции. Например, если мы хотим заблокировать запросы с null-символом в переменной запроса $_REQUEST[bxu_info][CID], то выглядеть это будет примерно так:
[block_null_symbol] target = \'_REQUEST[bxu_info][CID]\' match[] = \'/\\x00/\'
А вот, например, как мы можем запретить последовательность "<?php" в любой переменной запроса, кроме списка разрешённых:
[block_php_start_tag] :target = \'_REQUEST[*]\' target_not[] = \'_REQUEST[form_data][filesrc]\' target_not[] = \'_REQUEST[filesrc]\' match[] = \'/(\\<\\?php)/i\'
Защита от спама
Благодаря возможности задавать правила фильтрации в подобном синтаксисе, программист может быстро составить для вашего сайта простой и надёжно работающий спам-фильтр. Вот лишь небольшой набор возможных антиспам-правил для демонстрации:
[block_spam_bots] :target = \'_REQUEST[form_text_(84|91|155)]\' ; Имя длиннее 35 символов - спам match[] = \'/^[\\w\\s]{35,}/u\' ; Имя длиннее 3 слов (от 4 и более) - спам match[] = \'/(\\S+\\s){4,}/uU\' ; \\w здесь означает англ. буквы (т.к. без модификатора "u") - спам match[] = \'/^[\\w\\/]+$/\' ; Имя содержит текст "www." - спам. match[] = \'/www\\./\' target2 = \'_REQUEST[form_textarea_104]\' ; сообщение содержит теги ссылок – спам match_target2[] = \'/\\<a\\s+href/i\' ; сообщение заполнено и не содержит кириллицу – спам: -match_target2[] = \'/([\\x{0400}-\\x{04FF}]+|^$)/u\'
Кейс: история одного заражения
А теперь давайте посмотрим, как описанный нами межсетевой экран сработал в реальных "полевых" условиях, а не абстрактной лаборатории программиста.
Шаг 1: клиент обратился к нам с проблемой ошибок и странного контента на своём сайте
В результате беглого осмотра мы выяснили, что сайт был заражён вирусом: он внедрял свой код на страницы сайта. Этот код загружал контент со сторонних сайтов и выводил на страницах заражённого.
Вирус как создавал собственные файлы, так и дописывал себя к "хорошим" файлам сайта.
Шаг 2: попытка быстрой "вычистки" вируса
Проверка различными сканерами и очистка очевидно заражённых файлов давала очень нестабильный результат на короткий срок (вирус повторно распространялся по сайту).
Фактически, это означала необходимость остановки сайта, а далее либо восстановление из резервной копии, либо более глубокого анализа и очистки (как с помощью специализированных программ, так и вручную).
Шаг 3: проверка резервной копии
У клиента было настроено резервное копирование, но даже в архивах полугодовой и годовой давности файлы уже были заражены вирусом, который находился в "спящем" состоянии, ожидая момента своей активации.
Восстановление такой копии не имело особого смысла: вирус там всё равно есть, а данные за последние месяцы или даже годы в базе данных отсутствуют (в том числе информация о заказах).
Шаг 4: экстренная мера: установка межсетевого экрана
В качестве быстрого варианта, который мог хоть как-то облегчить ситуацию и дать время на вычистку кода, было принято решение установить и настроить на этом сайте наш межсетевой экран. На этот момент мы ещё не знали точно, поможет ли эта мера – и если как, то насколько. Потому что межсетевой экран никак не спасёт код сайта от уже произошедшего заражения, хотя и мог бы предотвратить это заражение при своевременной установке. Но зато он может заблокировать обращение к сайту извне, происходящие к его вредоносным страницам.
Немного статистики: работа Firewall\'а в цифрах
Сразу после включения межсетевой экран стал отсекать внушительное количество обращений к сайту: около 15% всех запросов. Вот некоторые примеры того, что было заблокировано:
/about/news/id/english_show.php?qu/96n /about/news/id/english_show.php?chr/2joyzo /bitrix/autoload_tai.php?S2n6Yd/641577.html /about/news/id/css/images/tai_show.php?ondr53283/z.html /about/news/id/css/tai_show.php?ziou%2Foopm3224gwuv.html /about/news/id/english_show.php%3Fnfvvipr/47m /about/news/id/english_show.php%3F20220108Z4asbE.html /about/news/id/english_show.php%3FJf25h2/723045.html \\x03\\x00\\x00/*\\xE0\\x00\\x00\\x00\\x00\\x00Cookie: mstshash=Administr POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php /restore.php?lang=de
Более пристальное наблюдение показало, что на заражённом сайте количество вредоносных запросов колеблется в диапазоне 6..23.5% в разные дни (со средним значением как раз в 15%). Для сравнения приведём статистику заражённого сайта, сопоставленную с аналогичными данными по незаражённым (на которых установлен такой же firewall):
Таблица №1. Сравнение относительного количества вредоносных запросов на заражённом и незаражённых сайтахЗаражённый сайт | Незаражённый сайт №1 | Незаражённый сайт №2 | |
---|---|---|---|
Всего запросов за период наблюдения (по данным access.log nginx) – шт. # |
4 753 948 Заражённый сайт |
2 148 151 Незаражённый сайт №1 |
3 142 253 Незаражённый сайт №2 |
Из них вредоносных – шт. (по данным межсетевого экрана) # |
712 292 Заражённый сайт |
6 352 Незаражённый сайт №1 |
20 225 Незаражённый сайт №2 |
% вредоносных # |
15% Заражённый сайт |
0,3% Незаражённый сайт №1 |
0,64% Незаражённый сайт №2 |
→ разница между заражённым и незаражённым сайтом примерно в 30 раз
А также отдельно по POST-запросам:
Таблица №2. Сравнение относительного количества вредоносных POST-запросов на заражённом и незаражённом сайтахЗаражённый сайт | Незаражённый сайт | |
---|---|---|
Всего запросов за период наблюдения (по данным access.log nginx) – шт. # |
299 959 Заражённый сайт |
703 926 Незаражённый сайт |
Из них вредоносных – шт. (по данным межсетевого экрана) # |
2 553 Заражённый сайт |
388 Незаражённый сайт |
% вредоносных # |
0,85% Заражённый сайт |
0,06% Незаражённый сайт |
→ разница между заражённым и незаражённым сайтом примерно в 14 раз
На основе приведённых данных мы можем констатировать, что количество вредоносных запросов, "отлавливаемых" межсетевым экраном, на заражённом сайте возрастает примерно в 30 раз, а POST-запросов – примерно в 14 раз. Автоматизированное наблюдение за этой метрикой и обнаружение "всплеска" вредоносных запросов само по себе может служить хорошим дополнительным сигналом к тому, что требуются срочные мероприятия по анализу ситуации и (возможно) удалению проникших на сайт вирусов.
Итоги: чем всё закончилось на этом сайте
После установки межсетевого экрана вирус был "парализован": несмотря на его присутствие в коде сайта, он не мог отвечать на внешние запросы от своего "командного пункта", т.к. эти запросы теперь блокировались.
Всё это позволило выиграть время, оставляя сайт работоспособным на период глубокой очистки кода программистами от вирусов.
Сейчас межсетевой экран на этом сервере продолжает работать – и успешно фильтрует вредоносные запросы, защищая от новых потенциальных проникновений.
Дополнительный бонус, который получил клиент после его установки – это защита форм сайта от спама. С этой задачей успешно справляется вторая ступень firewall'а.
Резюме: что может дать вашему сайту межсетевой экран
Решение, которое мы разработали и которое устанавливаем нашим клиентам, получилось довольно результативным. Оно хорошо дополняет проактивный фильтр и веб-антивирус 1С-Битрикс (и никак не конфликтует с ними). Помимо основной своей функции (защищать сайт от вредоносных атак), можно отметить следующие достоинства такого подхода:
✔️ Общая простота (как архитектуры, кода, так и процесса установки). Это также сильно облегчает техподдержку продукта;
✔️ Универсальность. Наш межсетевой экран подойдёт к разным CMS и фреймворкам (будь то Битрикс, WordPress, Laravel, Yii2 и мн.др.). Первая ступень требует лишь наличия nginx, вторая – php;
✔️ Независимость от обновлений Битрикс (как следствие независимости от Битрикс вообще). Выходит, что можно использовать данный межсетевой экран, даже если обновления Битрикс вы не получаете;
✔️ Лёгкость кастомизации: легко добавлять и редактировать правила фильтрации (которые хранятся в файлах на вашем сервере). Например, без проблем можно добавить любые исключения при ложноположительных срабатываниях firewall'а;
✔️ Универсальный язык задания сигнатур – для этого используются регулярные выражения, понятные любому программисту;
✔️ Диагностическая ценность. В описанном кейсе мы показали, что при наличии информации от межсетевого экрана можно косвенно определить, что на ваш сайт проник вирус (даже если его код не находит антивирус). И, соответственно, оперативно принять меры;
✔️ Прозрачность. При ложноположительных срабатываниях специалист легко сможет определить, из-за какой конкретно сигнатуры был заблокирован тот или иной запрос. И, соответственно, оперативно её скорректировать;
✔️ Межсетевой экран устанавливается on-premise, оставаясь полностью подконтрольным специалистам вашей сети.
Однако стоит также помнить о том, что межсетевой экран:
- Не заменяет собой антивирусы или другие продукты обеспечения безопасности, но дополняет их;
- Не удаляет с сайта вредоносный код (для этого существуют другие решения), но сильно осложняет возможность его проникновения на сайт;
- Может потребовать некоторой техподдержки, как и любой другой программный продукт. Например: скорректировать правила, обновить набор правил, добавить исключения, проанализировать логи и т.д.
Мы рекомендуем нашим клиентам устанавливать межсетевой экран для повышения устойчивости сайта к взломам и общего повышения уровня безопасности. Если вы хотите заказать его у нас – можете сделать это по ссылке.
Закажите бесплатную консультацию
Оставьте свои контакты,
мы свяжемся с вами в ближайшее время.