CodeBlanks Logo Icon CodeBlanks

Format string

Format string güvenlik açığını öğrenirsin.

Format string açığı nedir?

Format string açığı, kullanıcı girdisinin doğrudan printf'in ilk parametresi olarak verilmesiyle oluşur. printf(input) yazmak, saldırgana biçim dizisini kontrol etme imkânı verir.

Saldırgan %x ile yığıt değerlerini okuyabilir, %n ile belleğe yazabilir. Doğru kullanım printf("%s", input) biçimindedir; burada biçim dizesi sabittir. fprintf, sprintf, snprintf ve syslog aynı açığa sahiptir. Derleyici -Wformat-security uyarısıyla riskli kullanımları yakalar. Bu açık basit görünebilir ama gerçek dünyada çok saldırıya uğramıştır.

%n ile belleğe yazma

Format belirtici %n, o ana kadar yazılan karakter sayısını bir işaretçiye yazar. Bu özellik saldırgana printf üzerinden belleğe yazma imkânı verir.

Örneğin printf("%n", &target) target değişkenine 0 yazar. Saldırgan bu davranışla dönüş adresini değiştirebilir. Bu yüzden modern sistemlerde %n çoğu zaman kapatılır. Güvenli kodda biçim dizesi her zaman sabittir; kullanıcı girdisi yalnızca argüman olarak verilir. puts veya fputs biçimlendirme gerektirmeyen durumlarda daha güvenlidir. syslog çağrılarında da aynı titizlik gerekir.

Uygulama Güvenli biçimlendirme yazdır

void safe_print(const char *fmt, const char *arg) fonksiyonunu tanımla; gövdesi printf(fmt, arg); olsun. main içinde üç kez ("%s\n", "hello"), ("%s\n", "world"), ("%s\n", "safe") ile çağır.

Başlangıç kodu

main.c
#include <stdio.h>

// safe_print fonksiyonunu tanımla
// üç dizeyi "%s\n" biçimiyle yazdır

int main(void) {
    return 0;
}

Örnek çözüm

main.c
#include <stdio.h>

void safe_print(const char *fmt, const char *arg) {
    printf(fmt, arg);
}

int main(void) {
    safe_print("%s\n", "hello");
    safe_print("%s\n", "world");
    safe_print("%s\n", "safe");
    return 0;
}

Beklenen çıktı

hello
world
safe

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Hangisi güvenli bir printf çağrısıdır?

  • printf(input)
  • printf("%s", input) Doğru cevap
  • printf(input, &x)
  • printf(input, x)

Açıklama: Biçim dizesi sabit olmalı; kullanıcı girdisi argüman olarak verilmeli.

2 Format belirticilerini eşle

Kavram Anlamı
%s Dize
%d Tamsayı
%x Onaltılık
%n Yazılan sayı

3 Güvenli printf çağrısını tamamla

Soru
printf("%s", ____);
Cevap
printf("%s", name);

Açıklama: name argüman olarak verilir; biçim dizesi sabittir.

Uzman bölümündeki tüm dersler