Лучшая по цене-качеству Ddos защита

Защита WordPress (Часть 2). Противодействие хакерам

6

Опубликовано : 31-03-2016 | Рубрика : WordPress | Автор : tekseo

Чтобы противостоять уличным хулиганам, можно изучить самбо, научиться как следует бегать, либо соблюдать элементарные правила: не ходить в темное времени суток по безлюдным местам, не “светить” наличность, или дорогой смартфон, и т.д. Однако максимального результата поможет добиться лишь комплекс мер. Именно по этой причине на вопрос “Как защитить сайт от взлома?” невозможно дать однозначный ответ. Методик и рекомендаций существует множество, каждая из них подходит для вполне конкретных ситуаций, поэтому ни одной из них не стоит пренебрегать. Давайте же постараемся последовательно разобрать все возможные способы защиты от хакерских атак.

Общие советы по технике безопасности

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

1. Выбирайте хостинг, соответствующий вашим возможностям

Одним из самых популярных видов размещения сайтов является shared-хостинг. Главное его преимущество — дешевизна, среди минусов — многочисленные ограничения (отсутствует возможность тонкой настройки приложений, нельзя установить новые библиотеки) и оверселлинг.

В этой связи многие владельцы веб-проектов обращают внимание на VDS/VPS. Данная разновидность хостинга предоставляет те же возможности, что и физический сервер, плюс — честные вычислительные мощности. Однако подобное решение способно нанести чудовищный удар по безопасности сайта на WordPress, так как требует серьезных знаний в области системного администрирования. Не разбираясь в нюансах, вы существенно облегчите задачу злоумышленникам — хакеру не придется взламывать сам движок, он добьется своего, используя дыры в сервере.

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

2. Загружайте движок и плагины с официальных ресурсов

Вордпресс обладает открытым исходным кодом, изменение любого скрипта, входящего в его состав, не требует декодирования файлов (достаточно обычного блокнота). И любые “суперсборки все в одном”, а также пиратские версии платных модулей в лучшем случае содержат скрытые ссылки, в худшем — бекдоры и сложные вирусы, способные сделать ваш сайт частью бот-нета. Для получения дистрибутивов самого движка и плагинов, используйте только официальные источники:
● ru.wordpress.org — сайт проекта
● ru.wordpress.org/plugins/ — каталог плагинов (также многие из них можно получить непосредственно в админке)
● собственные ресурсы разработчиков расширений (можно узнать в описании позиций, размещенных в каталоге)

3. Регулярно обновляйте CMS и отдельные компоненты

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

По умолчанию, WordPress устанавливает в автоматическом режиме только минорные обновления движка — остальные приходится ставить вручную. Чтобы апгрейд стал полностью автоматическим, в wp-config.php необходимо прописать следующую строчку:

define('WP_AUTO_UPDATE_CORE', true);

4. Избавьтесь от ненужных расширений

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

5. Проверьте имеющиеся плагины на уязвимости

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

Первый из них, Exploit Scanner, анализирует скрипты, предоставляя детальный отчет о найденных сегментах подозрительного кода. Окно настроек выглядит следующим образом:

Определяем защиту сайта Exploit Scanner

Галочка напротив “Search for suspicious styles” позволяет включить в отчет информацию о css-стилях (стоит отметить, что в большинстве случаев это — не более, чем ложные срабатывания). Опция “Upper file size limit” (указывается в килобайтах) позволяет ограничить размер тестируемых файлов, что удобно в том случае, если на сайте активно используется видео и аудио — установка лимита исключит бессмысленную проверку мультимедия. “Number of files per batch” позволяет настраивать количество файлов, проверяемых за один подход — уменьшение этой величины позволит осуществлять тестирование без особых последствий для производительности даже на маломощных серверах.

Выбрав желаемые значения, можно запускать сканирование кнопкой “Run the Scan”. Результатом станет такой отчет:

результат по уязвимостям сайта

Как видно, число ложных срабатываний действительно велико. И если часть найденных строк Exploit Scanner самостоятельно помечает, как допустимые (об этом свидетельствует надпись в скобках — often used legitimately), то в других случаях необходимо обладать определенными навыками, чтобы понять, в чем кроется ошибка. К примеру, на приведенном скриншоте причиной срабатывания стало распознавание названия сервиса Dropbox как SQL-запроса “DROP”, позволяющего удалять таблицы базы данных.

Plugin Security Scanner в этом плане более прост. Он определяет установленные компоненты, сопоставляя информацию о них по базе уязвимостей. Сканирование осуществляется полностью автоматически, а результатом становится отчет следующего вида:

Отчет плагина Security Scanner

Здесь указывается название уязвимого компонента и ссылка на статью об имеющемся эксплоите. С точки зрения пользователя, данный сканер более прост и нагляден, однако и он допускает ошибки. Как видим, он посчитал подозрительным своего прямого конкурента, Exploit Scanner, вот только описываемой уязвимости уже почти 3 года и она давно исправлена.

6. Выставьте правильные права на файлы и папки

Права доступа определяют, что могут делать пользователи с файлом, или директорией (при этом в качестве одного из пользователей выступает сам веб-сервер). В *nix-системах они описываются последовательностью из трех цифр (например, 755):
● первая указывает, что может делать с объектом его непосредственный владелец;
● вторая определяет права для некоей группы пользователей;
● третья описывает перечень манипуляций для всех остальных.

В свою очередь, каждое число может принимать значение от 0 до 7. Существуют базовые:
● 0 — запрещены любые действия;
● 1 — файл может быть выполнен;
● 2 — разрешено редактирование файла/можно изменять содержимое директории;
● 4 — разрешено считывание информации в файле/листинг папки;

а также, дополнительные операторы, получаемые путем сложения перечисленных цифр. Давайте рассмотрим, что означает каждая сумма:
● 1+2=3 — запрещено чтение, разрешены выполнение и запись;
● 4+1=5 — запрещена запись, разрешены чтение и выполнение;
● 4+2=6 — запрещено выполнение, разрешены чтение и запись;
● 4+2+1=7 — разрешены любые действия.

С первого взгляда, все перечисленное может показаться сложным. На самом же деле, чтобы разобраться, как защитить сайт WordPress от взлома, достаточно запомнить несколько предельно простых правил:
● все папки движка должны иметь права 755
● все файлы — 644
● исключение — wp-config.php: поскольку здесь содержится информация для доступа к базе данных, а также ключи шифрования куки — лучше всего выставить права 400.

7. Регулярно создавайте резервные копии

“Веб-мастера делятся на две категории: те, кто еще не терял сайты, и те, кто уже делает бэкапы”. Хотя многие хостинги предоставляют услуги резервного копирования, это еще не гарантирует полную защищенность — даже провайдер может утратить данные, не говоря уже о человеческом факторе. В данном случае правило яиц и корзины работает “на ура”: сохранять критически важную информацию следует одновременно в несколько мест:
1) сам веб-сервер
2) персональный компьютер или облачный сервис
3) съемный носитель

Только в этом случае вы сможете быть на 100% уверены в сохранности вашей площадки. Что касается самого метода, то существует ровно два способа — ручной, и с использованием плагинов. Для начала разберем первый.

Он состоит из двух этапов: создание дампа базы данных (здесь хранится вся информация о сайте, а также контент), и копирование файлов движка. Бэкап MySQL осуществляется через панель управления phpMyAdmin. Авторизовавшись, выполните следующие действия:
1. Выберите базу данных проекта в левой колонке интерфейса;
2. Кликните по ссылке “Отметить все” (расположена внизу страницы);
3. Перейдите в раздел “Экспорт”;
4. Поставьте радиокнопку в положение “Быстрый — отображать минимум; настроек”, в поле “Формат” выставьте SQL;
5. Нажмите кнопку “Ок”, затем сохраните полученный файл.

Для получения файлов проще всего воспользоваться бесплатной программой Filezilla — одним из лучших FTP-менеджеров. Установив и запустив программу, проделайте следующее:
1. В горизонтальном меню выберите “Сервер” — > “Принудительно отображать скрытые файлы”
2. Подключитесь к серверу, используя данные, предоставленные хостинг-провайдером
3. Перейдите в директорию сайта. Как правило, ее название совпадает с доменным именем. Для tekseo.su путь может быть таков: var/www/tekseo.su/public_html. Папка public_html (бывают варианты с docs, или www) является корневой, именно в ней и находятся необходимые файлы.
4. Выделите нужную папку, щелкните по ней правой кнопкой мыши и нажмите “Скачать” — файл сохранится в выбранную папку на компьютере.

