Пользователь
0,0
рейтинг
4 августа 2014 в 13:49

Разработка → И опять атака на сайты Wordpress — перебор + XMLRPC

С полудня субботы на моем сервере, где хостится около 25 сайтов на Wordpress, начались дикие тормоза. Так как мне удалось пережить предыдущие атаки (атака 1 — ровно год назад, атака 2 — в марте) не замеченными, то я не сразу понял, в чем дело.

Когда разобрался, то выяснилось, что идет перебор паролей + множество запросов к XMLRPC.

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

Эти приемы скорее всего всем известны, но я наступил на пару граблей, которых не нашел в описаниях — вдруг это кому-то сэкономит время.

1. Останавливаем перебор, плагин Limit Login Attempts — ставим именно его, так как другие защиты сильно подвешивают сервер, например, при использовании плагина Login Security Solution сервер умер через полчаса, плагин сильно грузит базу.

В настройке обязательно включите галочку «За прокси» — иначе он будет для всех определять ip вашего сервера и автоматически блокировать всех.
UPDATE, спасибо DarkByte, подробности ниже в комментах — галочку «За прокси» включаем только если не работает определение при включенном «Прямое подключение»



2. Отключаем XML-RPC — плагин Disable XML-RPC (его просто активировать и всё).

3. Закрываем wp-login.php — если обращаться к сайту через ip, то плагин не срабатывает и подборщики продолжают долбить сайт. Чтобы этого избежать, в .htaccess добавляем:

<Files wp-login.php>
Order Deny,Allow
Deny from all
</Files>


Файл wp-login копируем, переименовываем в любое странное имя, например poletnormalny.php и внутри файла автозаменой меняем все надписи wp-login.php на poletnormalny.php.
Все, теперь к админке можно обратиться только по вашему файлу.

После этих 3 несложных шагов сайты опять начали летать и пришло спокойствие.

Ну и вдруг интересно


Один из вариантов как посмотреть, что вас атакуют. Это можно увидеть в логах nginx (например, вот путь для Debian /var/log/nginx файл access.log).

Если идет перебор, то вы увидите множество строк вида:
87.230.87.xx — - [04/Aug/2014:06:35:53 +0400] «POST /wp-login.php HTTP/1.0» 200 5791 "-" "-"

