American Fuzzy Lop – fuzzer, który stosuje algorytmy genetyczne w celu maksymalizacji pokrycia kodu przypadkami testowymi. Pomógł w wykryciu bugów w dziesiątkach projektów wolnego oprogramowania, w tym Serwera X.Org[1], PHP, OpenSSL, pngcrush[2][3][4], bash[5], Firefox[6], BIND[7][8] oraz Qt[9].
Kod źródłowy American Fuzzy Lopa jest powszechnie dostępny na stronie Michała Zalewskiego. Wokół programu skupiła się aktywna społeczność – 27 sierpnia 2015 roku, jego główna lista mailingowa liczyła 392 użytkowników i programistów i publikuje się na niej średnio 100 postów miesięcznie[10].
Typowe zastosowanie
AFL wymaga od użytkownika podania przykładowej komendy, która go uruchamia, oraz przynajmniej jednego przykładowego pliku wejściowego. W przypadku odtwarzacza muzycznego, American Fuzzy Lop może operować na krótkim pliku dźwiękowym. Następnie, fuzzer próbuje uruchomić wskazaną komendę i jeśli mu się powiedzie, próbuje na jego podstawie stworzyć najmniejszy plik wejściowy, który prowadzi do tego samego zachowania.
Po tym początkowym etapie, AFL zaczyna proces fuzzingu poprzez modyfikacje pliku wejściowego. Jeśli dojdzie do awarii programu lub jego zawieszenia, może to oznaczać odkrycie nowego błędu – może to być błąd bezpieczeństwa. W takim przypadku, zmodyfikowany plik wejściowy jest zapisywany w celu późniejszej weryfikacji.
W celu osiągnięcia maksymalnej wydajności, American Fuzzy Lop oczekuje, że testowany program został poddany kompilacji przy pomocy programu narzędziowego, który dodaje do kodu źródłowego funkcje, które śledzą przepływ sterowania. Pozwala to fuzzerowi na wykrycie zmian w zachowaniu aplikacji w reakcji na modyfikacje danych wejściowych. W przypadku gdy jest to niemożliwe, AFL pozwala także na testy czarnej skrzynki.
Funkcjonalność
Silnik fuzzera
Silnik American Fuzzy Lopa używa kilku algorytmów, których celem jest sprowokowanie nieprzewidzianego zachowania. Wśród nich należy wymienić zamiany bitów oraz całych bajtów pliku wejściowego na różne liczby, które mogą powodować przypadki graniczne. Poza tym, AFL może generować przypadki testowe na podstawie zbioru znanych słów kluczowych, co bywa pomocne w przypadku fuzzingu programów implementujących własne gramatyki - na przykład SQLite. Generowane przypadki testowe, które wzbudzają konkretne części kodu programu mogą potem zostać użyte przez bardziej wyspecjalizowane programy testujące. Ponadto, podczas fuzzowania możliwe jest wykrycie zawieszenia programu jeśli nie wyłącza się on przed upłynięciem określonego czasu oczekiwania. AFL zwraca także uwagę na awarie objawiające się zgłoszeniem sygnałów takich jak SIGABRT lub SIGSEGV.
Testowane dane wejściowe mogą zostać przekazane programowi w ramach standardowego wejścia lub wiersza poleceń. Fuzzowanie programów sieciowych nie jest aktualnie bezpośrednio wspierane, choć w niektórych przypadkach istnieją praktyczne rozwiązania tego problemu[11].
Usprawnienia wydajności
Jednym z problemów, które musiały zostać pokonane w celu implementacji AFLa było wydajne uruchamianie setek procesów na sekundę. Pierwotnie American Fuzzy Lop uruchamiał każdy proces od nowa, aktualnie jednak domyślnie silnik fuzzujący korzysta z rozwiązania, które w znacznym stopniu polega na wywołaniu systemowym "fork". Dodatkowo, możliwe jest przyspieszenie procesu fuzzowania poprzez wykorzystanie interfejsu LLVM, który pozwala testowanej aplikacji zgłosić moment, w którym ma ona zostać forkowana. AFL pozwala także na współbieżne fuzzowanie tego samego programu.
Interfejs użytkownika
American Fuzzy Lop komunikuje się z użytkownikiem poprzez kolorowy tekstowy interfejs użytkownika, który wyświetla w czasie rzeczywistym statystyki na temat procesu fuzzowania. Konfiguracja programu odbywa się poprzez ustawienia wiersza poleceń oraz zmienne środowiskowe. Poza tym, programy mogą odczytywać informacje o postępach z pliku "fuzzer_stats".
Programy narzędziowe
Poza afl-fuzz
oraz narzędziami, które mogą zostać użyte do zmian w kodzie programu, do American Fuzzy Lopa dołączone są programy przeznaczone do nadzoru procesu fuzzowania. Dodatkowo, istnieje afl-cmin
oraz afl-tmin
, które mogą zostać użyte do minimalizacji korpusu testowego i pojedynczych przypadków testowych. Narzędzia te mogą się przydać przy przygotowaniu danych wygenerowanych narzędziem afl-fuzz
do dalszego użytku przez inne fuzzery.
Przypisy
Linki zewnętrzne
- S. K. Cha, M. Woo, D. Brumley, Program-Adaptive Mutational Fuzzing, in Proceedings of the 36th IEEE Symposium on Security and Privacy, 2015. (to appear)
- Multi-System and Internet Security Cookbook, Hors-Serie No. 11 Outils de sécurité, p. 36, American Fuzzy Lop, Kevin Denis, June 2015.
- Fuzz and strings (lwn.net)
- Fuzzing (on) FreeBSD – (Mostly) automated bug discovery with security/afl – a presentation at FOSDEM
- Testing with two failure seeking missiles: fuzzing and property based testing. ep2015.europython.eu. [zarchiwizowane z tego adresu (2015-12-08)]. – a presentation at EuroPython 2015.
- Stagefright: Scary Code in the Heart of Android a presentation at Black Hat Briefings
- The Fuzzing Project
- Grammatical Inference and Language Frameworks for LANGSEC