Wild pointer write¶
Değeri uninitialized, eski ya da attacker'ın etkilediği bir pointer üzerinden yapılan, esasen keyfi bir adrese düşen ve orada ne varsa onu corrupt eden bir write.
Mechanism¶
Bir "wild" pointer, programın asla geçerli bir object adresi olmasını
amaçlamadığı bir değer tutar — çünkü uninitialized kullanılmıştır
(access-of-uninitialized-pointer), bir free'den sonra dangling bırakılmıştır ya
da corrupt/attacker-controlled metadata'dan hesaplanmıştır. Onun üzerinden write
yapmak, o sahte adrese veri depolar. Pointer değeri etkilenebilir olduğunda, store
yönlendirilmiş bir memory corruption'a dönüşür:
Bir pointer'ın değerini attacker etkileyebildiğinde, write operasyonları keyfi memory location'lara yönlendirilebilir; bu, function return address'leri ya da control-flow bilgisi dahil kritik data yapılarının değiştirilmesine izin verir. (Kök problem CWE-465 / CWE-824; destination kontrol edildiğinde sonuç CWE-123 write-what-where'dir.)
Note
Wild-pointer-write, birçok belirli primitive'in arkasındaki genel biçimdir:
destination'ı seçebildiğin (ya da kısmen seçebildiğin) anda, bir
arbitrary-write-primitive'e (write-what-where) yükselir. Bir buffer
overflow'dan farkı, kötü adresin bilinen bir buffer'ın sonundan taşmaktan değil,
pointer değerinin kendisinden gelmesidir. Kök problem invalid/uncontrolled
bir pointer value'dur: CWE-465 (Pointer Issues) ve CWE-824 (Uninitialized
Pointer Dereference). Destination attacker-controlled olduğunda somut sonuç
CWE-123 (Write-What-Where Condition); wild write bilinen bir buffer'ın OOB
bölgesine denk geldiğinde ise CWE-787 (out-of-bounds write)'tır.
Walkthrough¶
Uninitialized-pointer write (değer stack garbage'ıdır):
void f(int set, char *src) {
char *dst; /* uninitialized -- holds stale stack bytes */
if (set) dst = real_buf;
/* attacker arranges !set */
memcpy(dst, src, 32); /* writes 32 bytes to a wild address */
}
Attacker-controlled pointer → write-what-where:
struct node { long *where; long what; };
/* corrupt node->where via an earlier overflow/UAF, then: */
*n->where = n->what; /* stores chosen value at chosen address */
Tek bir controlled wild write tipik olarak yüksek değerli bir hedefe nişan alır —
bir saved return address, bir GOT/PLT entry (got-plt-overwrite), bir function
pointer ya da allocator metadata — tek bir write'ı control-flow hijack'e dönüştürür.
Bir wild/out-of-bounds store için ASan raporu
Detection¶
ASan/KASAN çoğu out-of-object write'ı yakalar; "wild" durumu çoğu zaman
non-canonical/garbage bir adreste bir SEGV olarak kendini gösterir. MSan,
uninitialized pointer'lar üzerinden yapılan write'ları işaretler; statik analiz
(-Wuninitialized, clang-analyzer, Coverity) bariz uninitialized-dst biçimini
yakalar. CFI/RELRO, control verisini hedeflediğinde başarılı bir write'ı tespit
edilmiş bir ihlale dönüştürür.
Mitigation¶
Her pointer'ı initialize et (ideal olarak NULL'a) ve free'den sonra null'la;
write'tan önce destination pointer'ları/offset'leri amaçlanan object'e karşı
doğrula; full RELRO GOT'u read-only yapar; CET shadow stack'ler saved return
address'leri korur; memory-safe diller ya da bounds-checked container'lar bu sınıfı
ortadan kaldırır.