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:
-
Kaynak koddan afl-gcc ile derlemek. Bu yöntemde AFL programı derlerken kendi fonksiyonları yerleştirip, fonksiyonlara göre fuzzing yapıyor.
-
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.
-
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
-
cd qemu_mode
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.gz” komutuyla 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.
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.
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
-
Fuzzing: https://en.wikipedia.org/wiki/Fuzzing
-
american fuzzy lop (2.52b): http://lcamtuf.coredump.cx/afl/
-
Rode0Day: https://rode0day.mit.edu
-
LAVA: Large-scale Automated Vulnerability Addition:
https://rode0day.mit.edu/static/lava.pdf
- GDB 'exploitable' plugin: https://github.com/jfoote/exploitable
Yorumlar
Yorum Gönder