VirtualBox Slirp NAT Packet Heap Exploitation

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Ukratko

  • VirtualBox isporučuje snažno modifikovan fork Slirp-a čiji baferi paketa (mbufs) žive u prilagođenom zone allocator-u sa ugrađenim (inline) meta-podacima i function-pointer callback-ovima (pfFini, pfDtor).
  • Gost može prepisati pouzdani m->m_len pomoću IP header length-a pod kontrolom napadača, što razbija sve kasnije provere granica i daje i infoleak i overwrite primitive.
  • Korišćenjem UDP paketa sa checksum 0 i prevelikim ip_len, gost može izvući mbuf tails i meta-podatke susednih chunk-ova da bi saznao heap i zone adrese.
  • Dostavljanje specijalno pripremljenih IP opcija prisiljava ip_stripoptions() da pozove memcpy() za previše podataka na mestu, pa napadač može prepisati sledeći mbuf-ov struct item header i usmeriti njegovo zone polje na potpuno kontrolisane podatke.
  • Oslobađanje korumpiranog mbuf-a pokreće zone->pfFini() sa argumentima koje obezbeđuje napadač; usmeravanje na memcpy@plt daje arbitrarni copy/write primitiv koji se može usmeriti prema GOT unosima ili drugim kontrolnim podacima unutar non-PIE VirtualBox binarija.

Anatomija alokatora paketa

VirtualBox alocira svaki ulazni Ethernet frame iz po-interfejs zone nazvane zone_clust. Svaki podatkovni chunk od 0x800 bajtova prethodi inline header-u:

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
};

Kada se mbuf oslobodi, stog poziva m_freem -> ... -> slirp_uma_free() veruje inline header-u:

  1. uma_zfree_arg() ponovo izračuna item = (struct item *)mem - 1 i should validira item->zone, ali Assert() je izbačen u release build-ovima.
  2. slirp_uma_free() učitava zone = item->zone i bezuslovno izvršava zone->pfFini(zone->pData, data_ptr, zone->size) praćeno zone->pfDtor(...).

Dakle, bilo koji write-what-where u mbuf header prevodi se u kontrolisani indirektni poziv tokom free().

Infoleak putem m->m_len prepisivanja

Na početku ip_input() VirtualBox je dodao:

if (m->m_len != RT_N2H_U16(ip->ip_len))
m->m_len = RT_N2H_U16(ip->ip_len);

Pošto dodela nastupa pre verifikacije IP zaglavlja, gost može prijaviti bilo koju dužinu do 0xffff. Ostatak stack-a (ICMP, UDP, handleri za fragmentaciju, itd.) pretpostavlja da je m->m_len pouzdan i koristi ga da odluči koliko bajtova da kopira sa mbuf-a.

Koristite UDP pakete sa checksum-om 0 (što znači “no checksum”). NAT fast-path prosleđuje m->m_len bajtova bez inspekcije integriteta payload-a, tako da povećanje ip_len tera Slirp da čita izvan stvarnog buffera i vrati heap residues gostu ili saradničkom eksternom helperu izvan NAT-a. Pošto je veličina chunka 2048 bajtova, leak može uključivati:

  • Inline struct item sledećeg mbuf-a, otkrivajući redosled freelist-a i pravi zone pokazivač.
  • Heap cookies kao što su magic polja, što pomaže u izradi validno-izgledajućih header-a pri kasnijim korupcijama.

Prepisivanje zaglavlja susednih chunk-ova pomoću IP opcija

Ista lažna dužina može da se pretvori u overwrite primitive tako što se paket natera kroz ip_stripoptions() (okida se kada IP zaglavlje ima opcije i payload je UDP/TCP). Helper računa dužinu za kopiranje iz m->m_len i onda poziva memcpy() da pomeri transport header preko uklonjenih opcija:

  1. Pošaljite dugu ip_len tako da izračunata dužina pomeranja ide iza trenutnog mbuf-a.
  2. Uključite mali broj IP opcija da Slirp uđe u stripping path.
  3. Kada se memcpy() izvrši, on čita iz narednog mbuf-a i upisuje preko payload-a i inline header-a trenutnog mbuf-a, korumpirajući magic, zone, ref_count, itd.

Pošto allocator drži pakete sa iste interfejsa kontinuirano na freelist-u, ovaj overflow deterministički pogađa sledeći chunk nakon umerene heap grooming faze.

Falsifikovanje uma_zone_t radi preuzimanja pfFini

Kada je susedni struct item korumpibilan, exploit se nastavlja na sledeći način:

  1. Iskoristite leaked heap adrese da izgradite lažnu uma_zone strukturu unutar mbuf-a koji je potpuno kontrolisan od strane gosta. Popunite:
  • pfFini sa PLT ulazom za memcpy().
  • pData sa željenim destination pointer-om (npr. GOT entry, vtable slot, niz pokazivača na funkcije).
  • size sa brojem bajtova za kopiranje.
  • Opcionalno: pfDtor kao drugi stejdž poziva (npr. da pozove novo-upisani pokazivač funkcije).
  1. Prepišite zone polje ciljnog mbuf-a pokazivačem na lažnu strukturu; prilagodite list pokazivače tako da bookkeeping freelist-a ostane dovoljno konzistentan da se izbegnu padovi.
  2. Free-ujte mbuf. slirp_uma_free() sada izvršava memcpy(dest=pData, src=item_data, n=size) dok mbuf još sadrži podatke kontrolisane od gosta, što rezultuje arbitrary write-om.

Pošto je Linux VirtualBox binar non-PIE, PLT adrese za memcpy i system su fiksne i mogu se koristiti direktno. Gost takođe može smestiti stringove kao što je /bin/sh u drugi mbuf koji ostaje referenciran kada oteti poziv bude izvršen.

Heap grooming putem fragmentacije

Slirp-ova per-interface zona je duboka 3072 chunka i inicijalno je izrezana kao kontinualni niz čija se freelist pretražuje od viših adresa naniže. Deterministička susednost se može postići pomoću:

  • Preplavljivanja NAT-a mnogim IP_MF fragmentima konstantne veličine tako da reassembly kod alocira predvidive mbuf sekvence.
  • Recikliranja specifičnih chunk-ova slanjem fragmenata koji isteknu, prisiljavajući frees da se vrate u freelist u LIFO redu.
  • Korišćenja znanja o freelist walk-u da se pozicionira budući victim mbuf odmah nakon mbuf-a koji će nositi IP options overflow.

Ova grooming faza osigurava da overflow pogodi ciljani struct item i da lažna uma_zone ostane unutar opsega leak primitive.

Od arbitrary write-a do izvršavanja koda na hostu

Sa memcpy-on-free primitive-om:

  1. Kopirajte attacker-kontrolisan /bin/sh string i komandni buffer u stabilan mbuf.
  2. Upotrebite primitiv da prepišete GOT entry ili indirektno mesto poziva (npr. pokazivač na funkciju unutar stanja NAT uređaja) PLT ulazom za system().
  3. Okinač prepisani poziv. Pošto VirtualBox pokreće NAT uređaj unutar host procesa, payload se izvršava sa privilegijama korisnika koji pokreće VirtualBox, omogućavajući guest-to-host escape.

Alternativni payload-i uključuju postavljanje mini ROP chain-a u heap memoriju i kopiranje njegove adrese u često pozivan callback, ili preusmeravanje pfFini/pfDtor samih na chained gadgets za ponovljene upise.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks