Skip to content

VMware ESXi ACPI TOCTOU OOB read info leak (CVE-2020-3981)

VMware'in ACPI device emulation'ındaki bir time-of-check/time-of-use double-fetch, guest'in read'ler arasında bir table length'i büyütmesine izin vererek vmx-process belleğini sızdıran bir out-of-bounds read sürükler.

Mechanism

Bug class: guest kontrolündeki ACPI table length üzerinde double-fetch TOCTOU

VMware guest'e ACPI table'ları sunar ve bu table verisinin bir kısmı guest-accessible memory içinde durur. Host (vmx) bir table'ı işlerken — örneğin bir checksum'ı yeniden hesaplarken — kaç byte gezeceğini bilmek için table'ın length field'ını okur. Açık şudur ki host length'i birden fazla kez okur ve değeri immutable olarak ele almaz: bir read ile bir mapping/size doğrular, sonra iterate ederken length'i guest memory'den yeniden okur.

Guest bu field'ı iki read arasında yazabildiği için bu bir double-fetch TOCTOU'dur. Guest küçük bir length ile doğrulamayı geçer, sonra onu büyütür, böylece checksum loop'u doğrulanmış region'ın sonunu aşıp komşu host heap memory'ye girer — bir out-of-bounds read. Yeniden hesaplanan checksum'ın nasıl değiştiğini gözlemleyerek guest out-of-range byte'ları çıkarsar ve hypervisor heap içeriğini sızdırır.

İhlal edilen invariant tüm double-fetch bug'larındaki ile aynıdır: bir memory walk'u sınırlamak için kullanılan bir size bir kez snapshot'lanmalı ve hem doğrulama hem iterasyon için aynı snapshot kullanılmalıdır. Mutable guest memory'yi yeniden okumak, kontrol edilen bound ile kullanılan bound arasındaki ilişkiyi bozar. Etki yalnızca information disclosure'dır (write yok), ama ASLR'ı yenmeye ve daha büyük bir escape chain'i tohumlamaya yeter.

Walkthrough

Public ZDI write-up'ından ve VMSA-2020-0023'ten high-level reconstruction. Offset ya da exploit code yok.

  1. Guest, kontrol edilebilir bir length field'ı dahil ACPI table verisini, vmx process'in parse edeceği guest memory'ye yerleştirir.
  2. Host table region/mapping'ini length'in ilk read'iyle doğrular (time-of-check).
  3. Guest bu kontrolden sonra length'i büyütür (başka bir guest context'inden yarışan bir write).
  4. Host'un checksum routine'i length'i yeniden okur (time-of-use) ve artık daha büyük olan aralık üzerinde iterate ederek table'ın ötesindeki host heap byte'larını okur.
  5. Guest ortaya çıkan checksum değerlerini ayırt ederek out-of-bounds byte'ları elde eder ve host belleğini byte-byte gezmek için bunu tekrarlar.
Conceptual double-fetch (illustrative)
len1 = read(table.length)         // time-of-check: validate mapping
...                                // <-- guest grows table.length here
for i in 0..read(table.length):   // time-of-use: re-read -> larger
    sum += host_mem[base + i]      // OOB read past the table
leak <- infer bytes from sum

Warning

Bir checksum/parity sonucu bir side channel'dır: guest'e hiç byte geri kopyalanmasa bile guest, türetilmiş bir değerin nasıl değiştiğine bakarak host belleğini yeniden inşa edebilir.

Detection

  • Güvenilir crash signal yok: OOB read leak loop'u tarafından sınırlanır ve genelde vmx'i panic'lemez, bu yüzden core dump'lara güvenmeyin. Davranışsal avlanın.
  • Behavioral signal: ACPI table memory'sini tekrar tekrar yeniden yazan ve ACPI re-evaluation'ı yeniden tetikleyen (aynı length field'ında birçok küçük mutation) bir guest anormaldir; meşru guest'ler ACPI table'larını bu şekilde çalkalamaz.
  • vmware.log / ESXi vmkernel logs: ACPI device-model warning'lerini, assertion mesajlarını ya da ACPI handling'e bağlı alışılmadık vmx CPU tüketimini izleyin.
  • EDR / host telemetry: tek bir VM'in ACPI/firmware emulation etrafında sürekli vmx aktivitesi sürmesi, özellikle diğer exploit davranışlarının habercisi olarak.

Mitigation

  • Patch: VMSA-2020-0023'teki düzeltilmiş build'lere geçin:
  • ESXi 6.5: ESXi650-202007101-SG (build 16901156)
  • ESXi 6.7: ESXi670-202008101-SG (build 16773714)
  • ESXi 7.0: ESXi_7.0.1-0.0.16850804
  • Workstation 15.x: düzeltilmiş 15.5.x hattına yükseltin
  • Fusion 11.x: 11.5.6
  • OS/compiler defense: kalıcı düzeltme single-fetch'tir — ACPI length'i bir kez bir local'e kopyalayın, doğrulayın ve walk'un sınırları için yalnızca o local'i kullanın, loop içinde guest memory'yi asla yeniden okumayın.
  • Attack surface'i azaltın: guest'leri patch'li hypervisor build'lerinde tutun; ACPI device opsiyonel değildir, yani buradaki birincil kontrol hardware kaldırma değil patch'tir.

References