VirtualBox Slirp NAT Packet Heap Exploitation
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
TL;DR
- VirtualBox постачається зі сильно модифікованим форком Slirp, буфери пакетів (mbufs) якого розміщуються в кастомному зональному аллокаторі з вбудованими метаданими та callback-ами через вказівники на функції (
pfFini,pfDtor). - Гість може перезаписати довірений
m->m_lenзначенням довжини IP-заголовка, контрольованим атакуючим, що руйнує всі подальші перевірки меж і дає і infoleak, і overwrite-примітиви. - Зловживаючи UDP-пакетами з контрольною сумою
0і завеликоюip_len, гість може exfiltrate хвости mbuf і метадані сусідніх чанків, щоб дізнатися адреси heap і zone. - Надання зіпсованих IP-опцій примушує
ip_stripoptions()виконатиmemcpy()занадто багато даних на місці, тому атакуючий може перезаписати заголовокstruct itemнаступного mbuf і вказати його полеzoneна повністю контрольовані дані. - Звільнення пошкодженого mbuf викликає
zone->pfFini()з аргументами, наданими атакуючим; спрямування його наmemcpy@pltдає довільний примітив копіювання/запису, який можна спрямувати на GOT entries або інші контрольні дані всередині non-PIE бінарника VirtualBox.
Packet allocator anatomy
VirtualBox виділяє кожен вхідний Ethernet-кадр із зони, пов’язаної з інтерфейсом, яка має ім’я zone_clust. Кожен 0x800-байтовий фрагмент даних передує вбудований заголовок:
struct item {
uint32_t magic; // 0xdead0001
void *zone; // uma_zone_t pointer with callbacks
uint32_t ref_count;
LIST_ENTRY(item) list; // freelist / used list links
};
Коли mbuf звільняється, стек викликів m_freem -> ... -> slirp_uma_free() покладається на inline-заголовок:
uma_zfree_arg()перераховуєitem = (struct item *)mem - 1і повинен перевірятиitem->zone, алеAssert()виключено в релізних збірках.slirp_uma_free()завантажуєzone = item->zoneта безумовно виконуєzone->pfFini(zone->pData, data_ptr, zone->size)а потімzone->pfDtor(...).
Отже, будь-який write-what-where у заголовку mbuf перетворюється на керований непрямий виклик під час free().
Infoleak via m->m_len override
На початку ip_input() VirtualBox додав:
if (m->m_len != RT_N2H_U16(ip->ip_len))
m->m_len = RT_N2H_U16(ip->ip_len);
Оскільки присвоєння відбувається до перевірки IP-заголовка, гість може рекламувати будь-яку довжину до 0xffff. Решта стеку (ICMP, UDP, обробники фрагментації тощо) вважає m->m_len довіреним і використовує його для визначення, скільки байтів копіювати з mbuf.
Використовуйте UDP-пакети з контрольною сумою 0 (що означає “без checksum”). NAT fast-path пересилає m->m_len байт без перевірки цілісності payload, тож збільшення ip_len змушує Slirp читати поза реальним буфером і повертати heap residues гостю або співпрацюючому зовнішньому хелперу за NAT. Оскільки розмір чунку — 2048 байт, leak може включати:
- Наступний mbuf’овий inline
struct item, що відкриває порядок freelist і реальний вказівникzone. - Heap cookies, такі як поля
magic, які допомагають сформувати валідні заголовки при пізніших корупціях.
Overwriting neighbouring chunk headers with IP options
Ту ж підроблену довжину можна перетворити на примітив перезапису, змусивши пакет пройти через ip_stripoptions() (запускається коли IP-заголовок має options і payload — UDP/TCP). Хелпер обчислює довжину копіювання з m->m_len, а потім викликає memcpy() щоб зсунути transport header поверх видалених options:
- Подайте довгий
ip_len, щоб обчислена довжина переміщення виходила за межі поточного mbuf. - Включіть невелику кількість IP options, щоб Slirp зайшов у шлях strip.
- Коли виконається
memcpy(), воно читає з наступного mbuf і записує поверх payload поточного mbuf та inline header, пошкоджуючиmagic,zone,ref_countтощо.
Оскільки аллокатор тримає пакети з того ж інтерфейсу суміжними в freelist, цей overflow детерміністично вражає наступний чанк після помірного heap grooming.
Forging uma_zone_t to hijack pfFini
Як тільки суміжний struct item стає коруптним, експлойт рухається так:
- Використайте влиті heap-адреси щоб побудувати підробну структуру
uma_zoneвсередині mbuf повністю контрольованого гостем. Заповніть:
pfFiniз PLT-entry дляmemcpy().pDataвказівником бажаного місця призначення (наприклад GOT entry, vtable slot, function pointer array).sizeкількістю байтів для копіювання.- Опційно:
pfDtorяк виклик другого етапу (наприклад, щоб викликати щойно записаний вказівник функції).
- Перезапишіть поле
zoneцільового mbuf вказівником на підроблену структуру; відрегулюйте вказівникиlistтак, щоб облік freelist лишався достатньо консистентним, щоб уникнути крашів. - Звільніть mbuf.
slirp_uma_free()тепер виконуєmemcpy(dest=pData, src=item_data, n=size), поки mbuf ще містить дані, контрольовані гостем, що дає arbitrary write.
Оскільки Linux VirtualBox-бінарник нерелокований (non-PIE), PLT-адреси для memcpy і system фіксовані і можуть використовуватись напряму. Гість також може розмістити рядки типу /bin/sh всередині іншого mbuf, що залишиться у посиланні коли захоплений виклик виконається.
Heap grooming via fragmentation
Slirp’s per-interface zone має глибину 3072 chunks і спочатку вирізана як суміжний масив, чей freelist обходиться від високих адрес вниз. Детерміновану суміжність можна досягти шляхом:
- Flooding the NAT великою кількістю
IP_MFfragments постійного розміру, щоб код реасемблі створював передбачувані послідовності mbuf. - Рециркуляції конкретних чункiв шляхом відправки фрагментів, які time out, змушуючи frees повертатися у freelist у LIFO-порядку.
- Використовуючи знання прогону freelist, щоб розмістити майбутню жертву mbuf безпосередньо після mbuf, який нестиме IP options overflow.
Цей grooming гарантує, що overflow влучає у цільовий struct item і що підроблена uma_zone лишається в межах leak-примітива.
From arbitrary write to host code execution
З memcpy-on-free примітивом:
- Скопіюйте керований атакуючим рядок
/bin/shта буфер команд у стабільний mbuf. - Використайте примітив щоб перезаписати GOT entry або indirect callsite (наприклад вказівник функції в стані NAT device) PLT-entry від
system(). - Спровокуйте виклик, що було перезаписано. Оскільки VirtualBox запускає NAT device всередині хост-процесу, payload виконається з привілеями користувача, що запускає VirtualBox, дозволяючи guest-to-host escape.
Альтернативні payload’и включають вкорінення мініатюрного ROP-chain у heap-пам’яті та копіювання його адреси у часто викликаний callback, або перенаправлення pfFini/pfDtor прямо на ланцюжок гаджетів для повторних записів.
References
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


