Содержание статьи
Проблема затрагивает все существующие версии Joomla вплоть до 3.8.3. О деталях сообщил исследователь из компании RIPS Technologies. Уязвимость получила идентификатор CVE-2018-6376. В версии 3.8.4 она была исправлена разработчиками CMS, о чем сообщается в анонсе от 30 января.
Проэксплуатировать уязвимость можно, обладая привилегиями менеджера в системе или выше. Сам баг довольно интересный, и его изучение позволит нам поговорить о технике инъекций second order SQL.
Стенд
Для тестирования эксплоита первым делом готовим стенд. Разумеется, у Joomla есть официальный репозиторий на сайте Docker Hub, где ты можешь найти всевозможные версии CMS. Но использовать их я не буду и подготовлю свой контейнер, поскольку делается это всего несколькими командами.
Сначала запускаем контейнер с Debian 9.
docker run -ti -p80:80 --rm --name=joomlavh --hostname=joomlavh debian /bin/bash
Ставим все необходимое: MySQL, Apache 2 и PHP 7.0.
apt-get update && apt-get install -y mysql-server apache2 php php7.0-xml php7.0-mysqli nano wget
Теперь сама CMS. Нам нужна версия 3.8.3.
cd /var/www/html/
wget https://downloads.joomla.org/cms/joomla3/3-8-3/Joomla_3-8-3-Stable-Full_Package.tar.gz?format=gz
tar xzf Joomla*
chown -R www-data:www-data .
И последнее: стартуем нужные сервисы и создаем базу данных для будущей установки приложения.
service mysql start && service apache2 start
mysql -u root -e "CREATE DATABASE joomla; GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'megapass';"
После этого необходимо перейти на свежеподнятый веб-сервер и установить CMS.
Создай аккаунт с правами Manager, через него будем тестировать эксплоит.
Подробнее об уязвимости
Из анонса уязвимости можно узнать, что корень проблемы — в отсутствии приведения типов переменной в информационных сообщениях темплейта Hathor (Hathor postinstall message).
Hathor — это название одного из предустановленных бэкенд-шаблонов административной панели, с которым поставляется Joomla.
По умолчанию используется темплейт isis (на всякий случай: он назван в честь богини Исиды, а не запрещенной в РФ организации), но пользователю разрешено вручную менять его в настройках профиля. Находится эта страничка по адресу
/administrator/index.php?option=com_admin&view=profile&layout=edit
Теперь настало время зарыться в дебри исходников. Но где искать? Отправную точку, как обычно, ищем в коммите, который решает проблему.
Как видишь, нам необходимо заглянуть в файл hathormessage.php
.
/administrator/templates/hathor/postinstall/hathormessage.php
19: function hathormessage_postinstall_condition()
20: {
...
22: $user = JFactory::getUser();
...
39: // Get the current user admin style
40: $adminstyle = $user->getParam('admin_style', '');
41:
42: if ($adminstyle != '')
43: {
44: $query = $db->getQuery(true)
45: ->select('template')
46: ->from($db->quoteName('#__template_styles'))
47: ->where($db->quoteName('id') . ' = ' . $adminstyle[0])
48: ->where($db->quoteName('client_id') . ' = 1');
...
50: // Get the template name associated to the admin style
51: $template = $db->setquery($query)->loadResult();
После патча переменная $adminstyle
приводится к int
, значит, она нам и нужна. Строка 40 говорит нам о том, что значение переменной — это результат работы метода getParam
из класса User
.
/libraries/src/User/User.php
024: class User extends \JObject
025: {
...
318: public function getParam($key, $default = null)
319: {
320: return $this->_params->get($key, $default);
321: }
Параметры ($this->_params
) текущего пользователя — это экземпляр класса Registry
.
/libraries/src/User/User.php
233: public function __construct($identifier = 0, UserWrapper $userHelper = null)
234: {
...
242: // Create the user parameters object
243: $this->_params = new Registry;
При инициализации пользователя, сохранении данных профиля и прочих манипуляциях с пользовательскими настройками данные попадают в эту переменную. В том числе и нужный нам admin_styles
. Нам остается лишь задать ему значение. Выше я уже писал, где находится редактирование профиля текущего юзера.
Давай включим сниффер и сохраним данные профиля. В пойманном пакете будет атрибут с названием jform[params][admin_style]
. Так как в запрос попадает первый элемент массива, то добавляем каноничную кавычку.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»