İçeriğe geç
edumintsBlog
Yazılım3 dk okuma

AFL++ ile Daha Etkili Fuzz Testi İçin İpuçları

Kaynak: Hacker News

Paylaş
YazılımEdumints Blog
İçindekiler 3 başlık

Fuzz testi (bulanıklaştırma testi), yazılım kusurlarını mekanik olarak keşfetmek için inanılmaz derecede etkili bir yöntemdir, ancak hala yeterince kullanılmamakta ve ihmal edilmektedir. Hangi dilde yazılmış olursa olsun, karmaşık girdileri hatasız bir şekilde kabul etmesi gereken ve daha önce hiç fuzz testinden geçmemiş herhangi bir programı ele aldığınızda, bu test genellikle en az bir hata ortaya çıkarır. Şu anda kendi bilgisayarınızda yüklü olan programların en az biri, hatta belki de çoğu bu duruma dahildir. Neredeyse her yazılımda keşfedilmeyi bekleyen kolay ulaşılabilir hatalar vardır.

Son altı yılda yaklaşık 1.000 projeyi fuzz testine tabi tuttuktan sonra derlenen bu kontrol listesi; C ve C++ için tartışmasız en iyi fuzzing platformu olan glibc tabanlı Linux dağıtımlarında çalışan açık kaynaklı C ve C++ hedefleri üzerinde AFL++ kullanımını ele almaktadır. Daha önce fuzz testi yapılmış bir programda bile bu teknikleri uygulamak, önceki testlerin gözden kaçırdığı kusurları ortaya çıkarabilir. Bu ipuçları, resmi AFL++ belgelerini ("Performance Tips" ve "afl-fuzz" teknik makalesi) tamamlayıcı niteliktedir.

(1) Sanitizer'ları ve Assertion'ları Yapılandırın#

Daha fazla assertion (doğrulama), daha etkili fuzzing demektir ve sanitizer'lar (temizleyiciler) otomatik olarak eklenen birer assertion gibidir. Varsayılan olarak hem Address Sanitizer (ASan) hem de Undefined Behavior Sanitizer (UBSan) ile test yapın:

  • Derleme sırasında şu bayrakları kullanın: $ afl-gcc-fast -g3 -fsanitize=address,undefined ...
  • ASan'ın varsayılan yapılandırması ideal değildir ve ASAN_OPTIONS ortam değişkeni ile ayarlanmalıdır. Özelleştirme yapıldığında AFL++ en azından şu seçenekleri gerektirir: export ASAN_OPTIONS="abort_on_error=1:halt_on_error=1:symbolize=0". Keşfedilen bir çökmeyi hata ayıklayıcıda (debugger) incelerken UBSan'ın da aynı şekilde davranması için benzer biçimde yapılandırılması gerekir.
  • Fuzzing hassasiyetini artırmak için use-after-return hatalarını tespit etmeyi etkinleştirin. Bu işlem testi biraz yavaşlatsa da maliyetine fazlasıyla değer: ASAN_OPTIONS+=":detect_stack_use_after_return=1"
  • Varsayılan olarak ASan, use-after-free hatalarını yakalamak için yeni bellek tahsislerinin yalnızca ilk 4KiB'lık kısmını bir desenle doldurur. Bu, fuzzing için yeterli değildir. Bir program malloc ile 4KiB'tan fazla bellek ayırır ve başlatılmamış bellek üzerinde strlen kullanırsa, 4KiB sonrasında muhtemelen bir sıfır bulunacağından hata tespit edilemez. Neredeyse tüm tahsisleri desenle doldurmak ve persistent mode (kalıcı mod) kullanırken testleri daha iyi izole etmek için bu sınırı yükseltin: ASAN_OPTIONS+=":max_malloc_fill_size=$((1 << 30))"
  • C++ projelerini test ederken ve GCC'nin libstdc++ kütüphanesini bağlarken -D_GLIBCXX_DEBUG kullanmayı düşünün. ASan, bir konteynerin kapasitesi dahilindeki sınır dışı erişimleri "göremez"; bu ek doğrulamalar boşlukları doldurur. Bu bayrağın ABI'yi değiştirdiğini unutmayın, ancak fuzz testi bu tür uyumsuzlukları anında ortaya çıkaracaktır.

(2) Persistent Mode (Kalıcı Mod) Kullanımını Tercih Edin#

AFL++, tek bir satır kod yazmadan (afl-gcc, afl-clang ile) birçok programı olduğu yerde test edebilse de, AFL++'ın persistent mode (afl-gcc-fast, afl-clang-fast) özelliğini tercih edin.

  • Bu mod genellikle on kat daha hızlıdır ve harcanan çabaya kesinlikle değer.
  • Yine de test izolasyonu gibi dikkat edilmesi gereken bazı tuzakları vardır.
  • Pratik bir yazılım geliştirme alışkanlığı olarak, tüm fuzz testlerinizin temelini oluşturacak hazır bir şablon dosyası (fuzztmpl.c gibi) bulundurmak, yeni test kurulumlarını hızlandıracaktır.

Yazılım Geliştirme ve Öğrenme Açısından Pratik Çıkarımlar#

  • Varsayılan Ayarlara Güvenmeyin: Araçların standart kurulumları genellikle genel kullanım içindir. ASAN_OPTIONS örneğinde görüldüğü gibi, güvenlik ve kalite araçlarını derinlemesine yapılandırmak, gizli kalmış bellek hatalarını yakalamanın anahtarıdır.
  • Test Hızı Doğrudan Kaliteye Etki Eder: Persistent mode kullanarak test hızını 10 katına çıkarmak, aynı sürede 10 kat daha fazla senaryonun denenmesi ve çok daha derin hataların keşfedilmesi anlamına gelir.

Kaynak ve atıf

Bu yazı, Hacker News üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:

  • nullprogram.com/blog/2025/02/05