
QEMU 11.1.2 - Alta - Local/Remoto - OOB - Estouro de heap L4 IPv4 curto no filtro-rewriter do COLO
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · qemu-colo-l4-oob
QEMU v11.1.2 (4fc49f46dc95d4a27de2509e7fceb2931e91faeb) - filtro reescritor do COLO
Classe: OOB (estouro de buffer de heap READ/WRITE). Alcance: Local (convidado) / Remoto (par COLO).
parse_packet_early aceita IPv4 assim que L2 mais ip_hl*4 couber. Nunca exige um cabeçalho L4 mínimo. fill_connection_key então lê quatro bytes em transport_header sem verificação de comprimento restante. O filter-rewriter copia o quadro com g_malloc0(size) e, após o SYN ter movido a conexão para TCPS_SYN_RECEIVED, um ACK com conn->offset != 0 grava th_ack / th_seq além desse bloco quando o comprimento capturado termina no cabeçalho de transporte.
O COLO não é padrão. Ele fica ativo quando -object filter-rewriter (e colo-compare) está configurado. TX/RX do convidado nesse reescritor está no modelo de segurança da virtualização. Um par COLO em primary_in / secondary_in é um protocolo de rede, também não confiável.
Um quadro IPv4/TCP de 34 bytes é suficiente para um heap-buffer-overflow READ do ASan no filter-rewriter.
| ID | ainda sem CVE |
| CWE | CWE-125 / CWE-787 |
| CVSS | Alto: 8.2 CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H |
| Produto | QEMU |
| Afetado | v11.1.2 (4fc49f46), rewriter/compare do COLO habilitados |
| Autenticação | convidado em um netdev rewriter do COLO, ou um par de comparação COLO |
| Licença | GNU Affero GPL v3.0 |
| Laboratório | soquetes loopback 127.0.0.1:18770 / 18771 |
Quem: convidado não confiável em uma NIC com COLO habilitado, ou um par de comparação COLO hostil. Convidado-para-host / par-para-host. Heap do espaço de usuário do QEMU.
| Método | Destino | Privilégio |
|---|---|---|
| ACK IPv4/TCP curto após um SYN de cabeçalho completo (quadro de 34 bytes, comprimento termina no cabeçalho de transporte) | filter-rewriter handle_primary_tcp_pkt / fill_connection_key | heap-buffer-overflow READ do ASan no filter-rewriter. TCP de cabeçalho completo de controle deixa o QEMU vivo. |
| Mesma ausência de piso L4 | parse_packet_early net/colo.c:43-98 | O pacote é classificado como TCP sem um cabeçalho L4 no buffer. |
Após o SYN, conn->offset != 0, o rewriter armazena th_ack / th_seq em net/filter-rewriter.c:112-114 e :216-218. Opções IP (ip_hl > 5) deslocam essa gravação para o próximo bloco de heap. WRITE no heap do host acionável pelo convidado.
O colo-compare fill_pkt_tcp_info define header_size a partir de th_off<<2 sem verificação contra pkt->size. payload_size sofre underflow. colo_compare_packet_payload faz memcmp de dezenas de kilobytes além de ambas as alocações de pacote. Crash mais READ no heap do host.
Abort do QEMU sob ASan na leitura do rewriter. Sem ASan, isto é um OOB de heap ativo no processo do hipervisor.
net_fill_rstate rejeita packet_len > NET_BUFSIZE).O laboratório não demonstra controle de RIP nem um shell de convidado para host. A classe é OOB de heap do processo QEMU em um netdev com COLO habilitado.
Li net/colo.c à procura de um limite mínimo de comprimento que incluísse a L4. O limite é Ethernet mais VLAN mais vnet_hdr. ip_hl é obtido a partir de uma cauda curta. fill_connection_key então confia em transport_header. O filter-rewriter sempre carrega th_flags no deslocamento 13 de struct tcp_hdr.
Caminhos errados: tratar o comprimento do TAP como o limite do COLO (caminho diferente); enviar o overflow como o primeiro pacote (o rewriter precisa do SYN primeiro para que conn->offset esteja ativo); o underflow de th_off do colo-compare como testemunha principal (o READ do rewriter disparou primeiro).
cd lab
./run.sh
Tem como alvo apenas sockets de loopback 127.0.0.1:18770 (filter-rewriter netdev) e 18771 (colo-compare). O pin é clonado de github.com/qemu/QEMU tag v11.1.2 / 4fc49f46. ASan. COLO proxy habilitado no momento da configuração. Apenas testemunha.
SUCCESS qemu-colo-l4-oob asan=heap-buffer-overflow access=READ sink=filter-rewriter control=alive QEMU-COLO-L4-OOB-WITNESS
Replay: python3 qemu-colo-l4-oob-Abraxas-Labs.py.
parse_packet_early deve exigir um cabeçalho L4 completo (TCP 20, UDP 8, SCTP 12, AH 8) após o cabeçalho IP, e rejeitar quando size termina em ou antes de transport_header. fill_connection_key e os armazenamentos th_* do rewriter devem verificar o comprimento restante. O colo-compare deve rejeitar th_off<<2 que não caiba em pkt->size antes de calcular payload_size.
4fc49f46dc95d4a27de2509e7fceb2931e91faebparse_packet_early · filter-rewriterGNU Affero GPL v3.0. Consulte LICENSE. Apenas laboratório de loopback. Sem garantias.