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

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Bug anatomy: fixed-size realloc + scattered OOB writes

  • PVSCSI_FillSGI inakopi entry za guest scatter/gather ndani ya array ya ndani. Inaanza na static buffer ya entries 512 (0x2000). Zaidi ya entries 512 inafanya realloc hadi 0x4000 bytes na, kwa sababu ya bug ya kifunction, inareallocate kila mzunguko.
  • Ukubwa wa reallocation hauongezeki: 0x4000 / vichwa vya 0x10-byte = 1024 entries zinazoweza kutumika. Wakati guest inatoa >1024 entries, kila entry mpya inaandikwa 16 bytes zaidi ya chunk iliyochangiwa hapo juu ya 0x4000, ikiharibu header ya chunk au object inayofuatia.
  • Yaliyomo kwenye overflow: VMware inahifadhi {u64 addr; u64 len}; guest hutoa {u64 addr; u32 len; u32 flags}. len ya 32-bit inafanywa zero-extended, hivyo dword ya mwisho ya kila elementi OOB ya 16-byte huwa daima 0x00000000.

LFH constraints & deterministic “Ping-Pong” placement

  • 0x4000 allocations zinaenda kwenye Windows 11 LFH (16 chunks/bucket, metadata ya 0x10-byte na keyed checksum). Kila chunk ambayo checksum ya header yake itagongwa baadaye itasababisha process kusimamishwa, hivyo headers zilizoharibiwa lazima zisitumike tena.
  • LFH hurudisha chunk huru kwa bahati nasibu, lakini inapendelea bucket yenye chunk iliyotolewa hivi karibuni. Lenga kuifanya iwe na nafasi mbili za bure tu:
    1. Allocate zote chunk huru za 0x4000 ili kusawazisha allocator; spray 32 SVGA shaders kujaza buckets B1 na B2.
    2. Free B1 isipokuwa shader moja iliyosimamiwa (Hole0) ili B1 iendelee kuwa active; allocate 15 URBs ndani ya B1.
    3. Free shader moja katika B2 (PONG), kisha mara moja free Hole0. LFH itabadilika kati ya allocations mbili zinazopatikana PING (B1) na PONG (B2).
  • Iteration 1025 inaharibu header baada ya PONG (haigusiwi tena); iteration 1026 inagonga 16 bytes za kwanza za URB baada ya PING (kupita metadata salama). Reclaim PING/PONG kwa shaders za placeholder ili kuweka layout thabiti na kurudiwa.

Reap Oracle: labeling contiguous holes

  • UHCI URBs zinaishi katika FIFO queue na hufunguliwa (freed) wakati zinakamilika kuwekewa reaped. Overwrite iliyo na ukomo wa 16-byte kila mara inafanya actual_len kuwa sifuri, ikitoa alama.
  • Reap URBs kwa mpangilio; ukiona actual_len iliyofanywa sifuri, toa mara moja slot iliyotolewa na ujaze na shader inayotambulika. Kurudia hufanya uweze kupiga ramani Hole0–Hole3 kama chunks nne zinazozamana kwa mpangilio unaojulikana kwa matumizi ya baadaye yanayohitaji uwingizaji.

Turning constrained writes into arbitrary overwrite (coalescing abuse)

PVSCSI inachanganya entries zilizoungana kwa kutumia AddrA + LenA == AddrB na huchomekwa entries za baadaye juu.

  • Two-pass overflow: Anzisha kuanza kwenye PING (index zisizo za mbili) na toka mapema ili kuruka coalescing; anzisha tena kuanzia PONG (index za mbili) ili kujaza mapengo na kuendelea kuandika ndani ya shader iliyopakwa spray yenye fake S/G entries.
  • Vacuum + payload: Weka entries [1023..2047] kuwa {addr=0,len=0} ili coalescing izidonge hizo kuwa moja, ikitengeneza hole ya mantiki. Entries za payload zilizowekwa baadaye (katika shader) zitahamishwa juu ndani ya kumbukumbu ya awali, zikifika ndani ya URB la mwathiriwa.
  • Adjacency-check bypass: Kwa kuweka LenA=0, sharti linageuka kuwa AddrA==AddrB. Finyia paaru
{addr = X, len = 0}
{addr = X, len = Y}

hivyo coalescing inaunga hilo kuwa {addr=X,len=Y}. Elementi za ukubwa sifuri za index zenye nambari mbili zinatokana na overflow iliyo na ukomo; elementi za index zisizo za mbili ziko katika shader. Matokeo: miundo ya 16-byte yoyote licha ya dword iliyolazimishwa kuwa sifuri.

Hybrid URB infoleak via coalescing side-effects

  • Panga chunks zinazozamana: [Hole0 (free/PING), URB1 (target), URB2 (valid, actual_len=0), URB3 (leak target)].
  • Jaza URB1 na fake entries zilizo karibu (sizes 0xFFFFFFFF), ukigusa URB2 kidogo. Coalescing inawaunganisha kuwa entry moja; jumla 0xFFFFFFFF * 0x401 inaweka dword ya juu katika offset ya actual_len ya URB1 kuwa 0x400.
  • Compaction inakopa data ifuatayo juu, ikivuta header ya URB2 ndani ya URB1. URB1 sasa ina header halali (pipe/list pointers), actual_len=0x400, na pointer ya data tayari iko mwishoni mwa buffer ya URB2.
  • Reaping URB1 inakopi bytes 0x400 kuanzia kabla kidogo ya URB3, ikitoa OOB read ya header/references za URB3, ambayo inaonyesha anwani za heap kamili na kuvunja ASLR kwa structures zilizoigizwa baadaye.

Post-leak primitives (no re-triggering the bug)

  • Unda URB ya bandia ndani ya shader inayochukua Hole0, kisha tumia coalescing “move up” kubadilisha URB1 na data ya bandia.
  • Fanya URB isiyoxoshwa: weka URB1.next = Hole0 na ongeza refcount; reaping URB1 hueka URB ya bandia iliyo backed na Hole0 kuwa kichwa cha FIFO. Primitives za baadaye ni tu reallocations za Hole0 na fake URBs mpya.
  • Arbitrary read: URB ya bandia yenye data_ptr na actual_len uliochagua, kisha reap kusoma memory ya host kwa guest.
  • Arbitrary write (32-bit): URB ya bandia ambayo pipe inaonyesha kwenye memory ndogo udhibiti na utilize UHCI TDBuffer writeback kuhifadhi dword uliopangwa kwa anwani yoyote.
  • Arbitrary call: fanya overwrite ya USB pipe callback; host itaitisha hiyo callback na data iliyodhibitiwa katika RCX+0x90. Pata WinExec dinamically (kusoma Kernel32 upande wa guest) na piga pivot kupitia gadget inayokubalika na CFG ndani ya vmware-vmx inayopakia arg kutoka RCX+0x100 kabla ya kupitisha kwa WinExec("calc.exe").

LFH timing side-channel to learn the initial bucket offset

  • Ping-Pong inayotabirika inahitaji kujua offset ya free-chunk ya LFH (ni slot ngapi kati ya 16 zitapigwa kwanza). Tumia maagizo ya VMware backdoor (inl %%dx, %%eax) na amri ya synchronous ya VMware Tools vmx.capability.unified_loop na string ya 0x4000-byte, ambayo inalazimisha allocations mbili za 0x4000 kwa kila mwito.
  • Pima muda wa miito 8 (allocations 16) kwa kutumia gettimeofday; mwito mmoja unaonyesha spike thabiti pale LFH inapounda bucket mpya. Rudia na allocation moja zaidi: kama spike inabaki kwenye index ile ile offset ni odd, kama inabadilika ni even; vinginevyo restart kutokana na kelele.
  • Tahadhari: unified_loop hifadhi strings za kipekee kwenye orodha isiyoweza kufutwa, ikisababisha O(n) lookup overhead na kuongezeka kwa kelele, hivyo side-channel lazima itoke kwa haraka.

References

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks