JOP under IBT-disabled userspace¶
Jump-Oriented Programming, functional gadget'ları
retyerine indirectjmp/callve bir dispatcher gadget aracılığıyla chain'ler, dolayısıyla bir shadow stack'i hiç tetiklemez — ve CET Indirect Branch Tracking'in (IBT) userspace'te devre dışı veya yok olduğu her yerde tamamen geçerli kalır.
Mechanism¶
Neden çalışır
CET, control-flow integrity'yi iki yarıya böler: shadow stack backward
edge'leri (RET) korur ve IBT, her indirect hedefin ENDBR64 ile
başlamasını gerektirerek forward edge'leri (indirect JMP/CALL) korur.
JOP bu boşlukta yaşar: yalnızca forward edge'leri kullanır ve IBT'nin kapalı
olduğu platformlarda o forward edge kısıtlanmamıştır.
- Jump-Oriented Programming'de (Bletsch, Jiang, Freeh & Liang, ASIACCS 2011)
attacker stack'i ve
RET'i tamamen terk eder. Functional gadget'lar — asıl işi yapan dizilimler —retile değil, bir indirectjmp/callile biter. - Kontrol bir dispatcher gadget tarafından sıralanır: gadget adreslerinden
oluşan bir dispatch table boyunca bir virtual program counter'ı ilerletir
ve bir sonrakine atlar. Klasik bir biçim
add edx, 4; jmp dword ptr [edx]'dir — table pointer'ını artır, kendi indirect jump'ıyla kontrolü dispatcher'a geri veren bir sonraki functional gadget'a atla. - Hiçbir
RETçalışmadığı için, shadow stack hiç danışılmaz: tespit edilecek bir return-address uyuşmazlığı yoktur. Bir CET shadow stack (user veya supervisor) saf bir JOP chain'ine karşı hiçbir şey yapmaz. - Forward edge yalnızca IBT etkinse kontrol edilir. Linux'ta IBT kernel için
etkindir ama userspace process'leri için değil (non-
ENDBRbinary'lerle geriye dönük uyumluluk), dolayısıyla userspace indirect jump'ları kısıtlanmamıştır. IBT'nin açık olduğu yerlerde bile fonksiyonlarendbr64ile başlar, dolayısıyla fonksiyon entry point'lerine (veya herhangi birendbr64-prefix'li konuma) atlayan bir dispatcher yine de IBT kontrolünü geçer — kaba taneli IBT her call site'ın hangi geçerli hedefe ulaşabileceğini sabitlemez.
Invariant: bir shadow stack yalnızca RET'in ne okuduğunu kısıtlar. JOP hiç
return etmez, dolayısıyla onunla yürütme arasında duran tek şey forward-edge
CFI'dır — ve IBT-disabled userspace'te bu yoktur.
Walkthrough¶
1. Forward edge'in korumasız olduğunu doğrula. -fcf-protection ile derlenmiş
bir userspace binary'si endbr64 marker'ları taşır, ama platform onu enforce etmedikçe
process IBT kapalı çalışır:
$ readelf -n ./target | grep -a IBT
Properties: x86 feature: IBT, SHSTK
$ objdump -d ./target | grep -m1 endbr64
1149: f3 0f 1e fa endbr64 ; valid indirect-branch landing pad
GNU-property note'u binary'nin IBT'yi desteklediğini söyler; enforce edilip edilmediği bir runtime/kernel kararıdır ve userspace IBT genellikle etkin değildir.
2. Dispatch table'ı ve bir dispatcher gadget'ı hazırla. Dispatcher table'da gezinir ve her functional gadget'a devreder:
; dispatcher gadget (advance virtual PC, jump to next gadget)
add edx, 4
jmp dword ptr [edx] ; edx -> dispatch table of functional-gadget addresses
; a functional gadget ends in an indirect branch back to control
pop eax
jmp dword ptr [esi] ; returns flow to the dispatcher, not via RET
3. Shadow stack neden sessiz kalır. Chain yalnızca jmp/call çalıştırır; hiç
RET verilmez, dolayısıyla hiçbir shadow-stack karşılaştırması olmaz ve hiçbir #CP
fault'u ateşlenmez. Saldırı, user shadow stack tamamen etkin olsa bile başarılı olur.
JOP'u gerçekte ne durdurur
Bunu yalnızca forward-edge CFI durdurur: IBT'yi etkinleştirmek (böylece
indirect branch'ler ENDBR64'ü hedeflemeli) ve ideal olarak her call site'ı
meşru hedef kümesine kısıtlayan fine-grained CFI —
FineIBT, Clang CFI veya
kernel CFI. Kaba IBT tek başına yine de
herhangi bir endbr64'e atlamaya izin verir, dolayısıyla geçerli entry
point'lerin JOP/COOP tarzı yeniden kullanımı onu atlatabilir.
Detection¶
Runtime monitor'ları JOP'u, gadget boyutundaki dizilimlere yapılan sık indirect jump'ların ve tekrarlayan bir dispatcher'ın istatistiksel imzasıyla işaretler (örn. JOP-alarm tarzı anomali tespiti), çünkü meşru kod nadiren birçok kısa indirect-jump parçasını arka arkaya dizer.
Mitigation¶
(Artık risk / onu ne durdurur.) Userspace'te IBT'yi etkinleştir ve enforce et;
onu fine-grained forward-edge CFI (FineIBT, Clang CFI)
ile eşleştir, böylece dispatcher endbr64 hedeflerini serbestçe chain'leyemez.
Shadow stack'ler (Intel CET shadow stack) ROP için
gereklidir ama JOP'a karşı tek başlarına yetersizdir.
References¶
- Tyler Bletsch, Xuxian Jiang, Vince W. Freeh, Zhenkai Liang. Jump-Oriented Programming: A New Class of Code-Reuse Attack (ASIACCS 2011). — https://www.comp.nus.edu.sg/~liangzk/papers/asiaccs11.pdf
- nsg650. Out of control (JOP under disabled userspace IBT, CET notes). — https://nsg650.github.io/blogs/22-4-2025.html
- Wikipedia. Indirect branch tracking. — https://en.wikipedia.org/wiki/Indirect_branch_tracking