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

Уязвимость BDU:2021-02749 (CVE-2021-23017) nginx

Уязвимость возникает в функции ngx_resolver_copy() модуля DNS-резолвера nginx. Ошибка заключается в единичном смещении (off-by-one) при копировании доменного имени из DNS-ответа. Когда имя заканчивается точкой (символ 0x2E), точка записывается за пределы выделенного буфера в куче. Это приводит к повреждению соседних структур данных, что может быть использовано для выполнения произвольного кода (RCE) или отказа в обслуживании (DoS).

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

Уровень опасности: 7.7 (Высокий)
Вектор атаки: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L

  1. AV:N (Вектор атаки: Сетевой) – Удалённая эксплуатация через интернет.

  2. AC:H (Сложность атаки: Высокая) – Требуются сложные условия или манипуляции.

  3. PR:N (Привилегии: Нет) – Доступ к системе не требуется.

  4. UI:N (Взаимодействие: Нет) – Участие пользователя не нужно.

  5. S:U (Область: Неизменная) – Влияет только на уязвимый компонент.

  6. C:H (Конфиденциальность: Высокое) – Полная утечка данных.

  7. I:H (Целостность: Высокое) – Возможность полного изменения данных.

  8. A:L (Доступность: Низкое) – Ограниченное влияние на работоспособность системы.

Интерпретация: Уязвимость высокой опасности (7.7) позволяет удалённо нарушить конфиденциальность и целостность данных, но требует сложных условий эксплуатации. Риск связан с критическим воздействием на защищённость информации, несмотря на низкое влияние на доступность системы.

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

  1. Уязвимые версии: nginx 0.6.18 – 1.20.1.

  2. Сценарий атаки:

    • Сервер nginx должен использовать DNS-резолвер (настройка resolver в конфиге).
      Пример конфигурации:

    server {
        resolver 8.8.8.8;
        location / {
            proxy_pass http://backend$request_uri;
        }
    }
    • Атакующий должен отправить поддельный DNS-ответ на UDP-порт 53 сервера.

  3. Сетевой доступ:

    • Для эксплуатации через ARP-спуфинг (как в PoC) атакующий должен находиться в той же локальной сети.

    • Внешняя атака возможна, если злоумышленник контролирует DNS-сервер, используемый nginx.

Анализ эксплоита из общего доступа

Код из общего доступа для эксплуатации уязвимости BDU:2021-02749 (CVE-2021-23017) выполняет ARP-спуфинг для перехвата DNS-запросов целевого сервера и подмены ответов. Рассмотрим ключевые этапы:

  1. ARP-отравление:

    def ARPP(target, dns_server):
        send(ARP(op=2, pdst=target, psrc=dns_server, hwdst=target_mac))
        send(ARP(op=2, pdst=dns_server, psrc=target, hwdst=dns_server_mac))

    Атакующий маскирует себя под DNS-сервер для цели и наоборот, перенаправляя трафик через свой интерфейс.

  2. Перехват DNS-запроса:
    Функция sniff из библиотеки Scapy отслеживает UDP-пакеты на порту 53:

    sniff(filter="udp and port 53 and host " + target, prn=process_received_packet)  
  3. Формирование вредоносного ответа:
    В process_received_packet создается поддельный DNS-ответ, содержащий переполняющие данные. Ключевой фрагмент:

    payload = [
        dns_request[0:2],  # Transaction ID
        b"\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00",  # Флаги (ответ, рекурсия)
        dns_request[12:null_pointer_index+1],  # Часть оригинального запроса
        ...,  # Другие части
        b"\x00\x0B\x18\x41\x41...\xC0\x04"  # CNAME-запись с переполнением
    ]

    Здесь 0x41 (символ 'A') используется для заполнения буфера, а точка (после C0 04) записывается за его пределы.

Как уязвимость активируется через PoC:

  • Эксплоит отправляет DNS-ответ с поддельной CNAME-записью, где длина домена превышает размер буфера.

  • При разборе ответа nginx вызывает ngx_resolver_copy(), которая неправильно обрабатывает завершающую точку, вызывая переполнение.

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

  1. Обновление nginx:
    Установите версию 1.21.0 или выше. Для проверки текущей версии:

    nginx -v  
  2. Сетевые меры:

    • Отключите ARP-спуфинг через статическиe ARP-записи или DHCP snooping.

    • Используйте DNSSEC для проверки подлинности DNS-ответов.

  3. Конфигурация nginx:
    Ограничьте использование resolver доверенными DNS-серверами:

    resolver 8.8.8.8 valid=10s;  
    resolver_timeout 5s;  
Алексей Черемных Алексей Черемных
122