COOP for Intel CET Bypass¶
Counterfeit Object-Oriented Programming, bütün C++ virtual fonksiyonlarını bir counterfeit object array üzerinden zincirler — yalnızca legitimate call/ret çiftleri kullanır, böylece ne CET shadow stack'i desenkronize eder ne de bir
endbr'nin dışına iner.
Mechanism¶
Note
COOP (Schuster et al., S&P 2015), binary'de halihazırda bulunan virtual fonksiyon zincirlerini,
her birini normal call site'ı üzerinden invoke eder. Shadow-stack hayatta kalması: her
virtual call'un eşleşen bir ret'i vardır, böylece hardware shadow stack senkronize kalır —
hiçbir return address ezilmez, dolayısıyla shadow-stack karşılaştırması asla başarısız olmaz.
IBT hayatta kalması: vfgadget'lar, legitimate entry point'leri zaten endbr64 ile başlayan
CFG-valid C++ virtual fonksiyonlarıdır, böylece forward-edge IBT check'leri geçer. Zincir, bir
main-loop vfgadget'ı ("Looper") tarafından orkestre edilir; bu vfgadget, saldırgan tarafından
düzenlenmiş bir counterfeit object pointer dizisi üzerinde iterate eder ve her birini programın
kendi indirect-call mekanizması aracılığıyla dispatch eder.
CET'in dayattığı invariant (return'ler shadow stack ile eşleşir; indirect branch'ler endbr'ye
iner) yapısal olarak sağlanır — COOP yalnızca well-formed virtual dispatch kullanır.
Walkthrough¶
Bir type-confusion bug'ı, bir vtable pointer'ını saldırgan tarafından kurulmuş bir counterfeit
object array'ine işaret ettirir. Looper, her object pointer'ını okur ve onu CFG-onaylı indirect
call (örneğin __guard_dispatch_icall_fptr) aracılığıyla dispatch eder; bu da bir endbr64'e iner:
mov rbx, [rcx+0x40] ; gadget array base from counterfeit object
loop_start:
mov rax, [rbx] ; next vfgadget pointer
call __guard_dispatch_icall_fptr ; CFG-approved indirect call -> endbr64
mov rbx, [rbx+0x20] ; advance to next gadget
test rbx, rbx
jnz loop_start
Ardından bir Invoker vfgadget'ı, this+0x10'daki bir function pointer'ını (örneğin WinExec)
ve this+0x08'deki argümanını (örneğin "cmd.exe /C calc") okur ve aynı dispatcher aracılığıyla
çağırır. Her vfgadget'ın call/ret çifti dengelendiğinden shadow stack baştan sona tutarlı kalır —
CET yalnızca sıradan polymorphic dispatch görür.
Warning
"IBT'yi atlatır" iddiası, yayın anında kısmen geleceğe dönüktü: Windows'ta tam IBT enforcement'ı
henüz devreye alınmamıştı. endbr64-hedef argümanı sağlamdır, ama gerçek dünyada IBT-enabled
COOP gösterimleri sınırlı kalır.
Mitigation¶
IBT tek başına coarse'tur — endbr64-prefix'li herhangi bir virtual fonksiyon erişilebilirdir. Onu
fine-grained forward-edge type check'leri (VTV gibi vtable/type tabanlı CFI ya da
FineIBT per-callsite tag'leri) ile eşleştir ve counterfeit object'leri reddetmek için
object/vtable provenance'ını doğrula. Shadow stack gereklidir ama, COOP'un gösterdiği gibi,
virtual-call'a-özel zincirlere karşı yetersizdir.
Bkz. Intel CET shadow stack bypass via counterfeit objects.