Skip to content

Structures-Before-Canary Overwrite

Exploit hedefine, memory'de stack canary'den önce duran local variable'lara, struct'lara ya da saved pointer'lara overflow ederek ulaş — cookie'nin kendisine asla dokunmadan ya da onu leak etmeden.

Mechanism

Neden işe yarar

Bir stack canary (__stack_chk_guard) yalnızca saved return address'i ve saved frame pointer'ı korur: compiler cookie'yi local buffer'lar ile saved RIP arasına yerleştirir ve __stack_chk_fail yalnızca cookie function epilogue'unda değişirse abort eder. Compiler'ın canary'nin altına (daha düşük adreslere, bir forward overflow'un önce yazdığı yere) yerleştirdiği local variable'lar, in-frame structure'lar ve pointer'lar hakkında hiçbir şey söylemez. Exploitation hedefine o komşu object'lerden birini bozarak ulaşılabilirse — bir offset/index variable'ı, bir function pointer, bir FILE*, bir length field'i, bir loop counter'ı — canary asla overwrite edilmez, __stack_chk_fail asla ateşlenmez ve function normal şekilde return eder.

Bir canary'nin zorunlu kıldığı invariant "saved return address linear olarak overwrite edilmedi"dir. Canary'den önce kalan bir overflow, programı yine de hijack ederken o invariant'ı sağlam bırakır, dolayısıyla savunma basitçe saldırının data path'inde değildir.

Walkthrough

Klasik target: overflow'a uğramış buffer'a komşu yerleştirilmiş bir index/offset variable'ı. Onu overflow etmek bir sonraki write'ın nereye ineceğini değiştirir ve saldırganın canary slot'unu atlarken return address'e doğrudan ulaşmasını sağlar.

char buf[16];
int  i;                 /* lives next to buf; controls the write offset */
for (i = 0; ; i++) {
    buf[i] = getchar();
    if (buf[i] == '\n') break;
}

"While overflowing buf with your 17th character, it will end up overflowing into the local i variable. This variable will decide in the next iteration at what offset the rest of the data will be written" — bu da saldırganın canary'yi tamamen atlayıp doğrudan return address'e yazmasını sağlar.

Cookie'yi yenen diğer komşu object'ler
  • scanf("%lf") atlaması: tek başına bir . beslemek target variable'ı overwrite etmeden bırakır, böylece bir write dizisi canary'nin üzerinden adımlayıp cookie'yi bozmadan return pointer'a inebilir.
  • Komşu function pointer / longjmp buffer'ı / SEH record'u: canary'nin altında saklanan callable bir pointer'ı overwrite etmek, epilogue check'i hiç çalışmadan, bir sonraki indirect call'da control flow'u yönlendirir.
  • Sonraki bir copy'nin length / size field'i: sonraki bir memcpy'yi sınırlayan bir in-frame struct member'ını bozmak, küçük bir overflow'u, kendisi yalnızca return address'i hedefleyen bir arbitrary write'a çevirir.

Layout garanti değildir

Yararlı bir object'in gerçekten canary'den önce durup durmadığı; compiler version'ına, optimization level'ına ve reordering'e bağlıdır. Bazı GCC/Clang version'ları, bu maruziyeti azaltmak için array'leri scalar'ların üstüne taşıyabilir (stack-protector'ın local-reordering davranışı; garanti değildir ve optimization level'ına bağlıdır — bkz. Stack Protector / SSP) ve randstruct kernel struct layout'unu randomize eder. Saldırı yalnızca exploitable bir object'in cookie'den önce ulaşılabilir olduğu durumda işler.

Mitigation

Bu sınıf canary'nin kendisi tarafından durdurulmaz. Onu durduran şey:

  • Array'ler scalar'ların üstüne gelsin diye local'leri yeniden sırala (stack-protector'ın local-reordering davranışı): -fstack-protector-strong hangi function'ların instrument edileceğini seçer, layout kararları ise compiler version'ına ve optimization level'ına bağlıdır. İdeal durumda index/offset ve pointer variable'larını buffer'ın üstünde tutar, böylece bir forward overflow onlara ulaşmadan önce canary'ye tosar.
  • Bounds/overflow eliminasyonu_FORTIFY_SOURCE ve Stack Variable Auto-Init, overflow primitive'ini kaldırır ya da kısıtlar.
  • Pointer-seviyesi integrityIntel CET shadow stack return address'i bağımsız olarak korur ve Code-Pointer Integrity, bir structures-before-canary write'ının aksi halde boz​acağı in-frame code pointer'ları korur.

Leak/brute sınıflarıyla karşılaştır — Stack Canary Leak ve Byte-by-Byte Canary Brute Force — bunlar bunun yerine cookie değerini kurtararak aynı savunmayı yener.

References