Fuzzing ve AFL


Fuzzing

Giriş

Fuzzing uygulamalara/sistemlere beklenmedik veya semi-malformed veriler yollanarak sıralı bir şekilde test etme yöntemidir. Black-box yazılım testi olarak kategorilendirilebilir. Bu yöntemle uygulamaları, protokolleri, sistemleri test edebiliriz.
Fuzzing bugları bulmakta iyiyken bulduğu buglar genelde basit düzeyde oluyor. Bu bugları sömürmek için exploit geliştirmek araştırmacıya kalıyor. İnsan eliyle yapılması zor olan rastgele mutasyonları gerçekleştirip bunları sürekli deneyerek araştırma yapan kişiye önemli bulgular sağlıyor.
Bu yazıda en çok kullanılan fuzzing aracı olan American Fuzzy Lop’u (AFL) anlatıp, nasıl kurulduğunu ve neler yapabildiğimizi anlatacağım.

AFL

American Fuzzy Lop açık kaynaklı bir fuzzing aracıdır. Genetik algoritmaların yardımıyla girdilerini değiştirerek uygulamalarda crash arar. Şimdiye kadar günlük hayatımızda kullandığımız çoğu uygulamada bug veya açık bulmak için kullanıldığını görüyoruz. Firefox’tan iOS çekirdiğine kadar büyük bir aralıkta açık bulmak için kullanılmıştır[2].
Afl fuzz yapmak için bize 2 tane mod sunmaktadır:
  1. Kaynak koddan afl-gcc ile derlemek. Bu yöntemde AFL programı derlerken kendi fonksiyonları yerleştirip, fonksiyonlara göre fuzzing yapıyor.
  2. QEMU modu. Bu modu kaynak koda erişimimiz olmadığında kullanabiliriz. QEMU emülatörünü kullanarak çalıştırılabilir dosyayı fuzz edebiliriz.


Kurulum

Afl’i iki şekilde kurabiliriz:
  • Kaynak kodlarından derleyerek.
  • Apt-get üzerinden kurabiliriz.
Kaynak kodlarından kurmak için aşağıdaki yol izlenebilir:
  • sudo apt install build-essential libtool-bin automake bison flex python libglib2.0-dev
  • wget http://lcamtuf.coredump.cx/afl/releases/afl-2.52b.tgz
  • tar -xvf afl-2.52b.tgz
  • make && make install
  • Eğer QEMU modunu da kullanmak istiyorsanız:
    • cd qemu_mode
    • ./build_qemu_support.sh
Apt-get üzerinden kurulmak istenirse “sudo apt-get install afl” komutu yeterli olacaktır.

Kullanımı

İnternet üzerinde basit programlar üzerinde kullanışıyla ilgili çok fazla kaynak var. Ben bu yazıda biraz daha farklı bir örnek üzerinden ilerlemek istiyorum. Rode0day[3] isimli bug bulma yarışmasından bir dataset üzerinde ilerlemek istiyorum. Rode0day Northeastern, New York ve MIT üniversitelerinin düzenlediği bir yarışma. Belirli periyodlarla LAVA[4] (Large-scale Automated Vulnerability Addition) ile bug enjekte edilmiş uygulamaları paylaşarak bunlarda bug arayıp puan kazandığımız bir yarışma. Yani içerisinde bug olduğunu biliyoruz fakat nerede ve hangi inputla açığa çıktığını bulmak ise fuzzing işlemine düşüyor.
wget https://rode0day.mit.edu/static/archive/18.09.tar.gzkomutuyla dataset’i indiriyoruz.
tar -xvf 18.09.tar.gz” komutuyla dataseti çıkartıyoruz.
Bu dataset içerisinde fuzz etmek istediğim program download/jpegs dizininde bulunan uygulama. Kaynak kodu’da olduğu için derleyip hemen başlayalım.
CC=afl-gcc ./build.sh” komutuyla derliyoruz. afl-gcc ile derlememizin sebebi afl’in derlerken kendi işini kolaylaştıran fonksiyonları yerleştirerek fuzzing’i daha kolay yapmak.

 
Bunu daha iyi görebilmek için derlediğimiz dosyayı IDA ile açıp içerisine bakalım.




