
QEMU 11.1.2 - Alta - Locale/Remota - OOB - Overflow heap IPv4 L4 breve in COLO filter-rewriter
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · qemu-colo-l4-oob
QEMU v11.1.2 (4fc49f46dc95d4a27de2509e7fceb2931e91faeb) - filtro-rewriter COLO
Classe: OOB (lettura/scrittura oltre i limiti del buffer heap). Portata: Locale (guest) / Remota (peer COLO).
parse_packet_early accetta IPv4 una volta che L2 più ip_hl*4 rientra. Non richiede mai un header L4 minimo. fill_connection_key legge poi quattro byte a transport_header senza alcun controllo della lunghezza residua. filter-rewriter copia il frame con g_malloc0(size) e, dopo che SYN ha spostato la connessione a TCPS_SYN_RECEIVED, un ACK con conn->offset != 0 scrive th_ack / th_seq oltre quel blocco quando la lunghezza catturata termina all'header di trasporto.
COLO non è predefinito. È attivo quando è configurato -object filter-rewriter (e colo-compare). Il TX/RX del guest su quel rewriter rientra nel modello di sicurezza della virtualizzazione. Un peer COLO su primary_in / secondary_in è un protocollo di rete, anch'esso non attendibile.
Un frame IPv4/TCP di 34 byte è sufficiente per un heap-buffer-overflow READ di ASan in filter-rewriter.
| ID | nessuna CVE al momento |
| 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 |
| Prodotto | QEMU |
| Affetto | v11.1.2 (4fc49f46), rewriter/compare COLO abilitati |
| Auth | guest su un netdev rewriter COLO, oppure un peer compare COLO |
| Licenza | GNU Affero GPL v3.0 |
| Lab | socket loopback 127.0.0.1:18770 / 18771 |
Chi: guest non attendibile su una NIC abilitata a COLO, oppure un peer compare COLO ostile. Da guest a host / da peer a host. Heap dello spazio utente di QEMU.
| Metodo | Sink | Privilegio |
|---|---|---|
| ACK IPv4/TCP corto dopo un SYN con header completo (frame di 34 byte, lunghezza che termina all'header di trasporto) | filter-rewriter handle_primary_tcp_pkt / fill_connection_key | heap-buffer-overflow READ di ASan in filter-rewriter. Il TCP di controllo con header completo lascia QEMU vivo. |
| Stesso limite minimo L4 mancante | parse_packet_early net/colo.c:43-98 | Il pacchetto viene classificato come TCP senza un header L4 nel buffer. |
Dopo SYN, conn->offset != 0, il rewriter memorizza th_ack / th_seq in net/filter-rewriter.c:112-114 e :216-218. Le opzioni IP (ip_hl > 5) spostano quella scrittura sul chunk heap successivo. Scrittura heap sull'host attivabile dal guest.
colo-compare fill_pkt_tcp_info imposta header_size da th_off<<2 senza alcun controllo rispetto a pkt->size. payload_size va in underflow. colo_compare_packet_payload esegue memcmp per decine di kilobyte oltre entrambe le allocazioni dei pacchetti. Crash più lettura heap sull'host.
QEMU termina in modo anomalo sotto ASan sulla lettura del rewriter. Senza ASan si tratta di un OOB heap attivo nel processo dell'hypervisor.
net_fill_rstate rifiuta packet_len > NET_BUFSIZE).Il laboratorio non dimostra il controllo di RIP né una shell da guest a host. La classe è OOB heap del processo QEMU su un netdev abilitato a COLO.
Leggo net/colo.c cercando un limite minimo di lunghezza che includesse L4. Il limite è Ethernet più VLAN più vnet_hdr. ip_hl viene preso da una coda corta. fill_connection_key poi si fida di transport_header. filter-rewriter carica sempre th_flags all'offset 13 di struct tcp_hdr.
Vicoli ciechi: trattare la lunghezza TAP come il limite COLO (percorso diverso); inviare l'overflow come primo pacchetto (il rewriter necessita prima del SYN affinché conn->offset sia attivo); l'underflow di th_off in colo-compare come prova principale (la READ del rewriter è scattata prima).
cd lab
./run.sh
Destinazione solo socket loopback 127.0.0.1:18770 (netdev filter-rewriter) e 18771 (colo-compare). Il pin è clonato da github.com/qemu/QEMU tag v11.1.2 / 4fc49f46. ASan. Proxy COLO abilitato in fase di configure. Solo witness.
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 richiedere un header L4 completo (TCP 20, UDP 8, SCTP 12, AH 8) dopo l'header IP, e rifiutare quando size termina in corrispondenza o prima di transport_header. fill_connection_key e gli store th_* del rewriter devono verificare la lunghezza rimanente. colo-compare deve rifiutare th_off<<2 che non rientra in pkt->size prima di calcolare payload_size.
4fc49f46dc95d4a27de2509e7fceb2931e91faebparse_packet_early · filter-rewriterGNU Affero GPL v3.0. Vedi LICENSE. Solo lab loopback. Nessuna garanzia.