VirtualBox Slirp NAT Packet Heap Exploitation

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

TL;DR

  • VirtualBox stapel ’n sterk aangepaste fork van Slirp waarvan die packet buffers (mbufs) in ’n custom zone allocator met inline metadata en function-pointer callbacks (pfFini, pfDtor) woon.
  • ’n gast kan die vertroude m->m_len herskryf met ’n aanvallers-beheerde IP header length, wat alle latere bounds checks vernietig en beide infoleak en overwrite primitives oplewer.
  • Deur UDP packets met checksum 0 en oversized ip_len te misbruik, kan die gast mbuf tails en die metadata van naburige chunks exfiltrateer om heap- en zone-adresse te leer.
  • Deur gesmede IP options te voorsien dwing dit ip_stripoptions() om te veel data in-place met memcpy() te kopieer, sodat die aanvaller die volgende mbuf se struct item header kan overwrite en sy zone veld na volledig beheerbare data kan wys.
  • Die vrylating van die gekorrumpeerde mbuf trigger zone->pfFini() met aanvaller-geleverde argumente; dit na memcpy@plt wys gee ’n arbitrary copy/write primitive wat na GOT entries of ander kontrole-data binne die non-PIE VirtualBox binary gestuur kan word.

Packet allocator anatomy

VirtualBox ken elke inkomende Ethernet frame toe uit ’n per-interface zone genaamd zone_clust. Elke 0x800-byte data chunk word voorafgegaan deur ’n inline header:

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

Wanneer ’n mbuf vrygestel word, vertrou die oproepstapel m_freem -> ... -> slirp_uma_free() die inlyn-header:

  1. uma_zfree_arg() bereken weer item = (struct item *)mem - 1 en moet item->zone valideer, maar Assert() is in release builds uitgekompileer.
  2. slirp_uma_free() laai zone = item->zone en voer onvoorwaardelik zone->pfFini(zone->pData, data_ptr, zone->size) uit, gevolg deur zone->pfDtor(...).

Gevolglik vertaal enige write-what-where in die mbuf-header na ’n beheerde indirekte oproep tydens free().

Infoleak via m->m_len override

Aan die begin van ip_input() het VirtualBox die volgende bygevoeg:

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

Omdat die toewysing gebeur voor die verifikasie van die IP-header, kan die guest enige lengte tot 0xffff adverteer. Die res van die stack (ICMP, UDP, fragmentation handlers, ens.) neem aan dat m->m_len vertroubaar is en gebruik dit om te besluit hoeveel bytes van die mbuf uitgekopieer moet word.

Gebruik UDP-pakkette met checksum 0 (betekenis “no checksum”). Die NAT fast-path stuur m->m_len bytes deur sonder om die payload-integriteit te inspekteer, so deur ip_len op te blaas laat Slirp dit lees voor die werklike buffer en teruggee heap residues aan die guest of aan ’n samewerkende eksterne helper buite die NAT. Omdat die chunk-grootte 2048 bytes is, kan die leak insluit:

  • Die volgende mbuf se inline struct item, wat die freelist-volgorde en die werklike zone-pointer openbaar.
  • Heap-cookies soos magic-velde, wat help om geldig-lykende headers te bou wanneer later korrupsies uitgevoer word.

Oorskryf naburige chunk-headers met IP-opties

Dieselfde vals lengte kan in ’n overwrite-primitive omskep word deur die pakket deur ip_stripoptions() te dwing (geaktiveer wanneer die IP-header opsies het en die payload UDP/TCP is). Die helper bereken ’n kopieerlengte vanaf m->m_len en roep dan memcpy() aan om die transport-header oor die gestripte opsies te skuif:

  1. Verskaf ’n lang ip_len sodat die berekende verhuislengte verder strek as die huidige mbuf.
  2. Sluit ’n klein aantal IP-opties in sodat Slirp die strip-pad betree.
  3. Wanneer memcpy() loop, lees dit vanaf die volgende mbuf en skryf oor die huidige mbuf se payload en inline header, wat magic, zone, ref_count, ens. korrupteer.

Omdat die allocator pakkette van dieselfde interface aaneenlopend op die freelist hou, tref hierdie overflow deterministies die volgende chunk na matige heap grooming.

Forging uma_zone_t to hijack pfFini

Sodra die aangrensende struct item korrupteerbaar is, gaan die exploit voort soos volg:

  1. Gebruik leaked heap-adresse om ’n vals uma_zone-struktuur te bou binne ’n mbuf wat volledig deur die guest beheer word. Vul dit met:
    • pfFini met die PLT-inskrywing van memcpy().
    • pData met die gewenste bestemming-pointer (bv. GOT-entry, vtable-slot, funksie-pointer-array).
    • size met die aantal bytes om te kopieer.
    • Opsioneel: pfDtor as ’n tweede-fase oproep (bv. om die pas-geskrewe funksie-pointer aan te roep).
  2. Oorskryf die teiken-mbuf se zone-veld met die pointer na die vals struktuur; pas list-pointers aan sodat die freelist-boekhouding voldoende konsekwent bly om crashes te vermy.
  3. Vry die mbuf. slirp_uma_free() voer nou memcpy(dest=pData, src=item_data, n=size) uit terwyl die mbuf nog guest-gestuurde data bevat, wat ’n arbitrary write lewer.

Omdat die Linux VirtualBox-binary non-PIE is, is PLT-adresse vir memcpy en system vas en kan direk gebruik word. Die guest kan ook strings soos /bin/sh in ’n ander mbuf wegsteek wat steeds gerefereer word wanneer die gekaapte oproep uitgevoer word.

Heap-grooming deur fragmentasie

Slirp se per-interface zone is 3072 chunks diep en aanvanklik gekerf as ’n aaneenlopende array waarvan die freelist van hoë adresse af deurloop. Deterministiese naburigheid kan bereik word deur:

  • Oorlaai die NAT met baie IP_MF fragmente van konstante grootte sodat die reassembly-code voorspelbare mbuf-reekse alokeer.
  • Herwin spesifieke chunks deur fragmente te stuur wat uittyd, wat vrystellings in LIFO-volgorde terug op die freelist dwing.
  • Gebruik kennis van die freelist-loop om die toekomstige slagoffer-mbuf reg ná die mbuf te plaas wat die IP-opties overflow sal dra.

Hierdie grooming verseker dat die overflow die geteikende struct item tref en dat die vals uma_zone binne die grense van die leak-primitive bly.

Van arbitrary write na host-kode-uitvoering

Met die memcpy-on-free-primitive:

  1. Kopieer ’n attacker-controlled /bin/sh string en command buffer in ’n stabiele mbuf.
  2. Gebruik die primitive om ’n GOT-entry of indirekte callsite (bv. ’n funksie-pointer binne die NAT-toestel-state) te oorskryf met die PLT-inskrywing van system().
  3. Trigger die oorskryfde oproep. Omdat VirtualBox die NAT-toestel binne die host-proses uitvoer, word die payload met die voorregte van die gebruiker wat VirtualBox loop uitgevoer, wat ’n guest-to-host escape moontlik maak.

Alternatiewe payloads sluit in die plant van ’n miniatuur ROP-ketting in heap-geheue en die kopieer van sy adres na ’n gereeld-aangeroepde callback, of om pfFini/pfDtor self na geketende gadgets te herlei vir herhaalde skrywe.

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks