В предыдущей статье мы рассматривали как удалить следы присутствия Joomla с сайта. Теперь более детально остановимся на следующей популярной платформе для сайтов - Wordpress. По аналогии с Joomla мы попытаемся с минимальными потерями и возможностью дальнейшего обновления сайта.
В первую очередь стоит скрыть доступ посторонним для админки. Похожее мы делали в джумле, однако в случае с вордпрессом есть свои нюансы.
В любом случае защита админки - это жирный плюс к безопасности. Почему? Да очень просто. Очень многие сайты подвергаются атаке брутофорса или перебора паролей, говоря простым языком. Часть из них падет ниц перед злоумышленниками. Кроме этого, многие известные уязвимости плагинов и CMS находят свое применение через административную панель сайта. В том случае, когда уязвимости нулевого дня остаются без доступа к админке, они становятся бесполезными, а сайт остаётся невредимым.
Как удалить следы вордпресса своими руками с сайта
Теперь, когда мы убедились в необходимости усиления панели управления сайтом, займемся этим на практике.
Мы будем делать это стандартными средствами Apache, без использования сторонних плагинов. Существует два варианта запрета доступа: по айпи или по паролю.
Рассмотрим для начала вариант с ip. В этом случае мы должны иметь статический айпи-адрес, на худой конец айпи адреса одних подсетей.
Создадим в папке wp-admin файл .htaccess и добавим директиву deny,allow
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
где вместо xxx.xxx.xxx.xxx мы ставим наш адрес. Через запятую можно указать несколько айпи-адресов или можно указать маску подсети xxx.xxx.xxx. ( в этом случае будут работать все адреса начинающиеся на данную маску).
Внимание! Если ваша тема или плагины на сайте используют технологию аякс (AJAX), то вполне возможно, что нам придется открыть доступ к одному файлу в папке, для этого необходимо дописать в файл .htaccess следующий код:
<Files admin-ajax.php>
Order allow,deny
Allow from all
Satisfy any
</Files>
После таких манипуляций любой посторонний доступ к папке wp-admin будет запрещен. Если же понадобится зайти с другого компьютера на другом айпи, не забудьте зайти по фтп и добавить нужный адрес в список.
Однако мы не защитили саму авторизацию, если на вашем сайте не используется регистрация и вход пользователей, то в корневой файл .htaccess стоит добавить следующие строки:
<Files wp-login.php>
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
</Files>
где опять укажем наш белый айпишник. Данная мера поможет избежать возможности bruteforce на сайт.
Если регистрация и авторизация на сайте не нужны (это актуально для большинства сайтов-визиток), то стоит и закрывать файл xmlrpc.php - через него хакеры любят перебирать пароли через POST запросы. Здесь правда можно вообще закрывать прямой доступ, не обязательно по айпи или basic или digit авторизации.
<Files xmlrpc.php>
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
</Files>
Второй метод основан на установке парольной защиты на директорию wp-admin и файл wp-login.php
Код для закрытия wp-login.php
<Files wp-login.php>
AuthName "Protected area, need authorization"
AuthType Basic
AuthUserFile /path/to/file/htpasswd/.htpasswd
Require valid-user
</Files>
Аналогично выглядит и для файла xmlrpc.php
<Files xmlrpc.php>
AuthName "Protected area, need authorization"
AuthType Basic
AuthUserFile /path/to/file/htpasswd/.htpasswd
Require valid-user
</Files>
Не буду повторяться о данном методе, подробно это описано в защите админки джумлы, приведу лишь пример для файла .htaccess в папке wp-admin, где мы исключаем файл admin-ajax.php:
AuthType Basic
AuthName "Welcome home"
AuthUserFile "path to .htpasswd file"
SetEnvIf Request_URI ^/wp-admin/admin-ajax.php.* noauth=1
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth
Закрываем админку Wordpress на Apache 2.4
В новых версиях апача директивы order, deny и allow были упразднены и заменены на require. Старые правила конечно продолжают работать (неизвестно до какой версии правда), но в логах будут возникать такого рода ошибки:
[access_compat:error] AH01797: client denied by server configuration:
Дабы избежать такого мусора да и проблем с совместимостью будущем перепишем наши правила, настоятельно советую всем, у кого используется Apache 2.4 использовать новые правила!
Итак, запрет по айпи административной панели вордпресс теперь превратится в одну строчку:
Require ip 127.0.0.1
Для исключения из правил аякс запросов добавляем следующие строки:
<Files admin-ajax.php>
Require all granted
</Files>
Точно также будет и для авторизации через wp-login.php:
<Files wp-login.php>
Require ip 1.2.3.4
</Files>
Двухфакторная авторизация для админки примет следующий вид:
AuthType Basic
AuthName "Welcome home"
AuthUserFile /path/to/file/.htpasswd
Require valid-user
<Files admin-ajax.php>
Require all granted
</Files>
А для закрытия авторизации на сайте через wp-login.php или xmlrpc.php ничего не изменится.
Как видим ничего сложного нету, и новые директивы более просты в использовании.
Удаляем версию Wordpress на сайте
Следующим шагом будет удаление генератора из кода html. Достаточно открыть исходный код любой страницы и можно лицезреть следующее:
<meta name="generator" content="WordPress 4.5.3"/>
Согласитесь, это нам совсем ни к чему.
Делается это совсем просто, достаточно найти файл functions.php вашей темы ( расположена по пути wp-content/themes/<названиетемы> ) добавить функцию:
remove_action('wp_head', 'wp_generator');
Идем дальше, глянем на файлы в корне. По умолчанию там любят скапливаться разные информационные файлы, которые подлежат немедленному удалению.
Стандартный набор таких файлов: readme.html, license.txt иногда бывают с разрешением .md
В любом случае желательно и в папках шаблонов и плагинов удалить файлы версий как changelog, readme и license с различными видами расширений. Это предотвратит распознавание версий плагинов, а значит и невозможность подбора уязвимости под версию.
С другой стороны, при обновлении сайта эти файлы будет созданы вновь, и удалять каждый раз согласитесь не комильфо. Поэтому можно просто сделать запретить доступ в файле .htaccess к определенным файлам:
<Files readme.html>
Order deny,allow
Deny from all
</Files>
<Files wp-config-sample.php>
Order deny,allow
Deny from all
</Files>
<Files license.txt>
Order deny,allow
Deny from all
</Files>
Расширить список файлов можно и самому, добавив по аналогии свои.
Если мы хотим запретить конкретные типы файлов, к примеру txt,sql и т.д. - можно воспользоваться следующей конструкцией (убедитесь, что не блокируете лишнее как карта сайта или robots.txt):
<Files ~ "[\.(txt|sql|ini|xml)$">
Order allow,deny
Deny from all
Satisfy all
</Files>
Не забываем открыть доступ нужным файлам, особенно ценных для поисковиков:
<Files sitemap.xml>
Order allow,deny
Allow from all
</Files>
<Files robots.txt>
Order allow,deny
Allow from all
</Files>
Запрещаем обращение к корневым файлам вордпресс
Теперь коснемся файлов внутри корневой директории - это все файлы, начинающиеся на wp- (wp-config.php, wp-cron.php и другие) и файл xmlrpc.php
При прямом запросе к этим файлам мы будем получать различные ответы сервера, отличные от 404 - а значит файл существует. В интернете советуют решение прописать редирект с этих файлов на 404 ошибку. Честно говоря, мне этот метод не особо нравится, я бы лучше запрещал прямой доступ к файлам через директиву deny, allow
Однако даже и в этом случае у нас будет 403 ошибка вместо 404 - но и тут можно решить проблему, достаточно переопределить разного рода ошибки на 404 - и обязательно включить логирование, чтобы просматривать реальные ошибки сервера.
В любом случае, я советую для начала проанализировать работу сайта с закрытым прямым доступом к этим файлам - чересчур торопиться не стоит, при закрытии некоторых файлов можно закрыть доступ к авторизации или регистрации, фиду новостей и другим возможностям - поэтому будьте предельно осторожны с этим пунктом!
Как запрещать доступ к отдельным файлам было показано выше, для любителей краткости могу предложить такой вариант:
<FilesMatch "\.htaccess.*|\.htpasswd.*|xmlrpc\.php|wp\-cron\.php|wp_cron\.php">
order allow,deny
deny from all
</FilesMatch>
Удаляем версии скриптов в коде страницы на сайтах Wordpress
Ну и напоследок, один из явных признаков определения точной версии вордпресс - это версионность скриптов и стилей. Если присмотреться в исходный код html, то можно обнаружить добавки к путям скриптов:
<script type="text/javascript" src="/wp-includes/js/wp-embed.min.js?ver=4.7.2"></script>
В некоторых случаях скрипты имеют свою версию, но большинство получают номер текущей сборки, тем самым выдают реальную версию вордпресса. Для чего воообще это сделали разработчики? Ответ прост, многие браузеры кешируют скрипты и стили на компьютере и при обновлении файлов скриптов не все пользователи могут додуматься обновить кеш. А различия в коде обновления могут исказить сайт в нелучшую сторону. Добавление версии позволяет избавиться от этой проблемы.
Итак, приведу решение, как избавиться раз и навсегда от определения версии Wordpress. Не знаю, кто именно придумал этот метод, но он действенен, необходимо добавить в файл functions.php следующие строки:
function _remove_script_version( $src ){
$parts = explode( '?', $src );
return $parts[0];
}
//Это для скриптов
add_filter( 'script_loader_src', '_remove_script_version', 15, 1 );
//Это для стилей
add_filter( 'style_loader_src', '_remove_script_version', 15, 1 );
Заметаем все следы Wordpress полностью
С большей частью работы мы справились, однако признаков определения CMS остается прилично. Полностью мы не сможем избавиться от всех следов, не нарушив работоспособность, однако попробуем выжать максимум. Начнем с тем. Во-первых, удаляйте лишние и неиспользуемые темы: стандартные темы типо twentysixteen, twentyseventeen или twentyfifteen можно безболезненно деинсталлировать с сайта. Во-вторых, можно переименовывать темы на свои уникальные, дабы искажать информацию об установленном шаблоне. Тут палка о двух концах, мы не будем получать обновления, это было б неплохо для тяжелых тем, особенно с функционалом магазина. С другой стороны будем уверены, что обновление не перепишет наши правки.
Следующим шагом будем убирать информацию, которые оставляют плагины. Достаточно заглянуть в код страницы и лицезреть в комментариях различного рода информацию, от версий и названий плагинов до информации отладки. Приведу некоторые примеры:
<!-- This site is optimized with the Yoast SEO plugin v3.4.2 -->
<!-- platinum seo pack 1.3.8 --> <!-- /platinum one seo pack -->
<!-- Powered by WPtouch: 4.0.4 -->
Такой мусор нам совсем ни к чему, в большинстве случаев это можно откючить в настройках плагинов, реже придется лезть в код.
Как отключить Emoji в WordPress
Добавляем в 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' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'tiny_mce_plugins', 'disable_wp_emojis_in_tinymce' );
function disable_wp_emojis_in_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( 'wpemoji' ) );
} else {
return array();
}
}
Как полностью отключить REST API в Wordpress
В последних версиях ворпресса появилась очередная фича для разработчиков, позволяющая более гибко и удобно создавать различные приложения. REST API позволяет использовать возможности WP Query посредством простых запросов и всё через wp-json. Простым блогам, не использующим данную технологию, эти нововведения принесли лишь дополнительные хлопоты: в вебмастерах стали индексироваться непонятные страницы, содержащие в адресе /wp-json/wp/v2/posts или /wp-json/wp/v2/users/. Нет повода для радости и в том, что хакеры тоже нашли применение новому апи и во всю эксплуатировали найденные дыры для веб-спама и создания дорвеев. И я думаю, что это далеко не последняя обнаруженная уязвимость в фреймворке REST API. Именно поэтому для тех, кто не использует на своём сайте данные фишки, то их без зазрения совести можно и нужно отключить. Делается это как также в файле функций темы необходимо добавить следующий код:
// Отключаем сам 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 ); remove_action( 'wp_head', 'wp_oembed_add_discovery_links' ); // если собираетесь выводить вставки из других сайтов на своем, то закомментируйте след. строку. remove_action( 'wp_head', 'wp_oembed_add_host_js' );
Если при этом возникают проблемы с работоспособностью плагинов, к примеру, с отправкой форм в Contact Form 7 - то удалите или закомментируйте следующие строки:
remove_action( 'init', 'rest_api_init' ); remove_action( 'rest_api_init', 'rest_api_default_filters', 10, 1 ); remove_action( 'parse_request', 'rest_api_loaded' );
И напоследок, скину список стандартных файлов, которые обнаруживают популярные сканеры (cmsmap в частности):
/readme.html
/license.txt
/wp-includes/images/crystal/license.txt
/wp-includes/images/crystal/license.txt
/wp-includes/js/plupload/license.txt
/wp-includes/js/tinymce/license.txt
/wp-includes/js/swfupload/license.txt
/wp-includes/ID3/license.txt
/wp-includes/ID3/readme.txt
/wp-includes/ID3/license.commercial.txt
Что с ними делать, уже вам решать, удалять, запрещать доступ или оставлять как есть.
Если понравилась статья, поделитесь с ней друзьями. В комментариях жду ваши советы по заметанию следов вордпресса.
Убрать версионность скриптов и стилей можно так:
function _remove_script_ version( $src ){
$parts = explode( '?', $src );
return $parts[0];}
add_filter( 'script_loader_ src', '_remove_script _version', 15, 1 );
add_filter( 'style_loader_s rc', '_remove_script _version', 15, 1 );
Добавьте этот код в файл function.php в папке вашей темы на WP.
RSS лента комментариев этой записи