Возникает закономерный вопрос: как восстановить проект в том случае, если защита web-сайта пала от действий хакеров и ему нанесен непоправимый ущерб? После взлома движок может быть заражен вирусом, либо получить бекдор (черный ход, через который злоумышленник сможет перехватить управление в любой момент), поэтому, при наличии свежего бекапа, лучше выполнить переустановку начисто. Сперва следует восстановить базу данных. Поскольку текущая скомпрометирована, от нее следует избавиться: войдите в phpMyAdmin, вкладка “Базы данных”, поставьте галочку напротив нужной, нажмите “Удалить”, затем “Ок”. Теперь проделайте следующее:
1. В поле под надписью “Создать базу данных” введите имя новой БД. Оно должно отличаться от предыдущего;
2. В списке “Сравнение” проставьте utf8_general_ci и щелкните по “Создать”;
3. Выберите вновь созданную БД в левой колонке, затем перейдите на вкладку “Импорт”;
4. Нажмите на кнопку “Обзор”, и найдите последнюю версию дампа;
5. Выставьте кодировку UTF-8 и щелкните по кнопке “Ок”.

Теперь осталось восстановить файлы и подключить CMS к MySQL. Для этого проделайте следующее:
1. Используя Filezilla, или панель управления, предоставленную хостером, удалите корневой каталог;
2. Скопируйте ранее сохраненную корневую папку вместе со всем содержимым в директорию веб-ресурса на сервере;
3. Подключите движок к базе данных, отредактировав файл wp-config.php. Нас интересуют две строчки:

define('DB_NAME', 'name'); - впишите вместо name имя базы данных
 ● define('DB_PASSWORD', 'password'); - замените password на пароль БД

Процесс можно автоматизировать благодаря плагину UpdraftPlus Backup and Restoration — на сегодняшний день это, пожалуй, лучшее решение в сегменте. После установки модуля, для начала резервного копирования достаточно нажать кнопку “Создать РК сейчас”

Создаём резервную копию сайта

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

Бекап MySQL и ФТП данных

Управление имеющимися РК осуществляется на второй вкладке. Кнопка “Посмотреть лог” открывает документ с отчетом о ходе создания резервных копий:

Лог работы программы UpdraftPlus

В разделе “Настройки” можно автоматизировать процесс копирования, задав расписание и количество необходимых копий. Также имеется возможность подключить любое из популярных облачных хранилищ. Единственное ограничение бесплатной версии — единовременно активен может быть лишь один аккаунт.

Расписание копирования копий веб сайта

Также здесь можно выбрать, что именно следует включить в состав РК и указать электронную почту для отправки отчетов. Шифрование доступно только в PRO-редакции (оно не особо и нужно), а экспертные настройки лучше не трогать вообще:

Расширенные настройки создания копий

8. Используйте мониторинг Яндекс.Метрики

Статистикой от Яндекса пользуется практически каждый СЕО-специалист. Но отнюдь не каждый отдает должное такому инструменту, как уведомления. А между тем, их активация способна помочь в противостоянии кибератакам. Включить их можно на соответствующей вкладке “Настроек”:

Метрика для безопасности WordPress

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

Скрываем признаки использования WordPress

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

1. Удаляем автоматические мета-теги

По умолчанию CMS выводит в страниц кучу ненужной информации, позволяющей сходу вычислить тип движка. Чтобы их отключить, необходимо прописать дополнительный код в конец functions.php активной темы:

remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'feed_links', 2);
remove_action('wp_head', 'index_rel_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'feed_links_extra', 3);
remove_action('wp_head', 'start_post_rel_link', 10, 0);
remove_action('wp_head', 'parent_post_rel_link', 10, 0);
remove_action('wp_head', 'adjacent_posts_rel_link', 10, 0);

[tip]Когда речь заходит о functions.php, имеется в виду файл, отвечающий за функции конкретной темы, и расположенный в папке /wp-content/themes/название_темы. Изменить его можно через меню WordPress (раздел “Внешний вид” — “Редактор”), или открыв через файловый менеджер в текстовом редакторе.[/tip]

2. Скрываем следы в заголовках

Послав запрос на сайт с помощью того же cURL, мы можем увидеть следующее:

— Для версий Вордпресс младше 4.4:

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Mon, 20 Feb 2016 01:11:45 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.16
X-Pingback: http://tekseo.su/xmlrpc.php

Здесь CMS демонстрирует файл xmlrpc.php. Кроме того, и сам протокол является уязвимым — его отключение также обеспечит защиту сайта от DDoS-атак и брутфорса (о том, как это сделать, я рассказывал в предыдущей статье). Убрать же строчку X-Pingback поможет такая конструкция (как и ранее, добавляется в functions.php):

function remove_x_pingback($headers) {
    unset($headers['X-Pingback']);
    return $headers;
}
add_filter('wp_headers', 'remove_x_pingback');

— Для более новых редакций движка:

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Mon, 20 Feb 2016 01:11:45 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.16
Link: <http://tekseo.su/wp-json/>; rel="https://api.w.org/"

Как видим, разработчики убрали из заголовков пингбэк, однако теперь добавилась wp-json — виртуальная директория, создаваемая новым API — REST. Мало того, что префикс файла красноречиво указывает на тип CMS, wp-json склонен плодить многочисленные дубли контента. Так что код, предложенный ниже, убивает сразу двух зайцев: мы удаляем признаки WordPress из заголовка, плюс к этому, предотвращаем возможные проблемы с индексацией:

// Отключаем сам REST API
add_filter('rest_enabled', '__return_false');
 
// Отключаем фильтры REST API
remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
remove_action( 'wp_head', 'rest_output_link_wp_head', 10, 0 );
remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 );
remove_action( 'auth_cookie_malformed', 'rest_cookie_collect_status' );
remove_action( 'auth_cookie_expired', 'rest_cookie_collect_status' );
remove_action( 'auth_cookie_bad_username', 'rest_cookie_collect_status' );
remove_action( 'auth_cookie_bad_hash', 'rest_cookie_collect_status' );
remove_action( 'auth_cookie_valid', 'rest_cookie_collect_status' );
remove_filter( 'rest_authentication_errors', 'rest_cookie_check_errors', 100 );
 
// Отключаем события REST API
remove_action( 'init', 'rest_api_init' );
remove_action( 'rest_api_init', 'rest_api_default_filters', 10, 1 );
remove_action( 'parse_request', 'rest_api_loaded' );
 
// Отключаем Embeds связанные с REST API
remove_action( 'rest_api_init', 'wp_oembed_register_route' );
remove_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 );

Помимо правки кода, можно воспользоваться удобным плагином wp_head() cleaner. Удаление “мусора” из в данном случае сводится к простой расстановке галочек в чекбоксах:

Правим код для защиты от Ddof

Разберем, что означает каждый пункт:
Really Simple Discovery — вывод тэгов XML-RPC;
Windows Live Writer — тэги редактора блогов Windows Live;
WordPress generator meta tag — отображает версию движка;
Post Relational Links — Start — относительная ссылка на первый пост;
Post Relational Links — Index — относительная ссылка на главную страницу;
Post Relational Links — Previous and Next — отключает относительные ссылки для кнопок “Предыдущий” и “Следующий”;
Post shortlinks — шортлинки;
Canonical links — канонические ссылки на посты;
Post and Comment Feed — вывод ленты статей и комментариев;
Other feeds, for example category feeds — фиды категорий и другие;
REST API — тэги API REST;
oEmbed — тэги oEmbed.

Отдельно поговорим об Emoji scripts и Emoji styles. В отличие от своего собрата (WP Head Section Cleaner, не обновлявшегося уже 3 года), данное расширение способно отключить набор эмотиконов Emoji, поддержка которых осуществляется благодаря дополнительным JavaScript и CSS. Они отвечают за отображение в браузере улучшенных смайликов:

Отключение скрипта emoji

Сам по себе Emoji не является таким уж значимым маркером, но его выключение снижает нагрузку на сервер. wp_head() cleaner позволяет деактивировать как скрипты, так и стили. То же самое можно сделать, подкорректировав functions.php:

remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );

3. Удаляем лишние комментарии из кода

Большинство модулей, да и сам движок, оставляют служебные комментарии — это очень помогает при разработке, однако не менее полезно и для хакеров: в ряде случаев здесь даже могут быть указаны версии плагинов. Удалять каждую такую запись отдельно — весьма неблагодарное занятие, но структура движка позволяет использовать все тот же fuctions.php — следующая конструкция поможет их заблокировать:

function callback($buffer) {
	$buffer = preg_replace('/<!--(.|\s)*?-->/', '', $buffer);
	return $buffer;
}
function buffer_start() {
	ob_start("callback");
}
function buffer_end() {
	ob_end_flush();
}
add_action('get_header', 'buffer_start');
add_action('wp_footer', 'buffer_end');

Методы защиты сайта от взлома

Мы предприняли все необходимые меры, замаскировав Вордпресс, настроив обновления, указав верные права и прочее. Настало время изучить, как отбиваться от разнообразных хакерских атак.

1. Задаем уникальный префикс таблиц базы данных

Один из важнейших шагов по защите сайта на WordPress, позволяющий отсечь часть атак непосредственно на MySQL. В идеале, желательно заменить стандартный префикс “wp_” на случайную последовательность строчных букв и цифр (заканчиваться префикс должен нижним подчеркиванием) еще на этапе первичной установки CMS. Если же ваш проект уже существует, процедура будет несколько более сложной. Можно воспользоваться следующим методом (это — самый простой вариант замены префиксов таблиц в рамках действующего ресурса):

1. Найдите файл wp-config.php, откройте в блокноте, найдите строчку $table_prefix = ‘wp_’ и замените на что-то другое (например, $table_prefix = ‘abcb123456_’;);
2. Зайдите в phpMyAdmin, выберите базу данных сайта, кликните по ссылке “Отметить все”, перейдите на вкладку “Экспорт”, нажмите кнопку “Ок” и скачайте на компьютер полученный файл;
3. Откройте его в Notepad++ (бесплатный многофункциональный редактор), выберите “Поиск” — “Замена”, в поле “Найти” введите “wp_”, в поле “Заменить на” введите новый префикс (в нашем случае “abcb123456_”), нажмите “Заменить все”, дождитесь окончания процесса и сохраните файл;
4. Вернитесь в phpMyAdmin, удалите базу данных сайта и создайте новую с точно таким же именем;
5. Выберите ее в списке, зайдите на вкладку “Импорт”, щелкните по кнопке “Обзор”, найдите на компьютере ранее отредактированную резервную копию, укажите кодировку UTF-8 и нажмите “Ок”.

2. Защищаем папку wp-content

Директория wp-content содержит темы, плагины, а также загруженные файлы и документы. С помощью дополнительного htaccess можно настроить селективный доступ исключительно к медиаконтенту. Для этого создайте новый файл с названием “.htaccess”, и поместите его непосредственно в папку wp-content. Он должен содержать следующие директивы:

# Блокируем любые запросы к каталогу
Order deny,allow
Deny from all
# Разрешаем запрашивать файлы с определенными расширениями
<Files ~ ".(xml|css|js|jpe?g|png|gif|pdf|docx|rtf|odf|zip|rar)$">
Allow from all
</Files>

3. Защищаем wp-includes

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

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

4. Останавливаем вредоносных ботов

Хакеры используют автоматические утилиты не только в качестве сканеров, но и как средство взлома. С помощью htaccess такие программы можно блокировать, проверяя user agent. Определяется угроза по характерным фрагментам идентификатора. На этом и основано действие приведенного ниже кода:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (;|<|>|'|"|\)|\(|%0A|%0D|%22|%27|%28|%3C|%3E|%00).*(libwww-perl|wget|python|nikto|curl|scan|java|winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner) [NC,OR]
RewriteRule ^(.*)$ - [F,L]
</IfModule>

5. Фильтруем подозрительные запросы

Множество типов атак основано на формировании вредоносных запросов к CMS. Чтобы пресекать подобную активность на корню, стоит воспользоваться редиректом:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK|DEBUG) [NC]
RewriteCond %{THE_REQUEST} \?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} \/\*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} etc/passwd [NC,OR]
RewriteCond %{THE_REQUEST} cgi-bin [NC,OR]
RewriteCond %{THE_REQUEST} (%0A|%0D) [NC,OR]
RewriteRule ^(.*)$ - [F,L]
</IfModule>

Теперь на все “плохие” запросы будет выдаваться ошибка Forbidden.

6. Предотвращаем исполнение произвольных команд

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

● SQL-injection — добавление к запросу SQL-кода, обеспечивающего доступ к базе данных (так можно получить информацию, содержащуюся в таблицах, изменить или удалить ее);
● RFI (Remote File Inclusion), в нашем случае — PHP-инъекция, становится возможной в том случае, если не осуществляется проверка входных параметров;
● XSS (межсайтовый скриптинг) — его суть заключается во внедрении потенциально опасных команд непосредственно в страницу сайта. Код выполняется на компьютере пользователя при открытии соответствующего веб-документа;
● Подмена глобальных переменных — позволяет изменять php-сценарии на стороне пользователя;
● Атаки с использованием base64 — обратимое кодирование, позволяющее передавать данные между любыми устройствами, а в случае с хакерами — обходить многие фильтры;
● iFrame-инъекции — атаки с использованием фреймов.

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

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC,OR]
RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC,OR]
RewriteCond %{QUERY_STRING} (\.\./|\.\.) [OR]
RewriteCond %{QUERY_STRING} ftp\: [NC,OR]
RewriteCond %{QUERY_STRING} http\: [NC,OR]
RewriteCond %{QUERY_STRING} https\: [NC,OR]
RewriteCond %{QUERY_STRING} \=\|w\| [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)/self/(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)cPath=http://(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*iframe.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^i]*i)+frame.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR]
RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>).* [NC,OR]
RewriteCond %{QUERY_STRING} (NULL|OUTFILE|LOAD_FILE) [OR]
RewriteCond %{QUERY_STRING} (\./|\../|\.../)+(motd|etc|bin) [NC,OR]
RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR]
RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{QUERY_STRING} concat[^\(]*\( [NC,OR]
RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} (;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode) [NC,OR]
RewriteCond %{QUERY_STRING} (sp_executesql) [NC]
RewriteRule ^(.*)$ - [F,L]
</IfModule>

7. Предотвращаем использование эксплоита timthumb

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

<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} (timthumb\.php|phpthumb\.php|thumb\.php|thumbs\.php) [NC]
RewriteRule . - [S=1]
</IfModule>

8. Ограничиваем количество знаков в комментариях

Как может быть связано число символов в оставленном комментарии и защита веб-сайтов от взлома? Чтобы это понять, стоит обратиться к событию, произошедшему в апреле 2015 года. Тогда специалистам финской компании «Klikki Oy» удалось выявить фатальный баг WordPress, позволяющий взломщику получить полный контроль не только над самим движком, но даже сервером.

Суть метода заключалась в следующем. В секцию комментария было необходимо скопировать приблизительно такой код:

<a title='x onmouseover=alert(unescape(/hello%20world/.source)) style=position:absolute;left:0;top:0;width:5000px;height:5000px  [+ 64 kb]'></a>

дополнив строчку еще 66 тысячью символов. База данных не справляется с таким запросом, и в результате ошибки комментарий будет обрабатываться, как скрипт. После этого достаточно повторно зайти на эту же страницу, и в систему будет инсталлирован бэкдор, обеспечивающий доступ к административной панели. Уязвимость выявлена на CMS версии 4.2, и была исправлена в течение двух часов после подачи отчета. Однако нет гарантии, что аналогичных дыр вовсе не осталось.

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

Для более ранних версий Вордпресс существовал специальный плагин, но для ядра 4.4 и выше он неактуален. Однако, проблему можно решить, внедрив приведенный код в файл functions.php используемого на сайте шаблона:

add_filter( 'preprocess_comment', 'wpb_preprocess_comment' );
 
function wpb_preprocess_comment($comment) {
	if ( strlen( $comment['comment_content'] ) > 2500 ) {
    	wp_die('<p style="text-align: center;">Комментарий слишком длинный. Максимально допустимое число символов - 2500.</p>
	<div style="text-align: center;"><input type="button" onclick="history.back();" value="Вернуться к сообщению"/></div>');
	}
if ( strlen( $comment['comment_content'] ) < 120 ) {
    	wp_die('<p style="text-align: center;">Минимальная длина комментария составляет 120 знаков.</p>
	<div style="text-align: center;"><input type="button" onclick="history.back();" value="Вернуться к сообщению"/></div>');
	}
	return $comment;
}

Теперь, при попытке оставить слишком короткий комментарий, на экране пользователя появится такая надпись:

Безопасность WordPress комментариев

а слишком длинный — такая:

Защита от взлома и атак в комментариях

Разумеется, приведенный текст можно изменить по своему вкусу.

Защита WordPress от DDoS-атак

Вынесенный в подзаголовок термин расшифровывается, как Distributed Denial Of Service Attack, что дословно переводится: “Распределенная атака, вызывающая отказ в обслуживании”. Говоря простым языком, это — совокупность действий, приводящая к перегрузке сервера, в результате чего сайт становится недоступен. Хакеры используют данную методику достаточно часто — она позволяет “положить” проект без необходимости в трудоемком взломе.

Сразу стоит оговориться — эффективная защита сайта от DDoS начинается лишь на уровне сервера. Любые программные решения для CMS способны противостоять лишь самым слабым атакам, действуя по принципу “лучше, чем ничего”. Впрочем, это не значит, что ими следует пренебрегать — часть злоумышленников все равно удастся отсеять. Ниже приведена инструкция, с помощью которой вы сможете самостоятельно создать подобный скрипт, и подключить его к Вордпресс.

1. Найдите в корневой директории index.php, и добавьте в его начало (сразу после открывающего тэга <?php) следующую строчку

include("ddosblock.php");

2. Если в каталоге отсутствует папка tmp, создайте ее;
3. Создайте файл ddosblock.php, откройте и скопируйте туда следующий код:

<?php
/*
* Скрипт скрипт фиксирует промежуток времени между повторными
* обращениями с каждого. Если за указанный
* период поступает повторный запрос, сервер отдает ошибку 503.
*/
 
/* Указываем время задержки в секундах */
$ad_delay=2;
/* Выставляем путь к папке для временных файлов 
* (должен реально существовать)
*/
$ad_DirName=$_SERVER['DOCUMENT_ROOT'].'/tmp';
 
/*
* Пишем список поисковых роботов,
* чтобы случайно не загнать их в бан.
*/
$ad_Robots_UserAgent=array(
  'aipbot',
  'Aport',
  'eStyleSearch',
  'Gigabot',
  'Gokubot',
  'Google',
  'MJ12bot',
  'msnbot',
  'PlantyNet_WebRobot',
  'StackRambler',
  'TurtleScanner',
  'Yahoo',
  'Yandex',
  'YaDirectBot',
);
/*
* Составляем список доверенных IP.
* Удобно, если у вас статический адрес.
*/
$ad_good_ip = array(
    '217.107.36.73',
);
 
/*
* Нижеследующая функция создаёт файл, имя которого
* начинается с буквы a (это поможет отличить его от других).
* К имени файла добавляется ip-адрес клиента.
*/
function ad_WiteIP($dir){
  $f=fopen($dir.'/a'.$_SERVER['REMOTE_ADDR'], 'w');
  fclose($f);
}
/*
* Проверяем user agent, дабы выявить поисковых ботов.
*/
$ad_IsRobot=false;
foreach ($ad_Robots_UserAgent as $match){
  if (strstr($_SERVER['HTTP_USER_AGENT'], $match)){
      $ad_IsRobot=true;
      break;
  }
}
if( in_array($_SERVER['REMOTE_ADDR'], $ad_good_ip) ) {
    $good_ip = true;
} else {
    $good_ip = false;
}
/*
* Заодно добавим внутренней оптимизации. Как известно,
* поисковые роботы недолюбливают переменные сессии.
* Блок ниже позволит отделять ботов от других посетителей.
*/
if (!$ad_IsRobot AND !$good_ip){
  session_start();
}
 
if (!$ad_IsRobot AND !$good_ip){
/*
* Очистка каталога от старых файлов.
*/
  $ad_dir      =opendir($ad_DirName)
      or die('Отсутствует директория для временных файлов');
  $ad_now      =time();
  $ad_forbid  =$ad_now-$ad_delay;
/*
* Время обращения - это время изменения файла,
* а его имя - IP-адрес.
*/
  while (false!==($ad_FName=readdir($ad_dir))){
      if (ereg('^a[1-9]',$ad_FName)
        && (@ filemtime($ad_DirName.'/'.$ad_FName)<$ad_forbid)){
        @ unlink($ad_DirName.'/'.$ad_FName);
      }
  }
  closedir($ad_dir);
/*
* Проверка факта недавнего обращения
* с определенного ip-адреса.
*/
  if (file_exists($ad_DirName.'/a'.$_SERVER['REMOTE_ADDR'])){
/* Если обращение было недавно, то выводим сообщение об ошибке */
      header('HTTP/1.0 503 Service Unavailable');
      header('Status: 503 Service Unavailable');
      header('Retry-After: '.$ad_delay*3);
?>
<!DOCTYPE html>
<html>
<head>
<title>Ошибка 503</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Ошибка 503 (Service Unavailable)</h1>
<p>В настоящий момент страница недоступна.
Попробуйте презагрузить эту страницу через несколько секунд (клавиша F5).</p>
</body>
</html>
<?php
      ad_WiteIP($ad_DirName);  // Перед выходом записываем ip
      exit;
  }else{
      ad_WiteIP($ad_DirName);
  }
}
?>

4. Загрузите файл ddosblock.php в корневую директорию ресурса.

Прелесть данного кода заключается в том, что его можно использовать на виртуальном хостинге — здесь не требуется доступ к iptables (файрволу сервера). При этом, он не может гарантировать 100% защиты. Если сценарий явно не будет справляться, можно на некоторое время законсервировать сайт, предоставив скрипту возможность спокойно банить ботов. Для этого в index.php надо добавить exit:

include("ddosblock.php");
exit;

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

Подытожим

Вооружившись знаниями из предыдущих статей, вы можете выстроить достаточно мощную защиту для сайта, базирующегося на CMS WordPress. Мощную, но отнюдь несовершенную, ведь ничего идеального не существует. И если за проект возьмется настоящий профессионал, он, безусловно, достигнет желаемой цели. Вопрос лишь в том, сможете ли вы заметить вмешательство извне и понять, что сайт подвергся атаке? Именно о способах обнаружения модификации кода, выявлении различных вирусов и способах борьбы с ними мы и поговорим в следующей публикации.


Комментарии

Спасибо, будем бороться с нечистью

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

А сам скрипт по защите не сильно нагружает сервер? Код немаленький и срабатывать должен для каждого пользователя, получается.
И еще, я правильно понял, что в папке будут создаваться файлы с забаненными ip в названии?

tekseo

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

Я бы еще рекомендовал от греха подальше навесить на хостинг CloudFlare. Бесплатный тариф по крайней мере отсеет школоту и прочих ламеров, плюс до кучи в комплекте идет CDN-ка и сертификат начального уровня, что тоже неплохо. Из минусов: “облако” часто юзают варезники и прочие темные личности, так что IP некоторых серверов попадают в ЧС Роскомнадзора. Справедливости ради, у меня таких прецедентов не было, но этот момент надобно отслеживать — метрика в помощь.

Виртуальный хостинг — тоже не панацея. На хабре была интересная публикация на эту тему. Хостер заказал пентест, на выходе — любой мог повысить права до рута и получить полный контроль над серверами из-за ошибки админов. Тут уж как сайт ни защищай — один пень взломают. Лучше тогда недельку маны покурить для CSF Firewall и поднять свою ВДСку, чем с такими деятелями связываться.

Добавить комментарий

Подтвердите, что Вы не бот — выберите человечка с поднятой рукой: