VirtualBox Slirp NAT — Eksploatacja sterty pakietów
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
TL;DR
- VirtualBox dostarcza mocno zmodyfikowany fork Slirp, którego packet buffers (mbufs) znajdują się w niestandardowym alokatorze stref z wbudowanymi metadanymi i callbackami wskaźnikowymi (
pfFini,pfDtor). - Gość może nadpisać zaufane
m->m_lenza pomocą długości nagłówka IP kontrolowanej przez atakującego, co niszczy wszystkie późniejsze sprawdzenia zakresów i daje zarówno infoleak, jak i overwrite primitives. - Poprzez wykorzystanie pakietów UDP z checksumą
0i zawyżonymip_len, gość może exfiltrate mbuf tails oraz metadane sąsiednich chunków, aby poznać adresy heap i zone. - Dostarczenie spreparowanych opcji IP zmusza
ip_stripoptions()domemcpy()zbyt dużej ilości danych in-place, dzięki czemu atakujący może nadpisać nagłówekstruct itemnastępnego mbufu i ustawić jego polezonena w pełni kontrolowane dane. - Zwolnienie uszkodzonego mbufu wywołuje
zone->pfFini()z argumentami dostarczonymi przez atakującego; skierowanie go namemcpy@pltdaje arbitralny copy/write primitive, który można skierować w stronę wpisów GOT lub innych danych kontrolnych wewnątrz nie-PIE binarki VirtualBox.
Packet allocator anatomy
VirtualBox alokuje każdą przychodzącą ramkę Ethernet ze strefy przypisanej do interfejsu o nazwie zone_clust. Każdy 0x800-bajtowy chunk danych poprzedzony jest wbudowanym nagłówkiem:
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
};
When an mbuf is freed the call stack m_freem -> ... -> slirp_uma_free() trusts the inline header:
uma_zfree_arg()recomputesitem = (struct item *)mem - 1and should validateitem->zone, butAssert()is compiled out in release builds.slirp_uma_free()loadszone = item->zoneand unconditionally executeszone->pfFini(zone->pData, data_ptr, zone->size)followed byzone->pfDtor(...).
Therefore, any write-what-where into the mbuf header translates into a controlled indirect call during free().
Infoleak via m->m_len override
At the top of ip_input() VirtualBox added:
if (m->m_len != RT_N2H_U16(ip->ip_len))
m->m_len = RT_N2H_U16(ip->ip_len);
Ponieważ przypisanie odbywa się przed weryfikacją IP header, guest może zadeklarować dowolną długość do 0xffff. Reszta stosu (ICMP, UDP, fragmentation handlers, itd.) zakłada, że m->m_len jest godny zaufania i używa go do decyzji, ile bajtów skopiować z mbuf.
Użyj UDP packets z checksumą 0 (oznaczającą “no checksum”). NAT fast-path przesyła dalej m->m_len bajtów bez sprawdzania integralności payloadu, więc nadmierne ustawienie ip_len powoduje, że Slirp czyta poza rzeczywisty bufor i zwraca heap residues do guest lub współpracującego zewnętrznego helpera poza NAT. Ponieważ rozmiar chunku to 2048 bajtów, leak może zawierać:
- Inline
struct itemnastępnego mbuf, ujawniając kolejność freelist i rzeczywisty wskaźnikzone. - Heap cookies takie jak pola
magic, ułatwiające stworzenie pozornie poprawnych nagłówków przy późniejszych corruptions.
Nadpisywanie sąsiednich nagłówków chunk przy pomocy IP options
Ta sama fałszywa długość może zostać zamieniona w overwrite primitive przez wymuszenie przejścia pakietu przez ip_stripoptions() (wywoływane gdy IP header ma options, a payload to UDP/TCP). Helper oblicza długość kopiowania z m->m_len, a następnie wywołuje memcpy() aby przesunąć transport header ponad stripped options:
- Dostarcz długie
ip_len, tak aby obliczona długość przesunięcia sięgała poza bieżący mbuf. - Dodaj niewielką liczbę IP options, żeby Slirp wszedł w ścieżkę stripowania.
- Gdy
memcpy()się wykona, odczyta z następnego mbuf i zapisze ponad payload i inline header bieżącego mbuf, korumpującmagic,zone,ref_countitd.
Ponieważ allocator trzyma pakiety z tego samego interface skontiguowane na freelist, ten overflow trafia deterministycznie w następny chunk po umiarkowanym heap grooming.
Forging uma_zone_t to hijack pfFini
Gdy sąsiedni struct item staje się podatny na corruption, exploit postępuje następująco:
- Użyj wyciekniętych adresów heap aby zbudować fałszywą strukturę
uma_zonewewnątrz mbuf w pełni kontrolowanego przez guest. Wypełnij:
pfFiniwpisem PLTmemcpy().pDatadocelowym wskaźnikiem (np. GOT entry, vtable slot, tablica wskaźników funkcji).sizeliczbą bajtów do skopiowania.- Opcjonalnie:
pfDtorjako wywołanie drugiego etapu (np. aby wywołać nowo zapisany wskaźnik funkcji).
- Nadpisz pole
zonedocelowego mbuf wskaźnikiem na fałszywą strukturę; dostosuj wskaźnikilist, tak aby księgowość freelist pozostała wystarczająco spójna, by uniknąć crashy. - Free’uj mbuf.
slirp_uma_free()teraz wykonamemcpy(dest=pData, src=item_data, n=size)podczas gdy mbuf nadal zawiera dane kontrolowane przez guest, dając arbitrary write.
Ponieważ linuxowy VirtualBox binarny jest non-PIE, adresy PLT dla memcpy i system są stałe i można ich użyć bezpośrednio. Guest może też przechować stringi takie jak /bin/sh w innym mbuf, który pozostanie referencjonowany gdy hijacked call się wykona.
Heap grooming przez fragmentation
Strefa per-interface Slirp ma głębokość 3072 chunk i początkowo jest podzielona jako kontiguja tablica, której freelist jest przeglądany od wysokich adresów w dół. Deterministyczną sąsiedność można osiągnąć przez:
- Zatkanie NAT wieloma
IP_MFfragments o stałym rozmiarze, tak by reassembly code alokował przewidywalne sekwencje mbuf. - Recykling konkretnych chunków przez wysyłanie fragmentów, które wygasają, wymuszając frees z powrotem na freelist w porządku LIFO.
- Wykorzystanie wiedzy o freelist walk, by umieścić przyszły victim mbuf tuż za mbuf, który będzie niósł IP options overflow.
To grooming zapewnia, że overflow trafia w targetowany struct item i że fałszywy uma_zone pozostaje w granicach leak primitive.
From arbitrary write to host code execution
Z memcpy-on-free primitive:
- Skomponuj kontrolowany przez atakującego string
/bin/shi bufor poleceń w stabilnym mbuf. - Użyj primitive aby nadpisać GOT entry lub indirect callsite (np. wskaźnik funkcji w stanie urządzenia NAT) wpisem PLT
system(). - Wyzwól nadpisane wywołanie. Ponieważ VirtualBox uruchamia NAT device wewnątrz procesu hosta, payload wykona się z przywilejami użytkownika uruchamiającego VirtualBox, umożliwiając guest-to-host escape.
Alternatywne payloady obejmują zainstalowanie miniaturowego ROP chain w pamięci heap i skopiowanie jego adresu do często wywoływanego callbacka, lub przestawienie pfFini/pfDtor bezpośrednio na chained gadgets dla powtarzalnych write’ów.
References
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


