Insyde SWSMI CommBuffer pointer not validated (CVE-2021-33626)¶
Bir InsydeH2O SWSMI handler'ı (SmmResourceCheckDxe), bir QWORD CommBuffer pointer'ını SMRAM dışında olduğunu kanıtlamadan kabul ediyor; bu da ring-0'daki bir caller'ın SMM write'larını SMRAM'in içine yönlendirip onu corrupt etmesine — ring -2'de arbitrary code execution'a kadar — imkân veriyor.
Mechanism¶
Note
SMRAM'deki SMM code'u, OS ile normal DRAM'de yaşayan paylaşımlı bir SMM
Communication Buffer (CommBuffer) üzerinden haberleşir. Herhangi bir SMI
handler'ı için trust invariant'ı şudur: attacker'ın sağladığı CommBuffer
data'sından ulaşılabilen her pointer, handler onu dereference etmeden ya da
üzerinden write yapmadan önce SMRAM'in dışını (ve beklenen bounds içinde)
gösterdiği doğrulanmalıdır. Standart EDK II kontrolü
SmmIsBufferOutsideSmmValid()'dir. Bir handler, CommBuffer'dan ham bir QWORD
okuyup onu bir destination pointer olarak bu kontrol olmadan kullandığında,
ring-0'daki bir attacker tekrar SMRAM'in içini gösteren bir adres
yerleştirebilir. Güvenilen SMM handler'ı bunun ardından — tam ring -2
privilege'iyle — attacker'ın seçtiği bir konuma write yapar ve SMRAM data'sını
ya da code'unu corrupt eder. Bu, SMM compromise'in confused-deputy biçimidir:
handler güvenilirdir ama attacker'ın kontrol ettiği doğrulanmamış bir pointer
üzerinden hareket eder (bkz.
commbuffer-smm-pointer-not-in-smram.md).
Walkthrough¶
Insyde advisory'sine (SA-2022021) ve CVE-2021-33626 için NVD'ye göre etkilenen driver SmmResourceCheckDxe'dir. NVD bunu "a vulnerability [that] exists in SMM ... that registers a SWSMI handler that does not sufficiently check or validate the allocated buffer pointer (QWORD values for CommBuffer). This can be used by an attacker to corrupt data in SMRAM memory and even lead to arbitrary code execution." diye tanımlar. Binarly bunu BRLY-2021-013 olarak izledi.
SmmResourceCheckDxe, OS'ten SMM communication protocol üzerinden ulaşılabilen bir software SMI handler'ı register eder.- Handler, CommBuffer'dan bir QWORD field okur ve onu SMRAM-range/bounds validation'ını çağırmadan bir memory pointer olarak kullanır.
- Ring-0'daki bir attacker o QWORD'ü SMRAM range'i içindeki bir adresle doldurur.
- SW SMI'yı tetiklemek, handler'ın attacker'ın seçtiği pointer üzerinden SMRAM içinde write yapmasını sağlar; SMRAM corrupt olur → potansiyel ring -2 code execution.
Kontrol edilmemiş CommBuffer pointer pattern'i (örnekleme amaçlı, silahlandırılmamış)
Warning
Skorlar kaynağa göre değişiyor: Insyde SA-2022021 CVSS 8.2
(AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H) listeliyor; NVD ise 7.8
(AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H), CWE-829 veriyor. Bu, Insyde'ın
"23 vulnerabilities" cluster'ından biri
(bkz. insydeh2o-smm-memory-corruption-cluster.md).
Detection¶
- CHIPSEC:
chipsec_main -m common.smmvetools.smm.smm_ptrfuzzer'ıyla CommBuffer pointer field'larını fuzz edip attacker'ın sağladığı adreslere write yapan SMI handler'larını tespit et; SMRAM lock'unu doğrula. - Binarly FwHunt: SPI dump'larını BRLY-2021-013 rule'uyla tarayıp
SmmResourceCheckDxeunchecked-pointer pattern'ini ara. - Static review: write destination'ını
SmmIsBufferOutsideSmmValid()/ eşdeğer range ve overflow kontrolleri olmadan CommBuffer içeriğinden türeten her SMI handler'ını işaretle.
Mitigation¶
- InsydeH2O update'lerini uygula: Kernel 5.1 → 05.16.23, 5.2 → 05.26.23, 5.3 → 05.35.23, 5.4 → 05.43.23, 5.5 → 05.51.23 (SA-2022021'e göre), platform/OEM vendor üzerinden.
- CommBuffer'dan türetilen her pointer'ı, herhangi bir dereference ya da write'tan
önce hem range (SMRAM dışında) hem de bounds açısından
SmmIsBufferOutsideSmmValid()(veya eşdeğeri) ile doğrula. - Hardware backstop'lar: locked SMRAM (SMRR / D_LCK),
SMM_Code_Chk_Enve desteklenen yerlerde bir SMM supervisor / deprivileging katmanı.