
Уязвимость 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
-
AV:N (Вектор атаки: Сетевой) – Удалённая эксплуатация через интернет.
-
AC:H (Сложность атаки: Высокая) – Требуются сложные условия или манипуляции.
-
PR:N (Привилегии: Нет) – Доступ к системе не требуется.
-
UI:N (Взаимодействие: Нет) – Участие пользователя не нужно.
-
S:U (Область: Неизменная) – Влияет только на уязвимый компонент.
-
C:H (Конфиденциальность: Высокое) – Полная утечка данных.
-
I:H (Целостность: Высокое) – Возможность полного изменения данных.
-
A:L (Доступность: Низкое) – Ограниченное влияние на работоспособность системы.
Интерпретация: Уязвимость высокой опасности (7.7) позволяет удалённо нарушить конфиденциальность и целостность данных, но требует сложных условий эксплуатации. Риск связан с критическим воздействием на защищённость информации, несмотря на низкое влияние на доступность системы.
Условия эксплуатации
-
Уязвимые версии: nginx 0.6.18 – 1.20.1.
-
Сценарий атаки:
-
Сервер nginx должен использовать DNS-резолвер (настройка
resolver
в конфиге).
Пример конфигурации:
server { resolver 8.8.8.8; location / { proxy_pass http://backend$request_uri; } }
-
Атакующий должен отправить поддельный DNS-ответ на UDP-порт 53 сервера.
-
-
Сетевой доступ:
-
Для эксплуатации через ARP-спуфинг (как в PoC) атакующий должен находиться в той же локальной сети.
-
Внешняя атака возможна, если злоумышленник контролирует DNS-сервер, используемый nginx.
-
Анализ эксплоита из общего доступа
Код из общего доступа для эксплуатации уязвимости BDU:2021-02749 (CVE-2021-23017) выполняет ARP-спуфинг для перехвата DNS-запросов целевого сервера и подмены ответов. Рассмотрим ключевые этапы:
-
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-сервер для цели и наоборот, перенаправляя трафик через свой интерфейс.
-
Перехват DNS-запроса:
Функцияsniff
из библиотеки Scapy отслеживает UDP-пакеты на порту 53:sniff(filter="udp and port 53 and host " + target, prn=process_received_packet)
-
Формирование вредоносного ответа:
В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()
, которая неправильно обрабатывает завершающую точку, вызывая переполнение.
Способы защиты
-
Обновление nginx:
Установите версию 1.21.0 или выше. Для проверки текущей версии:nginx -v
-
Сетевые меры:
-
Отключите ARP-спуфинг через статическиe ARP-записи или DHCP snooping.
-
Используйте DNSSEC для проверки подлинности DNS-ответов.
-
-
Конфигурация nginx:
Ограничьте использованиеresolver
доверенными DNS-серверами:resolver 8.8.8.8 valid=10s; resolver_timeout 5s;
