Pure-Call Oriented Programming¶
Control flow'u sürmek için bir dispatcher kullanarak
callile biten (retya dajmpyerine) gadget'ları zincirleyen bir code-reuse modeli — GNU libc gadget'larıyla Turing-complete olduğu gösterilmiştir (glibc proof-of-concept olarak kullanıldı; model glibc'ye özgü değildir).
Mechanism¶
Invariant
Klasik code-reuse saldırıları, bir control-transfer instruction ile biten kısa instruction sequence'ları ("gadget"ler) zincirler: ROP ret-terminated gadget'lar kullanır, JOP indirect jmp-terminated gadget'lar kullanır. Savunmalar ve detector'lar genelde bu terminator'lara bakar (örn. shadow stack'ler ret'i izler; gadget-frequency heuristic'leri yoğun ret/jmp chain'lerini işaretler).
Pure-Call Oriented Programming (PCOP) bu varsayımı kaldırır: her fonksiyonel gadget bir indirect call ile biter. Güvenlik açısından önemli özellik şudur: bir call sadece bir jump değildir — stack'e bir return address push eder ve çağrılan sequence'ın kendisi başka side effect'ler içerebilir. PCOP'un katkısı (a) call-terminated gadget'ların nasıl keşfedileceğini, (b) push edilen return address'in side effect'lerinin nasıl nötralize edileceğini ya da soğurulacağını ve (c) bunların, attacker-controlled bir index/table'ı ilerleten bir dispatcher gadget üzerinden nasıl zincirleneceğini göstermesidir — JOP'un dispatcher'ına benzer ama call'lar için. Yazarlar uygun call-gadget'ların GNU libc içinde mevcut olduğunu ve ortaya çıkan modelin Turing-complete olduğunu bildiriyor.
Savunma açısından neden önemli: yalnızca ret/jmp edge'lerini kısıtlayan ya da chaining'i kısıtlamadan call target'larını whitelist'leyen bir control-flow-integrity veya anti-ROP şeması, tamamen call edge'leriyle ifade edilen bir saldırıyla atlatılabilir. İndirgenmiş bir "TinyCOP" varyantının, güncel code-reuse savunmalarına daha da dirençli olduğu anlatılır.
PCOP ≠ COP. Bunu klasik
Call-Oriented Programming (Carlini et al., 2015)
ile karıştırma: COP, coarse-grained CFI'yı, return address'ini overwrite
eden bir dispatcher fonksiyon (memcpy gibi) ile bypass etmeye
odaklanır. PCOP (Sadeghi & Niksefat, 2017) ise her gadget'ın indirect
call ile bittiği "pure" modeli ve push edilen return-address
side effect'lerinin nötralizasyonu üzerinden Turing-completeness'i ele alır.
Walkthrough¶
Kavramsal yapı (somut gadget adresleri yok — bunlar binary/versiyona özgüdür):
[ functional gadget ] ... ; call [reg/mem] -> performs one operation, then transfers
[ dispatcher gadget ] advance index; call next_gadget_from_table
Bir PCOP kurgusunun izlediği high-level adımlar:
- Gadget kataloğu. Hedef bir image'da (örn. libc) faydalı bir primitive yapan ve indirect
callile biten sequence'ları tara, örtük return-address push'unun side effect'ini kaydet. - Dispatcher. Her iterasyonda attacker-controlled bir table'dan sonraki gadget pointer'ını okuyup onu
calleden bir gadget seç — chain'i bir araya dizen motor. - Side-effect yönetimi. Her
callbir return address push ettiğinden, layout'lar bu push'ları tolere etmeli ya da tüketmelidir (ROP "padding" qword'lerini hesaba katmanın muadili). - Kompozisyon. Arbitrary computation'ı ifade etmek için arithmetic/load/store/branch gadget'larını birleştir (Turing-completeness iddiası).
Kavramsal katalog girdisi
Bu girdi bilinçli olarak high-level'dir. PCOP, turnkey bir exploit değil, expressiveness'in akademik bir gösterimidir; gadget set'i, dispatcher ve table layout'u tamamen hedef binary ve toolchain'e özgüdür. Bir tarif değil, call-only savunmaların neden önemli olduğunu anlamak için bir model olarak ele al.
Detection¶
- Fonksiyonların ortasına ya da non-function-entry adreslere giden indirect
calledge'leri — call-gadget reuse'un alameti; coarse-grained CFI ve branch-target telemetry bunları işaretleyebilir. - Doğal call/return eşleşmesi olmadan, kısa ve arka arkaya indirect call'ların anormal yüksek sıklığı (call-chain yoğunluğu).
- Shadow-stack uyuşmazlıkları PCOP için ROP'a kıyasla daha az bilgi verir, bu yüzden savunmacılar yalnızca
ret-only monitoring'e güvenmemeli.
Mitigation¶
- Indirect-call target'larını geçerli function entry'lerine kısıtlayan fine-grained / forward-edge CFI, "call into gadget" adımını kırar.
- Intel CET — IBT (Indirect Branch Tracking), indirect call/jmp target'larının
ENDBR-marked olmasını gerektirir, çoğu mid-function call gadget'ını kaldırır. - Compile/link zamanında gadget-reduction ve ASLR/PIE (böylece gadget/table adresleri bir leak olmadan bilinmez).
References¶
- Pure-Call Oriented Programming (PCOP): chaining the gadgets using call instructions — Springer, Journal of Computer Virology and Hacking Techniques (2017)
- PCOP — Semantic Scholar entry
Ayrıca bkz: call-oriented-programming, jump-oriented-programming, return-oriented-programming.