MicroScope¶
Bir microarchitectural replay saldırısı (Skarlatos vd., ISCA 2019, UIUC): güvenilmeyen bir OS/hypervisor, page fault'ları kullanarak bir kurbanın transient instruction window'unu keyfi sayıda deterministik olarak replay eder ve aksi takdirde tek-atış ya da gürültülü bir side channel'ı neredeyse kusursuz birine dönüştürerek gürültüsünü temizler.
Mechanism¶
Çoğu microarchitectural side channel gürültülüdür ve birçoğu kurban yürütmesi başına yalnızca bir kez sızdırır (örneğin tek sefer çalışan secret'a bağlı bir floating-point op'u ya da branch). MicroScope bu kısıtlamayı ortadan kaldırır. OS/hypervisor kurbanın page table'larını kontrol ettiğinden, Replayer kurbanın dokunmak üzere olduğu bir page'in present bit'ini temizleyebilir; oluşan page fault, in-flight (transient) instruction window'u squash eder ve pipeline'ı fault handler'a yeniden yönlendirir. Replayer fault'u handle eder, trap'i yeniden arms eder ve döner — bu da kurbanın aynı speculative window'u yeniden yürütmesine yol açar. Bunu binlerce kez tekrarla ve saldırgan tek-atış bir event'in binlerce bağımsız ölçümünü elde etsin.
Neden çalışır — replay invariant'ı
Saldırgan channel'da yeni bir bug'a ihtiyaç duymaz; MicroScope bir amplifier'dır. Kurbanın ilerleyişini kontrol ettiği bir fault'a bağlayarak, Replayer tek bir transient execution'ı keyfi uzunlukta bir özdeş replay dizisine dönüştürür. Bu replay'ler üzerinden ortalama almak rastgele gürültüyü sıfıra indirir, dolayısıyla run başına bir bit'in bir kesrini sızdıran bir channel pratikte deterministik hale gelir. Üç rol işbirliği yapar (kurban hariç hepsi saldırgan kontrolünde):
- Replayer — güvenilmeyen OS/hypervisor; fault/replay loop'unu zorlamak için page-table present bit'ini toggle eder.
- Victim — secret'a bağlı kodu (genellikle bir SGX enclave'i içinde) çalıştırır, replay edildiğinden habersizdir.
- Monitor — replay başına bir kez side channel'ı (cache state, execution-port contention vb.) okuyan ve sinyal biriktiren bir thread.
Önemli olarak replay, sızdıran instruction'dan önceki bir instruction'da handle edilmiş bir fault tarafından sürüklenir, dolayısıyla secret'a bağlı transient window, kurban architectural ilerleme kaydetmeden her iterasyonda yeniden yürütülür.
Walkthrough¶
MicroScope, bir page-fault "nuke" channel'ı kuran bir Linux kernel modülü olarak gerçeklenmiştir.
- Gadget'ı map'le. Sızdıran kurban instruction window'unu (örneğin subnormal'a duyarlı bir FP instruction'ı ya da secret'a bağlı bir branch) ve bağlı olduğu page'i tespit et.
- Fault'u arm et. Replayer, sızdıran window'dan hemen önce erişilen bir page'in present bit'ini temizler, böylece kurban kontrollü bir noktada fault verir.
- Replay loop'u. Her fault'ta: Monitor side channel'ını prime eder/okur (örneğin port contention'ı prob eder), sonra Replayer present bit'ini yeniden temizler ve handler'dan döner; bu da bir başka özdeş transient replay'i zorlar.
- Biriktir & decode et. Replay başına ölçümleri birleştir; gürültüsü temizlenmiş bütün, secret'ı ele verir (hangi FP path'i, hangi branch yönü, hangi cache set'i).
MicroScope kernel modülünü inşa etme / yükleme (herkese açık repodan)
# one-time: pick a device path in microscope_mod.h, then create the char dev
$ sudo mknod nuke_channel c 1313 0
# build and load
$ make
$ sudo insmod microscope.ko
$ dmesg | tail # confirm the module registered the page-fault channel
$ sudo rmmod microscope # unload
Release, patch'lenmiş bir Ubuntu 4.4.0-101.124 kernel'ini hedefler ve
page-fault replay primitive'ini gerçekleyen microscope_mod.c/.h ile
util.c/.h dosyalarını içerir. (Yalnızca savunma/eğitim amaçlı kullanım.)
Detection¶
Kurbanın içinden zordur: replay'ler kurbanın göremediği sıradan, handle edilmiş page fault'lar tarafından sürüklenir. Host tarafındaki bir anomali sinyali, genellikle bir timing loop'unda dönen birlikte yerleşik bir Monitor thread'iyle correlate olan, aynı kurban instruction pointer'ı / page'i üzerinde yoğunlaşmış olağandışı yüksek, tekrarlı minor-page-fault oranıdır.
Mitigation¶
MicroScope bir channel değil, bir channel amplifier'dır — software mitigation'ının zor olmasının nedeni de tam budur:
- Yeni bir sızıntı getirmez; var olan herhangi bir transient/side channel'ı keyfi olarak güvenilir kılar. Bir channel'ın signal-to-noise oranını yalnızca azaltan savunmalar (jitter, randomization, tek-atış varsayımları) yenilir, çünkü saldırgan gürültü ortalamada sıfırlanana kadar replay edebilir.
- Replay primitive'i, kurbanın ayrıcalığının altında, OS/hypervisor'da yaşar — dolayısıyla bir kurban (bir SGX enclave'i dahil) zorlanan replay'leri önleyemez, hatta güvenilir biçimde gözlemleyemez bile.
- Bu yüzden pratik savunmalar architectural'dır: hardware'de şüpheli replay loop'larını tespit et/sınırla, fault veren bir instruction window'unun ne sıklıkta yeniden issue edebileceğini bound'la ya da transient window'ları başka türlü replay edilemez yap. Takip eden çalışma (örneğin Jamais Vu), microarchitectural replay'i hardware'de engellemeyi araştırır. Bir geçici çözüm olarak, alışıldık transient-execution hijyeni hâlâ önemlidir — alttaki channel'ı kapat (örneğin constant-time kod, secret'a bağlı port/cache ayak izi yok), çünkü MicroScope yalnızca var olan bir channel'ı amplify edebilir.