
Sonda en Go que reproduce el bug de offload de checksum IPv4 de Linux PwnEscape sobre un TAP preparado, inyectando cabeceras virtio manipuladas y verificando la copia fuera de límites de la cabecera del fragmento.
Sonda en Go para el fallo de descarga de checksum IPv4 de Linux conocido como PwnEscape. Se conecta a un TAP que ya hayas preparado y comprueba si el fragmentador del host confía en una cabecera IPv4 reescrita por skb_checksum_help.
La sonda se encarga de la inyección y captura de paquetes. scripts/setup.sh prepara las interfaces de laboratorio, los ajustes de sysctl y la regla de nftables dentro del espacio de nombres de red pwnesc. scripts/teardown.sh elimina el laboratorio.
En un kernel que todavía completa un checksum parcial antes de leer ihl (reproducido aquí en 6.18.54; corregido en 6.18.57):
csum_start=22. A continuación se eliminan dos etiquetas VID-0 (14+4+4), por lo que la escritura del checksum recae sobre el byte de versión/IHL de IPv4.0x45 a 0x4f. El fragmentador usa una cabecera de 60 bytes.-head 8, la cabeza lineal es de 28 bytes, por lo que la copia de la cabecera de 60 bytes lee 32 bytes más allá de skb_headlen dentro de las opciones IPv4 de los fragmentos de salida.Esto ejercita la primitiva de divulgación descrita en el artículo de PWN.AI sobre PwnEscape. Con CONFIG_INIT_ON_ALLOC_DEFAULT_ON, el espacio libre al final del slab recién asignado puede aparecer como ceros en los bytes copiados.
ihlip, nft, sysctlnf_conntrack y nf_defrag_ipv4 integrados o cargables/dev/net/tunDesde el directorio del repositorio en el host:
go build -o poc .
sudo ./scripts/setup.sh
sudo ip netns exec pwnesc ./poc
La sonda abre pwntap con IFF_TAP|IFF_NO_PI|IFF_VNET_HDR y captura la salida en pwnv1. Reserva pwntap para la sonda. La regla ct de nftables activa la defragmentación de conntrack, y pwnv0 usa MTU 200 para fragmentar de nuevo el datagrama reensamblado en la salida.
Una comprobación de cabecera exitosa imprime verify: first byte 0x4f ihl=15. A continuación, la sonda informa de los fragmentos de salida, sus opciones IPv4 y los bytes copiados más allá de la cabeza lineal.
-head (predeterminado 8): carga útil del fragmento en el desplazamiento 0 en bytes; un múltiplo de 8 desde 8 hasta 40. La copia esperada más allá de la cabeza lineal es de 40 - head bytes.-rest (predeterminado 400): carga útil del fragmento de finalización en bytes; al menos 16.-spray (predeterminado 0): número de tramas del mismo tamaño asignadas inmediatamente antes del fragmento en el desplazamiento 0.-spray-fill (predeterminado 0xee): byte usado para rellenar esas tramas.-page: usa una cabeza page_frag, cuya cola puede contener metadatos de skb. El valor predeterminado es una cabeza de slab.-skip-verify: pasa directamente a la comprobación del datagrama fragmentado.PWN_TAP selecciona la interfaz TAP (predeterminado pwntap). PWN_CAP selecciona la interfaz de captura (predeterminado pwnv1). El script de configuración usa estos nombres predeterminados.
Cuando la sonda termine, sal de cualquier shell en pwnesc y ejecuta desde el host:
sudo ./scripts/teardown.sh
Esto elimina pwnesc junto con sus interfaces, la tabla de nftables ip pwn y los ajustes de sysctl locales del espacio de nombres.