Запросы XMLRPC:
95.0.83.xx — - [04/Aug/2014:06:48:03 +0400] «POST /xmlrpc.php HTTP/1.0» 499 0 "-" «Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)»
Alex Awaikin @awaik
карма
7,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (21)

  • –6
    А не было идеи ни у кого всем договориться и включить диапазоны все адреса хецнеров и других крупных хостингов сразу в access deny? Кому нужно смотреть сайт с ip хостеров, кроме как боту или анонимайзеру?
    • +20
      Мне. У меня VPN на Хецнере.
      Благодаря таким, как вы, я не могу ходить на auto.ru, Доброчан и кучу всего еще.
      • –7
        Ну и сколько таких как вы людей? Сайт не много потеряет, тем более можно добавить статический маршрут мимо ВПН и без проблем смотреть нужные сайты, я думаю для человека который пользуется ВПН, это не проблема.
    • +3
      Мне, нужен. Держу VPN у хецнера и на некоторых администрируемых ресурсах (в том числе WP), вход в админку разрешен только с IP адреса сервера.
  • 0
    fail2ban вам в помощь, люди для ленивых уже даже плагин сделали (правда насколько рабочий не знаю, т.к. обычно ручками — новый jail и регулярка для фильтра делается для fail2ban за пару минут)…
  • 0
    В настройке обязательно включите галочку «За прокси» — иначе он будет для всех определять ip вашего сервера и автомат блокировать всех.

    Эта галочка случаем не использует заголовок X-Real-IP (X-Forwarded-For, и другие) вместо REMOTE_ADDR? Если так, то получился вредный совет, вместо полезного, и правильным выходом из ситуации будет корректная настройка веб сервера.
    • 0
      Проверил в коде плагина, да она использует
      define('LIMIT_LOGIN_PROXY_ADDR', 'HTTP_X_FORWARDED_FOR');

      Однако у меня без ее включения не работает корректно определение ip адреса. Быть может вы поделитесь почему это вредно и как поправить, буду очень благодарен!

      Из описания плагина
      What is this option about site connection and reverse proxy?
      A reverse proxy is a server in between the site and the Internet (perhaps handling caching or load-balancing). This makes getting the correct client IP to block slightly more complicated.The option default to NOT being behind a proxy — which should be by far the common case.
      • +4
        Насколько я понял, у вас используется связка nginx+apache, в таком случае до апача коннекты от всех клиентов доходят от адреса сервера (или 127.0.0.1). Правильно в таком случае со стороны nginx выставлять соответствующие заголовки:
        proxy_set_header X_REAL_IP $remote_addr;
        proxy_set_header X_FORWARDED_FOR $proxy_add_x_forwarded_for;

        А к апачу добавить модуль mod_rpaf2 и сказать ему, что реальный адрес пользователя находится в заголовке X_REAL_IP
        RPAFenable On
        RPAFsethostname On
        RPAFproxy_ips 127.0.0.1
        RPAFheader X-REAL-IP

        В RPAFproxy_ips указывается IP адрес сервера с nginx, если он находится на другим IP. Плюсом, после настройки модуля, в логах apache будут реальные адреса пользователей, а не адрес nginx или localhost.

        В противном случае, если включить опцию доверия заголовку HTTP_X_FORWARDED_FOR, а веб сервер будет не за прокси, то атакующий сможет с использованием данного заголовка обмануть плагин, отправляя с каждым запросом разномные IP адреса.
        • 0
          спасибо за ценный совет! Текст статьи обновил.
  • 0
    Включить Limit Login Attempts и отключить XML RPC будет достаточно? Хочется какого-то быстрого универсального решения, на будущее.
    • 0
      да, достаточно. Я планирую на днях написать плагинчик, который делает сразу 3 действия:
      1. limit logins
      2. отключает XML RPC с вариантами, например, чтобы можно было или полностью опцию отключить или только pingback
      3. переименование wp-login.php в выбранное имя

      Там ничего сложного, но потом проще будет обновлять и дополнять в будущем кучи сайтов свои. Если напишу кину тут ссылку на репозиторий.
      • 0
        Плагин iThemes security (бывший Better WP security) всё это умеет (и ещё много всего). Разве что потяжелее будет.
        • 0
          спасибо, он действительно тяжеловесный и большой, но оттуда можно взять несколько идей и текстов
  • +1
    location ~* /(wp-login\.php|administrator|admin\.php) {
    	set $humantest 0;
    	if ($http_cookie !~* "humans=checktest") {
    		set $humantest 1;
    	}
    	if ($args ~* (callback|logout|lostpassword)) {
    		set $humantest 0;
    	}
    	if ($humantest = 1) {
    		add_header Content-Type text/html;
    		return 200 "<html><body><script>document.cookie='humans=checktest;path=/';location.reload();</script></body></html>";
    	}
    	error_page 404 = @fallback;
    }
    
    

    Код не мой, но позволяет без всяких танцев с плагинами избавится от всякой живности, родился он примерно год назад и зомби еще не научились его парсить…
    • 0
      Иногда у nginx «default_type» выставлен в что то отличное от «text/html», и тогда мы можем получить в ответ что-то типа такого:
      HTTP/1.1 200 OK
      ...
      Content-Type: application/octet-stream
      Content-Length: 103
      Connection: keep-alive
      Keep-Alive: timeout=5
      Content-Type: text/html
      ...

      Некоторые браузеры не понимаю что это и предлагают «сохранить файл». Что бы такого не было, можно сделать так:
              location ~* /(wp-login\.php|administrator|admin\.php) {
                      default_type text/html;
                      set $humantest 0;
                      if ($http_cookie !~* "humans=checktest") {
                              set $humantest 1;
                      }
                      if ($args ~* (callback|logout|lostpassword)) {
                              set $humantest 0;
                      }
                      if ($humantest = 1) {
                              return 200 "<html><body><script>document.cookie='humans=checktest;path=/';location.reload();</script></body></html>";
                      }
                      error_page 404 = @fallback;
              }
      
      
    • 0
      Если ставить код после (кода ниже) то не работает, а если перед, то PHP не исполняется. Куда его ставить?

         location ~ \.php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+\.php)(/.+)$;
              fastcgi_pass unix:/var/run/php5-fpm.sock;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
              fastcgi_read_timeout 120;
              include fastcgi_params;
          }
      
  • 0
    А я когда-то прописал в .htaccess:

    #Защита от подбора пароля	
    <Files wp-login.php>
    Order Deny,Allow
    Deny from all
    allow from домашний_ip
    allow from рабочий_ip
    </Files>
    
    # protect xmlrpc
    <Files xmlrpc.php>
    	Order Deny,Allow
    	Deny from all
    </Files>	
    


    Если ip выдается динамически можно указать сеть провайдера.
    Вызов удаленных процедур, за который отвечает xmlrpc.php, мне не нужен
    • –1
      Спасибо! Отличный вариант
  • 0
    Буквально сегодня установил All In One WP Security & Firewall. Очень широкий функционал и никаких танцев с бубном.

    • 0
      Нет поддержки nginx
  • 0
    Нужно обновить WordPress (уязвимость в XML-парсере). Подробности: wordpress.org/news/2014/08/wordpress-3-9-2/
    Советую подписаться, чтобы получать подобные новости первыми.

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