fastbin dup into stack¶
Bir fastbin dup'tan sonra, fd'yi forge edilmiş bir stack chunk'ına overwrite et ve stack üzerine malloc et.
Mechanism¶
Bir fastbin-dup'tan başla, böylece bir chunk fastbin'de iki kez bulunur.
Duplicate edilmiş allocation'lardan birinde, chunk'ın fd'sini stack'in yakınındaki
fake bir chunk'a (safe-link ile mangle edilmiş) bir pointer ile overwrite et. Fake
konum, allocator'ın onu kabul etmesi için header slot'unda geçerli bir size
field taşımalıdır. O boyuttaki bir sonraki allocation ardından stack'e bir pointer
döndürür — target'ı senin kontrol ettiğin bir arbitrary write.
Warning
glibc >= 2.32'de fd overwrite'ı safe-link ile mangle edilmiş olmalıdır:
mangled = (chunk_addr >> 12) ^ target. Bu, key'i hesaplamak için bir
heap-address leak'i gerektirir; aksi halde forge edilmiş fd reddedilir/çöptür.
Walkthrough¶
unsigned long stack_var[4] __attribute__((aligned(0x10)));
stack_var[1] = 0x20; // forged chunk size header at stack_var+0x08 (stack_var[1])
// ... after a fastbin dup, d points at a freed chunk's fd field:
unsigned long addr = (unsigned long)d; // address where fd field is stored (mangle position)
unsigned long ptr = (unsigned long)stack_var; // target: fake chunk at stack_var
*d = (addr >> 12) ^ ptr; // safe-linking: mangle fd to target the stack
// drain the duplicated chunks, then:
void *p = calloc(1, 8); // returns the stack address
assert((unsigned long)p == (unsigned long)stack_var + 0x10);
stack_var[1] = 0x20 forge edilmiş size'dır, böylece stack_var+0x10'daki chunk
geçerli görünür; fd overwrite'ı glibc 2.32+ PROTECT_PTR dönüşümü (P >> 12) ^
target'ı kullanır. Beklenen çıktı: son calloc, stack_var + 0x10 döndürür ve
assert geçer — malloc stack'e bir pointer verdi, örn. saklı bir return address'i
overwrite etmek için.
Mitigation¶
Safe-linking (2.32+) bir heap leak'i zorunlu kılar; fastbin size sanity check'i target'ta makul bir forge edilmiş size gerektirir; stack canary'ler ve shadow stack'ler stack write'ının neyi başarabileceğini sınırlar.