Elimizde artık fuzz edebileceğimiz bir dosya var. Fuzzingi daha iyi yapabilmek için güzel bir girdi setine (corpus) ihtiyacımız var. Fuzz edeceğimiz dosyayla ilgili hiçbir şey bilmediğimizi düşünerek dosyayı çalıştırıyoruz. Bizden .jpg uzantılı bir dosya istediğini görüp ona göre input setimizi oluşturmaya başlıyoruz.

 
Bulunduğumuz dizinin altında bulunan inputs klasöründe 2 tane .jpg uzantılı dosya var. Bunlarıda kullanabilriz fakat biraz daha dosya kullanmamız daha iyi olabilir. Girdilerimizi indirip kopyalıyoruz. Girdilerimizi optimum hale getirmek için afl-cmin komutunu kullanacağız. Bu komutla girdilerimizi optimize edeceğiz.
Afl-cmin -i inputs -o min-out rebuilt/bin/memdjpeg @@” komutunu çalıştırıyoruz. Bu komutta -i girdilerin bulunduğu klasör -o komutun çıktılarının yazılacağı klasörü göstermek için kullanılıyor. En ondaki @@ ise argümanı dosyadan aldığını belirtiyor.
Spesifik input için kullanılan afl-tmin komutuyla da bir tane dosyayı minimal hale getirmeye çalışalım. afl-tmin komutu tek bir dosyay uygulanabilir. afl-cmin gibi bir dizine uygulanamaz. Basit bir döngüyle bütün klasördeki dosyaları kapsar hale getirebilirsiniz.




Fuzzinge başlamadan önce “echo core >/proc/sys/kernel/core_pattern” komutunu root olarak çalıştırarak afl’in programda hata aldığımız inputları yanlış anlamasını sağlıyoruz. Girdilerimiz hazır olduğuna göre afl’i çalıştırıp fuzzing işlemine başlamanın sırası geldi.
afl-fuzz -i min-out/ -o out -M fuzzer-master -- rebuilt/bin/memdjpeg @@”
Komutu açıklayalım:
  • -i girdileri alacağımız dizin
  • -o afl-fuzz’ın çıktılarını yazacağı dizin
  • -M/S bu parametrelerle paralel bir şekilde fuzzing yapabiliyoruz. Master node oluşturacağımız zaman -M slave node oluşturacağımız zaman -S parametresini kullanıyoruz. Parametre olarak verdiğimiz değer ise node’un ismi oluyor.
  • --’dan sonraki bölümde ise programın nasıl çalıştığını yazıyoruz.



Eğer birden fazla çekirdeğe sahipseniz paralel olarak afl’i çalıştırabiliyorsunuz. Kaç çekirdeğin müsait olduğunu afl-gotcpu komutuyla öğrenebiliriz.



Master node hala çalıştığı için 5 çekirdekten 4ü kullanılabilir gözüküyor. O zaman ilk slave’i oluşturalım.
afl-fuzz -i min-out/ -o out -S fuzzer-slave-1 -- rebuilt/bin/memdjpeg @@”



 
Afl’in bütün bulgularını görmek için out klasörüne gidiyoruz. Bu klasörde crashes, hangs ve queue adında 3 tane dizin var.
  • Crashes: Herhangi bir hata alınan girdiler.
  • Hangs: Programın timeout vermesini sağlayan girdiler.
  • Queue: Programa verilecek olan girdiler.
Crashes dizini bizim için önemli çünkü buradakilerle beraber program’dan hata alıyoruz.

Bu girdiyle aldığımız sonucun sömürülebilir olup olmadığını görmek için exploitable[5] adında bir gdb plugini kullanacağım. Exploitable eklentisini github üzerinden indirebilirsiniz. Gdb ile programı çalıştırıp Segmentation fault aldıktan sonra aşağıdaki gibi kullanabilirsiniz. Burada da gördüğümüz gibi bu girdiyi kullanarak programı exploit etme ihtimalimiz var.

 

Sonuç

Bu yazımızda fuzzing ve afl hakkında bilgi vermek istedim. Yazının içeriğinde fuzzing hakkında genel bilgi, american fuzzy lop’un ne olduğunu, kurulumunu ve nasıl kullanıldığını anlatmaya çalıştım.

Kaynaklar

  1. Fuzzing: https://en.wikipedia.org/wiki/Fuzzing
  2. american fuzzy lop (2.52b): http://lcamtuf.coredump.cx/afl/
  3. Rode0Day: https://rode0day.mit.edu
  4. LAVA: Large-scale Automated Vulnerability Addition: https://rode0day.mit.edu/static/lava.pdf
  5. GDB 'exploitable' plugin: https://github.com/jfoote/exploitable 
CT-Zer0

Yorumlar

Bu blogdaki popüler yayınlar

1. Geleneksel Stajyer CTF Soru ve Cevapları

B*-Tree (BTree, BPlusTree) Veri Yapısı ile Veri İndeksleme

2. Geleneksel Stajyer CTF Soru ve Cevapları - 2017