VMware Workstation PVSCSI LFH Escape (VMware-vmx on Windows 11)

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

Fout-anatomie: fixed-size realloc + scattered OOB writes

  • PVSCSI_FillSGI kopieer gast scatter/gather entries in ’n interne array. Dit begin met ’n 512-entry statiese buffer (0x2000). Bo 512 entries herallokeer dit na 0x4000 bytes en, as gevolg van ’n funksionele fout, herallokeer dit by elke iterasie.
  • Die herallokasie-grootte groei nooit: 0x4000 / 0x10-byte entries = 1024 bruikbare entries. Wanneer die gasheer >1024 entries verskaf, word elke nuwe entry 16 bytes verby die pas herallokeerde 0x4000-stuk geskryf, wat die aangrensende chunk-header of objek korrupteer.
  • Overflow-inhoud: VMware stoor {u64 addr; u64 len}; die gasheer verskaf {u64 addr; u32 len; u32 flags}. Die 32-bit len is zero-extended, so die laaste dword van elke 16-byte OOB element is altyd 0x00000000.

LFH-beperkings & deterministiese “Ping-Pong” plasing

  • 0x4000 allocations beland in die Windows 11 LFH (16 chunks/bucket, 0x10-byte metadata met keyed checksum). Enige chunk wie se header checksum later getref word, sal die proses beëindig, dus gekorrupte headers mag nooit hergebruik word nie.
  • LFH gee ’n ewekansige vrye chunk terug, maar voorkeur gee aan die bucket wat die mees onlangs vrygemaakte chunk bevat. Dwing net twee vrye slote af:
  1. Allokeer al die vrye 0x4000 chunks om die allocator te belyn; spray 32 SVGA shaders om B1 en B2 buckets te vul.
  2. Vry B1 behalwe een vasgepinde shader (Hole0) sodat B1 aktief bly; allokeer 15 URBs in B1.
  3. Vry een shader in B2 (PONG), en vry daarna onmiddellik Hole0. LFH sal allocations afwisselend tussen die twee beskikbare slote toeken: PING (B1) en PONG (B2).
  • Iterasie 1025 korrupteer die header na PONG (nooit weer aangeraak); iterasie 1026 tref die eerste 16 bytes van die URB na PING (veilige metadata-bypassing). Herwin PING/PONG met plekhouer-shaders om die uitleg stabiel en herhaalbaar te hou.

Reap Oracle: etikettering van aaneenlopende gate

  • UHCI URBs leef in ’n FIFO-ry en word vrygestel wanneer volledig reaped. Die beperkte 16-byte overskrywing nul maak altyd actual_len, wat ’n merk gee.
  • Reap URBs in volgorde; wanneer ’n genulde actual_len gesien word, vul onmiddellik die vrygemaakte slot met ’n herkenbare shader. Iterasie laat jou toe om Hole0–Hole3 as vier aaneenlopende chunks in bekende volgorde te karteer vir later adjacency-afhanklike primitives.

Maak beperkende skrywes in arbitrary overwrite (coalescing abuse)

PVSCSI coalesce aangrensende entries deur AddrA + LenA == AddrB en compact later entries opwaarts.

  • Twee-pas overflow: Trigger begin by PING (onewe indeks) en verlaat vroeg om coalescing te oorslaan; trigger weer begin by PONG (even indeks) om die gapings te vul en voort te gaan skryf in ’n gesprayde shader wat valse S/G entries bevat.
  • Vacuum + payload: Stel entries [1023..2047] op {addr=0,len=0} sodat coalescing hulle ineenstort tot een, wat ’n logiese gaping skep. Payload entries geplaas daarna (in die shader) word opwaarts verskuif in vroeër geheue, en land binne die slagoffer URB.
  • Adjacency-check bypass: Deur LenA=0 te stel, word die voorwaarde AddrA==AddrB. Skep pare
{addr = X, len = 0}
{addr = X, len = Y}

sodat coalescing hulle ineenvoeg tot {addr=X,len=Y}. Even-geïnspireerde zero-size elemente kom van die beperkte overflow; onewe-geïnspireerde waardes leef in die shader. Resultaat: arbitrary 16-byte patterns ondanks die geforseerde nul dword.

Hybride URB infoleak deur coalescing newe-effekte

  • Rangskik aaneenlopende chunks: [Hole0 (free/PING), URB1 (target), URB2 (valid, actual_len=0), URB3 (leak target)].
  • Vul URB1 met aaneenlopende valse entries (groottes 0xFFFFFFFF), raak URB2 net minimaal aan. Coalescing voeg hulle ineen tot een entry; die som 0xFFFFFFFF * 0x401 stel die boonste dword by URB1 se actual_len offset op 0x400.
  • Kompaksie kopieer die volgende data opwaarts, wat URB2 se header in URB1 trek. URB1 het nou ’n geldige header (pipe/list pointers), actual_len=0x400, en ’n datapointer reeds aan die einde van URB2 se buffer.
  • Reaping van URB1 kopieer 0x400 bytes wat net voor URB3 begin, wat ’n OOB read van URB3 se header/self-references gee, wat absolute heap-adresse openbaar en ASLR vir volgende vervalste strukture breek.

Post-leak primitives (sonder om die fout weer te aktiveer)

  • Forge ’n URB-struktuur binne ’n shader wat Hole0 beset, en gebruik dan die coalescing “move up” om URB1 met die vervalste data te vervang.
  • Maak die URB persistent: stel URB1.next = Hole0 en verhoog refcount; reaping van URB1 sit die Hole0-ondersteunde vervalste URB aan die FIFO-kop. Toekomstige primitives is net herallokasies van Hole0 met nuwe vervalste URBs.
  • Arbitrary read: vervalste URB met gekose data_ptr en actual_len, dan reap om host-geheue na die gasheer te kopieer.
  • Arbitrary write (32-bit): vervalste URB wie se pipe na beheerbare geheue wys en misbruik die UHCI TDBuffer writeback om ’n gekose dword by ’n arbitraire adres te stoor.
  • Arbitrary call: oor skryf ’n USB pipe callback; die host roep dit aan met beheerdata by RCX+0x90. Los WinExec dinamies op (gasheer-side lees van Kernel32) en pivot deur ’n CFG-valid gadget inside vmware-vmx wat argumente from RCX+0x100 laai voordat dit na WinExec("calc.exe") stuur.

LFH timing side-channel om die aanvanklike bucket offset te bepaal

  • Deterministiese Ping-Pong vereis kennis van die LFH vry-chunk offset (watter van 16 slote eerste getref sal word). Gebruik die VMware backdoor instruksie (inl %%dx, %%eax) met die sinchroniese VMware Tools command vmx.capability.unified_loop en ’n 0x4000-byte string, wat twee 0x4000 allocations per oproep dwing.
  • Meet 8 oproepe (16 allocations) met gettimeofday; een oproep toon ’n konsekwente piek wanneer die LFH ’n nuwe bucket skep. Herhaal met een ekstra allokasie: as die piek op dieselfde indeks bly is die offset onewe, as dit skuif is dit ewe; anders herbegin weens geraas.
  • Waarskuwing: unified_loop stoor unieke strings in ’n onverwyderlike lys, wat O(n) lookup overhead veroorsaak en geraas verhoog, so die side-channel moet vinnig konvergeer.

References

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