Skip to content

VirtualBox VBVA/HGSMI double-fetch escape

Bir VirtualBox guest-to-host escape'i (CVE-2018-2844, ilgili CVE-2018-2698); VBVA/HGSMI yolunda bir command type alanının compiler tarafından eklenen bir double-fetch'i, bir guest'in bir bounds check'i bir jump-table dispatch'inden desync etmesine ve host VM process'inde kod çalıştırmasına izin verir.

Mechanism

Note

VirtualBox'ın Video Acceleration'ı (VBVA), Host-Guest Shared Memory Interface olan HGSMI'nin üzerinde çalışır; VGA device'inin VRAM'inde (physical base 0xE0000000, ~16 MB) implemente edilir ve hem guest kernel'ine hem de host VM process'ine map'lenir. Guest, command buffer'larını VRAM'e yazar ve HGSMI guest I/O port'u (0x3d0) üzerinden host'u bilgilendirir. Isolation invariant'ı, host'un bir komutun type/size'ını bir kez validate edip sonra o aynı validate edilmiş değer üzerinde işlem yapmasıdır. Bug bir double-fetch'tir: vboxVDMACmdExec() içinde komutun pCmd->enmType'ı shared VRAM'de yaşar ve volatile olarak işaretli değildir, yani compiler onu yeniden yükler — bir kez bounds compare için, bir kez de bir jump table'ı index'lemek için. İkinci bir guest vCPU bu boşlukta enmType'ı çevirebilir, böylece kontrolü geçen bir değer jump table'ı range dışında index'ler ve attacker-etkili dispatch'e ulaşır. VRAM, host process'inde RWX map'lendiği için guest oraya shellcode yerleştirip ona ulaşmak için relative jump-table adresleme kullanabilir — guest→host sınırını aşan bir host-context execute (CVE-2018-2844 için Linux host'ları; CVE-2018-2698 tüm host'ları VRAM-relative keyfi bir R/W olarak etkiler).

Walkthrough

Public referans: voidsecurity "From Compiler Optimization to Code Execution" (CVE-2018-2844). Kavramsal, zaten-patch'lenmiş yol:

  1. VRAM'de bir HGSMI command buffer kur (HGSMIBUFFERHEADER + payload + HGSMIBUFFERTAIL); buffer offset'ini port 0x3d0'a yazarak host'u tetikle.
  2. Multi-vCPU bir guest'te, bir vCPU enmTypevboxVDMACmdExec() içindeki host bounds check'inden geçen bir VBVA/VDMA komutu gönderir.
  3. İkinci bir vCPU, host onu jump-table index'i için yeniden fetch etmeden önce shared VRAM'deki enmType'ı eşzamanlı olarak yeniden yazar — double-fetch race condition'ı.
  4. Range dışı index, attacker-etkili kontrole dispatch eder; VRAM RWX map'lendiğinden PoC, VRAM'i NOP'larla doldurur ve relative adresleme VRAM'e insin diye shellcode'u yüksek page'lere yerleştirir, bir info leak olmadan ASLR'ı atlatır.
  5. Sonuç: host-process code execution (CVE-2018-2698 ise userland host process'inde VRAM-relative keyfi bir read/write primitive'i verir).

Warning

Bug sınıfı için dokümante edilmiş, public ve patch'lenmiş bir sorun. Bu kayıt exploit geometrisini ve host offset'lerini atlar; bu kavramsal race condition'ıdır.

Double-fetch neden var (örnekleyici)
/* pCmd points into shared, guest-writable VRAM, NOT volatile */
if (pCmd->enmType >= LIMIT) return;     /* fetch #1: bounds check */
dispatch[pCmd->enmType](pCmd);          /* fetch #2: re-read, can differ */

Detection

  • Host tarafı: HGSMI port 0x3d0 bildirim patlamaları ve birden çok vCPU'dan eşzamanlı VRAM yazmalarıyla korele VM-process crash'leri.
  • Davranışsal: VBVA command-type alanlarının gönderim ile işleme arasında hızlı yerinde mutasyonu, normal bir video driver için anormaldir.

Mitigation

  • CVE-2018-2844 / CVE-2018-2698 için Oracle'ın VirtualBox fix'ini uygula (validate/dispatch etmeden önce komutu shared memory dışına kopyala, ya da fetch'i volatile işaretle ve local kopyayı validate et).
  • Gerekmeyen yerlerde VBVA/3D acceleration'ı devre dışı bırakarak shared-memory display attack surface'ini küçült; shared device buffer'larını RWX map'leme.
  • Defense-in-depth: VM process'ini sandbox'la/deprivilege et.

References

  • voidsecurity, "From Compiler Optimization to Code Execution - VirtualBox VM Escape - CVE-2018-2844": https://www.voidsecurity.in/2018/08/from-compiler-optimization-to-code.html
  • Exploit-DB 45372 — VirtualBox 5.2.6 VM Escape: https://www.exploit-db.com/exploits/45372