Format string read¶
Stack ve memory leak etmek için attacker-controlled bir format string içinde %x/%p/%s kullan.
Mechanism¶
Attacker-controlled data format string'in kendisi olarak verildiğinde — örneğin
printf("%s", user_input) yerine printf(user_input) — variadic fonksiyon gömülü
conversion specifier'ları yorumlar ve asla sağlanmamış argümanları çeker. Argümanların
sayısı/tipi için format string'e güvendiğinden, %x/%p stack'ten ardışık word'leri
okur ve %s bir stack word'ünü pointer olarak alıp (bir NUL'a kadar) dereference eder.
Note
Positional / direct-parameter söz dizimi %N$x, padding olmadan doğrudan N'inci
argüman slot'una atlar; buffer'ını bulduğunda kesin bir stack offset'ini hedeflemene
olanak tanır.
Walkthrough¶
Stack word'lerini leak etme:
$ ./example "Hello World %p %p %p %p %p %p"
Hello World 000E133E 000E133E 0057F000 CCCCCCCC CCCCCCCC CCCCCCCC
Direct-parameter erişimiyle hedefli read — %8$p 8'inci stack değerini leak eder:
Seçilen bir adresi buffer'a yerleştirip %N$s ile geri okumak (burada N, buffer'ının
stack'te göründüğü offset'tir) bir arbitrary memory read verir. Yaygın kullanımlar:
ASLR'yi boşa çıkarmak için bir libc/PIE pointer leak etmek veya bir stack canary okumak.
Detection¶
-Wformat -Wformat-security non-literal format'larda compile-time uyarı verir; FORTIFY
(-D_FORTIFY_SOURCE=2) %n'i kısıtlar ama read'leri değil. %n%n%n tarzı input'larla
fuzzing format-string sink'lerini ortaya çıkarır.
Mitigation¶
Her zaman literal bir format ver (printf("%s", user)). Compiler uyarıları ve static
analysis bug sınıfını yakalar. ASLR leak'in değerini artırır ama onu durdurmaz.