Skip to content

Loop Gadget / Main-Loop Gauge (COOP control)

Counterfeit Object-Oriented Programming (COOP)'in kalbindeki dispatcher vfgadget: saldırganın düzenlediği counterfeit object container'ını dolaşan ve her birinde bir virtual function çağıran gerçek bir loop — return address forge etmeden bütün method'ları zincirler.

Mechanism

Note

COOP (Schuster et al., IEEE S&P 2015), legitimate virtual call site'lar üzerinden ulaşılan var olan bütün virtual function'ları ("vfgadget") yeniden kullanarak coarse CFI'yı atlatır. Main-loop gadget (ML-G, namıdiğer "Looper") burada kilit taşıdır: binary içinde, object pointer'lardan oluşan bir container üzerinde iterate eden ve her element için bir virtual call dispatch eden gerçek bir loop'tur. Defender'ın anlaması gereken invariant şu: yalnızca "indirect target geçerli bir function entry mi / herhangi bir vtable'daki bir method mu?" diye kontrol eden bir CFI policy, COOP'in her adımı tarafından sağlanır, çünkü her call gerçek bir call site üzerinden gerçek bir virtual-function entry'ye iner. Hiçbir return address bozulmadığı için shadow-stack / return-edge savunmaları hiçbir şey görmez. Saldırgan counterfeit C++ object'leri sağlar (sahte vptr → sahte vtable); ML-G'nin kendi loop'u control-flow motoru haline gelir, argument-loader ve invoker vfgadget'lar veriyi örtüşen object field'ları üzerinden geçirir.

Bir defender için çıkarım: forward-edge koruması precise olmalı (type/signature-checked target'lar, sadece "herhangi bir vtable method" değil) ve object integrity (vptr provenance) önemlidir. Coarse-grained CFI tek başına ML-G dispatch'ini kısıtlamaz.

Walkthrough

Kavramsal olarak ML-G, bir container'dan object pointer'ları okuyan ve her iteration'da bir virtual call dispatch eden bir loop'tur. Açıklayıcı bir şekil (çalışan bir exploit değil):

        mov   rbx, [rcx+0x40]    ; load array base from a counterfeit object field
loop:
        mov   rax, [rbx]         ; rax = next object pointer
        mov   rdx, [rax]         ; rdx = its (fake) vtable
        call  [rdx+OFF]          ; legitimate virtual call -> a vfgadget
        mov   rbx, [rbx+0x20]    ; advance to next element
        test  rbx, rbx
        jnz   loop

Her call [rdx+OFF], coarse bir CFI target set'inin izin verdiği tam da o tür indirect call'dur. COOP "program"ı, tıpkı bir ROP chain'in return address dizisi olması gibi, counterfeit object'lerin önceden düzenlenmiş dizisidir.

Warning

Bu, defansif boşluğu anlamaya yönelik kavramsal bir control-flow taslağıdır, silahlandırılmış bir chain değil. Gerçek COOP, counterfeit object'leri yerleştirmek için bir memory-write primitive'i ve target binary'de somut bir ML-G/vfgadget set'i gerektirir; offset'ler tamamen target'a özgüdür.

COOP vfgadget taksonomisi (Schuster et al.)

Paper, yeniden kullanılabilir küçük bir gadget rolleri set'i adlandırır. Takip eden analizlerde atıf yapılan temsili tipler:

ML-G      main-loop gadget (the Looper / dispatcher)
ML-ARG-G  main loop that also forwards arguments to callees
ARG-G     argument loader (populate a register/field for the next call)
INV-G     invoker (call an arbitrary API function pointer)
W-SA-G    write gadget (store-to-attacker-address)
W-COND-G  conditional / loop-counter write

Geri kalanı birbirine composable yapan şey ML-G'dir: virtual dispatch'e yeniden giren bir loop olmadan, tek tek vfgadget'lar zincirlenemez.

Mitigation

Precise forward-edge CFI, gelişigüzel COOP dispatch'ini bozar: Clang CFI ve FineIBT yalnızca "bir function mu" değil, call-target'ın type'ını ya da tag'ini kontrol eder. COOP, COOP against Intel CET için motive edici bypass'tır: COOP hiçbir zaman return address'leri manipüle etmediğinden, tek başına bir shadow stack onu durduramaz — önemli olan özellik forward-edge precision'dır. Daha geniş expressivity tartışması için control-flow bending'i karşılaştır.

References