1С-Битрикс — одна их самых популярных систем CMS. Включает в себя много интересных решений, начиная от сайта визитки, заканчивая высоконагруженными системами. Мы часто встречаем во время пентестов данный продукт и отмечаем, что большинство обнаруживаемых проблем безопасности можно увидеть в самописных модулях, а не в самом ядре Битрикса. Однажды, анализируя защищенность одной системы, построенной на основе коробочного решения, мы задетектили ряд любопытных уязвимостей. Жаль, но про все рассказывать нельзя, а вот про удаленное выполнение кода и повышение привилегий на сервере — уже можно.
Кстати, разработчики RCE исправлять отказались.
Вредоносный кот
Если вы знакомы с интеграцией Битрикса и 1С Бухгалтерией, то наверняка встречали скрипт под названием “1c_bx_import.php”. Если коротко: это отладочный скрипт для диагностики, подробнее с его возможностями можно ознакомиться по ссылке от разработчиков. Помимо ряда специфичных действий, он реализует возможность скачивать и загружать файлы на сервер, распаковывать архивы, удалять произвольные файлы.
Ситуация с данным скриптом неоднозначная: со слов разработчиков, он не является официальной частью CMS, однако расположен на ресурсах компании и иногда используется технической поддержкой для решения проблем клиентов. В конечном счете это означает, что его вполне можно встретить на различных ресурсах, порой прямо в корне сайта. Разработчик честно указал, что пользоваться данным изделием следует только на свой страх и риск, но юзеры наверняка считают, что все безопасно и хорошо, ведь в скрипте присутствует аутентификация и авторизация. К сожалению, это не совсем так.
Давайте посмотрим, как в скрипте реализована аутентификация:
if ((@$_REQUEST['mode']!='query' && @$_REQUEST['mode']!='exchange'))
define('NEED_AUTH',true);
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
Скорее всего, изначально задумывалось, что если в URI параметр “mode” равен “query” или “exchange”, то пользователю отдается форма логина, и работа скрипта завершается. Однако, если присмотреться внимательно, то можно заметить, что в логические операторы вкралась ошибка. Получилось ровным счетом наоборот: аутентификация будет запрошена только если “mode” не равен «query» или «exchange»!
Теперь проверим, что в скрипте с авторизацией. Разработчик предполагал, что скрипт должен выполняться только у администраторов:
if ((!$USER->IsAdmin())&&(@($_GET['mode']!='query')))
{
echo 'Доступ запрещён. Вы не администратор сайта. До свидания.';
localredirect("/404.php");
}
Если не будут выполнены оба условия, выполнение скрипта закончится. Давайте посмотрим еще раз внимательно:
Если пользователь не администратор, и если mode не равен query, то вывести «Доступ запрещен».
Получается, можно не быть администратором, первое условие не будет истинным, в секцию «Доступ запрещен» мы не попадаем, а скрипт успешно продолжит работу. Выходит, что если анонимный пользователь укажет в качестве параметра «mode» значение «query», ему станут доступны все действия внутри скрипта (за выбор типа функции отвечает параметр «action»). Учитывая, что функциональность файла позволяет скачивать файлы с сервера и загружать их в произвольную директорию, публичный доступ к данному скрипту является весьма большой угрозой для безопасности.
Полный список команд, доступных для выполнения:
- createfile — создание файла с текстом “success” по заданному пути
- setsession — добавление произвольной Cookie в текущую сессию пользователя
- createiblocktypeform — создание типа инфоблока
- download — скачивание произвольного файла с сервера
- xmlgetinfo — скачивание произвольного файла с сервера
- deletefile — удаление произвольного файла с сервера
- getfile — получение списка файлов на сервере
- unzip — распаковка архива
- upload — загрузка файла в произвольную директорию
- search — поиск файла на сервере
- show_bxmltree — вывод структуры директории в виде xml-файла
Вот, например, запрос, позволяющий скачать конфигурационный файл, содержащий учетную запись для доступа к базе данных:
А таким запросом злоумышленник может получить листинг файлов на сервере:
Можно, наконец, и произвольный код загрузить:
Про уязвимость мы сообщили как клиенту, так и разработчикам CMS. К сожалению, разработчики Битрикса исправлять ошибку отказались, поскольку данный скрипт не является официальным компонентом CMS, как уже было отмечено выше.
Локальное повышение привилегий
Разработчики 1C-Битрикс Веб-кластера допустили ошибку, которая позволяет получить привилегии суперпользователя (root) на всех серверах кластера, обладая доступом к системному пользователю bitrix на одном из серверов кластера.
В 1C-Битрикс Веб-кластер используется система управления серверами Ansible, аутентификация между серверами осуществляется посредством SSH-ключей. Доступ к файлам ключей есть только у суперпользователя. Для того, чтобы Ansible мог прочитать ключи и выполнять команды на удаленных серверах, применяется утилита sudo, повышающая привилегии до пользователя root.
Установщик кластерной системы добавляет следующую строку в файл конфигурации команды sudo /etc/sudoers:
bitrix ALL=NOPASSWD: /usr/bin/ansible * -m setup
Вместо символа звездочки скрипты системы подставляют имя сервера в кластере.
Утилита sudo ищет вхождения подстроки в строку, а не разделяет аргументы, как это было бы в случае системных команд класса execv. Символ звездочки в строке выше позволяет вставить произвольное количество символов, которые будут разделены на отдельные аргументы. Поэтому повысить свои привилегии можно легко одной командой:
$ sudo /usr/bin/ansible 127.0.0.1 -m shell -a 'whoami; echo -m setup'
127.0.0.1 | success | rc=0 »
root
-m setup
bitrix@test: ~
Для самого sudo аргументы выглядят следующим образом:
["sudo", "/usr/bin/ansible", "127.0.0.1", "-m", "shell", "-a", "whoami; echo -m setup"]
И это соответствует написанному разработчиками правилу sudoers.
С данной уязвимостью разработчики согласились, и на текущий момент она уже исправлена.
Вывод
Что мы получаем в итоге? Уязвимости достаточно просты и не требуют специфических условий для эксплуатации.
Перечислим наши действия при поиске возможностей для получения контроля над тестируемым сайтом:
- Определяем хост, запускаем процедуру подбора файлов и директорий (dirbuster).
- Встретился “bx_1c_import.php”. Скачиваем исходники с сайта разработчика для анализа.
- Найдена возможность скачивать произвольные файлы с сервера.
- Первостепенно скачиваем конфигурационный файл для доступа к БД — dbcon.php. Увы, MySQL ждет подключений только с “localhost”. Анализируем исходники дальше.
- Найдена возможность загружать собственный код. Получаем бэкконнект на наш сервер, однако, текущий пользователь, под которым запущен веб-сервер и от имени которого мы работаем, имеет ограниченный набор прав.
- В результате анализа тестируемого хоста становится ясно – это целый кластер. Да и не стали бы делать интеграцию с 1С у сайта-визитки.
- Изучаем возможность взаимодействия с “Ansible”.
- Повышаем привилегии до root уже на всем кластере.
- …
- Ищем новые уязвимости.
Автор: Digital Security