
Go-проба, воспроизводящая баг контрольной суммы IPv4 в Linux с offload PwnEscape на подготовленном TAP, внедряющая сформированные заголовки virtio и проверяющая копирование заголовка фрагмента за границами буфера.
Go-проба для ошибки разгрузки контрольных сумм IPv4 в Linux, известной как PwnEscape. Она подключается к заранее подготовленному вами TAP-интерфейсу и проверяет, доверяет ли фрагментатор хоста заголовку IPv4, перезаписанному через skb_checksum_help.
Проба выполняет инъекцию и захват пакетов. scripts/setup.sh подготавливает лабораторные интерфейсы, настройки sysctl и правило nftables внутри сетевого пространства имён pwnesc. scripts/teardown.sh удаляет лабораторную среду.
На ядре, которое всё ещё завершает частичную контрольную сумму до чтения ihl (воспроизведено здесь на 6.18.54; исправлено в 6.18.57):
csum_start=22 принимается. Затем удаляются два тега VID-0 (14+4+4), поэтому запись контрольной суммы попадает на байт версии/IHL IPv4.0x45 на 0x4f. Фрагментатор использует 60-байтовый заголовок.-head 8 линейный заголовок составляет 28 байт, поэтому копия 60-байтового заголовка читает 32 байта за пределами skb_headlen в IPv4-опции выходных фрагментов.Это задействует примитив раскрытия, описанный в статье PWN.AI о PwnEscape. При CONFIG_INIT_ON_ALLOC_DEFAULT_ON свежее хвостовое пространство slab может отображаться как нули в скопированных байтах.
ihlip, nft, sysctlnf_conntrack и nf_defrag_ipv4/dev/net/tunИз каталога репозитория на хосте:
go build -o poc .
sudo ./scripts/setup.sh
sudo ip netns exec pwnesc ./poc
Проба открывает pwntap с IFF_TAP|IFF_NO_PI|IFF_VNET_HDR и захватывает вывод на pwnv1. Зарезервируйте pwntap для пробы. Правило nftables ct активирует defrag через conntrack, а pwnv0 использует MTU 200, чтобы повторно фрагментировать перенаправленный датаграмм на выходе.
Успешная проверка заголовка выводит verify: first byte 0x4f ihl=15. Затем проба сообщает о выходных фрагментах, их IPv4-опциях и байтах, скопированных за пределами линейного заголовка.
-head (по умолчанию 8): полезная нагрузка фрагмента со смещением 0 в байтах; кратна 8 от 8 до 40. Ожидаемая копия за пределами линейного заголовка составляет 40 - head байт.-rest (по умолчанию 400): полезная нагрузка завершающего фрагмента в байтах; не менее 16.-spray (по умолчанию 0): количество кадров того же размера, выделяемых непосредственно перед фрагментом со смещением 0.-spray-fill (по умолчанию 0xee): байт, используемый для заполнения этих кадров.-page: использовать заголовок page_frag, хвост которого может содержать метаданные skb. По умолчанию используется заголовок slab.-skip-verify: сразу перейти к проверке фрагментированной датаграммы.PWN_TAP выбирает TAP-интерфейс (по умолчанию pwntap). PWN_CAP выбирает интерфейс захвата (по умолчанию pwnv1). Скрипт настройки использует эти имена по умолчанию.
После завершения работы пробы выйдите из всех оболочек в pwnesc и выполните на хосте:
sudo ./scripts/teardown.sh
Это удалит pwnesc вместе с его интерфейсами, таблицей nftables ip pwn и локальными для пространства имён настройками sysctl.