Уязвимость в FortiOS и FortiProxy
Уязвимость в FortiOS и FortiProxy
Категория: Программы Теги: Уязвимости Опубликовано: 16 апреля 2025

Уязвимость BDU:2025-00281 (CVE-2024-55591) в FortiOS и FortiProxy

Уязвимость BDU:2025-00281 (CVE-2024-55591) в операционных системах FortiOS (7.0.0–7.0.17) и прокси-сервере FortiProxy (7.0.0–7.0.20, 7.2.0–7.2.13) позволяет удаленному злоумышленнику повысить привилегии до уровня «super-admin» без прохождения корректной аутентификации. Проблема связана с некорректной обработкой WebSocket-запросов в модуле Node.js, что приводит к обходу процедуры проверки прав доступа.

CVSS 3.0: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Технический анализ

Код эксплоита из общего доступа написан на Python с использованием библиотеки websockets для работы с WebSocket и модуля asyncio для асинхронного взаимодействия. Разберем ключевые компоненты:


1. Формирование полезной нагрузки

DEFAULT_EXPLOIT_PAYLOAD_TEMPLATE = "\"{username}\" \"admin\" \"root\" \"super_admin\" \"root\" \"none\" [127.0.0.1]:1337 [127.0.0.1]:1337\n"  
  • Цель: Подмена учетных данных.

  • Механика:

    • Параметр {username} заменяется на предоставленное имя пользователя (например, легитимного администратора).

    • Последовательность "super_admin" "root" указывает системе на необходимость повышения прав до уровня супер-администратора.

    • [127.0.0.1]:1337 — вероятно, попытка задать IP и порт для обратного подключения (в данном случае — локальный адрес, что может быть артефактом тестового кода).


2. Установление WebSocket-соединения

path = f"wss://{target}:{port}/ws/cli/?local_access_token={LOCAL_ACCESS_TOKEN}"  
async with websockets.connect(path, ssl=ssl_context) as websocket:  
  • Ключевые параметры:

    • local_access_token=GIANTYELLOWDUCK: Фиксированный токен, который, вероятно, не проверяется сервером должным образом (захардкожен в системе).

    • ssl=ssl_context: SSL-контекст с отключенной проверкой сертификата (ssl.CERT_NONE), что позволяет обходить ошибки самоподписанных сертификатов.


3. Отправка и прием данных

  • Функция send_payload:

    await websocket.send(payload)  
    response = await receive_complete_message(websocket, debug)  
    • Особенности:

      • Отправка происходит через асинхронный метод websocket.send().

      • Ответ обрабатывается функцией receive_complete_message, которая собирает данные из нескольких WebSocket-фреймов.

  • Функция receive_complete_message:

    full_message = b""  
    while True:  
        raw_data = await raw_receive(websocket, debug)  
        if raw_data is None:  
            break  
        full_message += raw_data  
    • Цель: Реконструкция полного сообщения из потока фреймов.

    • Проблема: Таймаут RECEIVE_TIMEOUT = 0.3 может быть недостаточным для медленных сетей, что приведет к потере данных.


4. Выполнение произвольных команд

await send_payload(websocket, command + "\n", debug)  
  • Механика:

    • После повышения привилегий скрипт отправляет команду, переданную через аргумент --command (например, execute reboot или config user add).

    • Символ \n имитирует нажатие Enter в CLI.


5. Механизмы устойчивости

async def retrying_main(...):  
    while True:  
        success = await main(...)  
        if success:  
            break  
        await asyncio.sleep(0.5)  
  • Цель: Повторное подключение при ошибках (например, разрыв соединения).

  • Риск: Бесконечный цикл может привести к DoS, если сервер блокирует IP после множества попыток.


Критические точки эксплоита

  1. Использование захардкоженного токена:

    • Значение GIANTYELLOWDUCK, вероятно, было обнаружено через реверс-инжиниринг или утечку конфигурации.

    • Сервер не проверяет действительность токена, принимая его как доверенный.

  2. Отсутствие проверки подлинности сертификата:

    ssl_context = ssl.create_default_context()  
    ssl_context.check_hostname = False  
    ssl_context.verify_mode = ssl.CERT_NONE  
    • Это позволяет подключаться к серверу с самоподписанным или невалидным сертификатом.

  3. Инъекция команд через WebSocket:

    • Уязвимый эндпоинт /ws/cli/ интерпретирует переданные данные как команды CLI, минуя проверки ACL.


Как эксплоит обходит аутентификацию?

  1. Эндпоинт /ws/cli/: Предназначен для внутреннего использования (например, для служб FortiOS), но не защищен должным образом.

  2. Фиксированный токен: Параметр local_access_token не генерируется динамически, что делает его уязвимым для перебора.

  3. Подмена контекста пользователя: Полезная нагрузка переопределяет текущего пользователя на super_admin, используя уязвимость в парсере аргументов WebSocket-модуля.


Условия успешной эксплуатации

  • Доступ к WebSocket-интерфейсу: Атакующий должен иметь возможность установить соединение с портом 443 (или другим, если изменена конфигурация) целевого устройства.

  • Отсутствие исправлений: Уязвимы версии FortiOS и FortiProxy, не обновленные до актуальных релизов (7.0.18+ для FortiOS, 7.0.21+/7.2.14+ для FortiProxy).

  • Сетевой доступ: В большинстве сценариев атакующий должен находиться во внутренней сети или иметь доступ к административному интерфейсу устройства через интернет (если порт открыт в публичную зону).


Рекомендации для анализа защитных мер

  1. Поиск захардкоженных токенов:

    • Проверить конфигурационные файлы FortiOS/FortiProxy на наличие GIANTYELLOWDUCK или аналогичных констант.

  2. Мониторинг WebSocket-трафика:

    • Сигнатура для обнаружения:

      path="/ws/cli/" && query="local_access_token=GIANTYELLOWDUCK"  
  3. Анализ логов CLI:

    • Команды, выполненные через WebSocket, могут отсутствовать в стандартных логах администратора. Ищите аномалии в системных вызовах.

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