Poradnik dotyczący testowania fuzzowania (fuzzowania).
⚡ Inteligentne podsumowanie
Testowanie rozmyte polega na wprowadzaniu do programu nieprawidłowych, nieoczekiwanych lub losowych danych i wykrywaniu awarii, zawieszeń i błędów pamięci, ujawniając w ten sposób luki w zabezpieczeniach, których skryptowe testy funkcjonalne prawie nigdy nie wykrywają samodzielnie.
Co to jest testowanie fuzzowe?
Testowanie rozmycia lub rozmycie Testowanie rozmyte (FUZZ) to technika testowania oprogramowania polegająca na wprowadzaniu nieprawidłowych lub losowych danych, zwanych FUZZ, do systemu w celu wykrycia błędów w kodzie i luk w zabezpieczeniach. Celem testowania rozmytego jest wstawianie danych za pomocą zautomatyzowanych lub półautomatycznych technik i testowanie systemu pod kątem różnych wyjątków, takich jak awaria systemu lub błąd wbudowanego kodu.
Testowanie rozmycia (fuzz testing) zostało pierwotnie opracowane przez Bartona Millera z Uniwersytetu Wisconsin–Madison, który ukuł ten termin po tym, jak zakłócenia na linii modemowej powodowały awarię używanych przez niego programów. Jego studenci uruchomili pierwsze testy rozmycia (fuzz testing) w 1989 roku i odkryli, że około jedna trzecia testowanych przez nich narzędzi UNIX ulegała awarii lub zawieszała się. Testowanie rozmycia to Testowanie oprogramowania technika i jest to rodzaj Testowanie bezpieczeństwa.
Poniższy diagram przedstawia podstawową pętlę rozmycia, w której wygenerowane dane są przesyłane do testowanej aplikacji, a następnie obserwowana jest reakcja.
Dlaczego warto przeprowadzać testy Fuzz?
Fuzzing zasługuje na swoje miejsce w planie testów, ponieważ bada dane wejściowe, dla których nikt nie pomyślał o napisaniu przypadku testowego. Poniżej wymieniono główne powody, dla których zespoły stosują tę metodę.
- Testowanie nieścisłe zwykle pozwala na wykrycie najpoważniejszych błędów i usterek bezpieczeństwa, ponieważ awaria stanowi bezpośredni dowód nieobsłużonej ścieżki wejściowej.
- Testowanie rozmyte daje skuteczniejszy wynik, gdy jest stosowane z Czarny Box Testy, testy beta i inne metody debugowania.
- Testowanie rozmyte służy do sprawdzania podatności oprogramowania na ataki. Jest to bardzo ekonomiczna technika testowania, ponieważ dane wejściowe są generowane automatycznie, a nie wpisywane ręcznie.
- Testowanie rozmyte (fuzz testing) to jedna z technik testowania typu „czarna skrzynka”. Fuzzing to również jedna z najczęstszych metod wykorzystywanych przez hakerów do wyszukiwania luk w zabezpieczeniach systemu, dlatego jego uruchomienie w pierwszej kolejności eliminuje najłatwiejszą drogę atakującemu.
Rodzaje testów rozmytych
Fuzzery są zazwyczaj grupowane według wiedzy o programie, który atakują. Im więcej fuzzer wie, tym głębiej może wniknąć w kod.
| Typ | Co wie fuzzer | Typowe zastosowanie |
| Rozmycie czarnej skrzynki | Nic o układzie wewnętrznym; widzi tylko dane wejściowe i wyjściowe. | Szybki test działa na pliku binarnym lub na żywo. |
| Rozmycie białego pola | Pełny kod źródłowy, często połączony z symbolicznym wykonywaniem w celu rozwiązania problemów w trudno dostępnych gałęziach. | Głęboka analiza komponentu, którego źródło jest dostępne. |
| Szare pole rozmycia | Brak przeglądu źródła, lecz informacja zwrotna z czasu wykonania, np. do których rozgałęzień kodu dotarło wejście. | Domyślna wartość dla nowoczesnych silników, takich jak AFL++ i libFuzzer. |
Drugi, starszy podział rozdziela głupie rozmywanie od inteligentne rozmywanie. Głupi fuzzer odwraca bity bez pojęcia o formacie danych wejściowych, więc większość danych jest odrzucana przez pierwszy napotkany parser. Inteligentny fuzzer rozumie sumy kontrolne, pola długości i strukturę wiadomości, dzięki czemu jego dane wejściowe przechodzą walidację i docierają do logiki leżącej u ich podstaw. Fuzzing sterowany zasięgiem jest udoskonaleniem metody „szarej skrzynki”, które uczyniło rozmycie głównym nurtem: silnik instrumentuje kod binarny, przechowuje wszelkie dane wejściowe docierające do nowej gałęzi i mutuje te, które pozostały, dzięki czemu korpus stopniowo ewoluuje w kierunku niezbadanego kodu zamiast zaczynać od nowa od losowego szumu.
Jak przeprowadzić test Fuzz
Kroki testowania rozmytego obejmują podstawowe kroki testowania:
Krok 1) Zidentyfikuj system docelowy — wybierz punkt końcowy pliku binarnego, biblioteki, usługi lub protokołu, który będzie przedmiotem ataku i potwierdź, że masz uprawnienia do jego przetestowania.
Krok 2) Zidentyfikuj dane wejściowe — wypisz wszystkie punkty wejścia, z których obiekt docelowy odczytuje dane: pliki, argumenty wiersza poleceń, zmienne środowiskowe, pakiety sieciowe, pola formularzy i ładunki API.
Krok 3) Wygeneruj rozmyte dane — wytwarzać nieprawidłowe dane wejściowe poprzez mutowanie prawidłowych próbek, generowanie ich z modelu formatu lub łączenie obu tych metod.
Krok 4) Wykonaj test, używając danych rozmytych — uruchom cel na wygenerowanych danych wejściowych, najlepiej w pętli, która automatycznie uruchamia proces ponownie po każdym błędzie.
Krok 5) Monitoruj zachowanie systemu — zwracaj uwagę na awarie, zawieszenia, błędy potwierdzenia, niekontrolowane wykorzystanie pamięci i raporty dotyczące dezynfekcji, zamiast sprawdzać tylko wydruk.
Krok 6) Wady dziennika — zapisz dokładne dane wejściowe, które wywołały każdą awarię, zmniejsz je do najmniejszego powtarzającego się przypadku i umieść w stosie trace załączone.
Przykłady Fuzzerów
Fuzzery klasyfikuje się również według sposobu, w jaki budują dane wejściowe. Trzy podejścia przedstawione poniżej to te, z którymi spotkasz się najczęściej.
- Fuzzery oparte na mutacjach Modyfikuj istniejące próbki danych, aby utworzyć nowe dane testowe. To bardzo proste i przejrzyste podejście: zaczyna się od prawidłowych próbek protokołu i nieustannie modyfikuje każdy bajt lub plik.
- Fuzzery oparte na generacjach Definiują nowe dane na podstawie danych wejściowych modelu. Zaczynają generować dane wejściowe od podstaw, zgodnie ze specyfikacją.
- Fuzzery oparte na protokole Zależą one od szczegółowej wiedzy na temat testowanego formatu protokołu, a zrozumienie to pochodzi ze specyfikacji. Polega ona na zapisaniu tablicy specyfikacji w narzędziu, a następnie zastosowaniu techniki generowania testów opartej na modelu do prześledzenia specyfikacji i dodania nieprawidłowości do zawartości danych, sekwencji itd. Jest to również znane jako testowanie składni, testowanie gramatyczne lub testowanie odporności. Fuzzer może generować przypadki testowe z istniejącego przypadku lub może wykorzystywać prawidłowe lub nieprawidłowe dane wejściowe.
Istnieją dwa ograniczenia fuzzowania opartego na protokole:
- Testowanie nie może być kontynuowane, dopóki specyfikacja nie będzie dojrzała.
- Wiele przydatnych protokołów jest rozszerzeniem opublikowanych protokołów. Jeśli testy fuzz opierają się na opublikowanych specyfikacjach, Pokrycie testowe dla nowych protokołów będzie ograniczona.
Najprostszą formą techniki fuzzingu jest wysyłanie losowych danych wejściowych do oprogramowania w postaci pakietów protokołu lub zdarzeń. Ta technika przekazywania losowych danych wejściowych jest bardzo skuteczna w wyszukiwaniu błędów w wielu aplikacjach i usługach. Dostępne są również inne techniki, które są bardzo łatwe do wdrożenia. Aby je wdrożyć, wystarczy zmienić istniejące dane wejściowe, a zmiana danych wejściowych może nastąpić poprzez prostą zamianę bitów.
Rodzaje błędów wykrytych przez Fuzz Testing
Ponieważ analiza rozmyta ocenia przebieg na podstawie zachowania programu, a nie na podstawie wartości oczekiwanej, wykryte defekty grupują się w trzy rodziny.
- Błędy asercji i wycieki pamięci: Ta metodologia jest powszechnie stosowana w przypadku dużych aplikacji, w których błędy mogą mieć wpływ na bezpieczeństwo pamięci, co stanowi poważne zagrożenie. Buffer tutaj pojawiają się przepełnienia, błędy użycia po zwolnieniu i odczyty poza zakresem.
- Nieprawidłowe dane wejściowe: W testowaniu rozmytym, rozmycia służą do generowania nieprawidłowych danych wejściowych, które są następnie wykorzystywane do testowania procedur obsługi błędów, co jest istotne w przypadku oprogramowania, które nie kontroluje swoich danych wejściowych. Proste rozmycie można postrzegać jako sposób na automatyzację. testy negatywne.
- Błędy poprawności: Fuzzing może być również używany do wykrywania niektórych rodzajów błędów „poprawności”, takich jak uszkodzona baza danych lub słabe wyniki wyszukiwania. Fuzzing różnicowy, który przekazuje te same dane wejściowe do dwóch implementacji i porównuje uzyskane wyniki, jest standardową metodą ich wykrywania.
Narzędzia do testowania Fuzza
Narzędzia wykorzystywane w zabezpieczeniach sieci WWW mogą być szeroko stosowane w testach niejasności, takich jak: Burp Suite i Peach Fuzzer. Kilka z poniższych klasycznych nazwisk jest już zarchiwizowanych, więc ich aktualny status jest podany obok każdego wpisu.
- Brzoskwiniowy Fuzzer:Peach Fuzzer zapewnia bardziej kompleksową ochronę bezpieczeństwa niż skaner. Inne narzędzia testowe mogą wyszukiwać tylko znane zagrożenia, podczas gdy Peach Fuzzer umożliwia użytkownikom znajdowanie znanych i nieznanych zagrożeń. Peach Tech został przejęty przez GitLab, a wersja Community Edition v3 nie jest już utrzymywana; utrzymywanym następcą jest… GitLab Protocol Fuzzer Community Edition.
- Pełnomocnik Spike'a: Profesjonalne narzędzie, które wyszukuje luki w zabezpieczeniach aplikacji internetowych na poziomie aplikacji. SPIKE Proxy obejmuje podstawy, takie jak: SQL Wstrzykiwanie i ataki między witrynami w całkowicie otwartym środowisku Python infrastruktura i była dostępna dla Linux oraz Windows. Nie był on aktualizowany od wielu lat i został tu zamieszczony ze względu na kontekst historyczny.
- WebScarab:WebScarab jest napisany w Java i dlatego jest przenośny na wiele platform. Framework WebScarab komunikuje się za pomocą protokołów HTTP i HTTPS i działa jako serwer proxy przechwytujący: pozwala operatorowi przeglądać i modyfikować żądania utworzone przez przeglądarkę przed ich otrzymaniem przez serwer, a także przeglądać i aktualizować odpowiedzi wygenerowane przez serwer przed ich otrzymaniem przez przeglądarkę. Wszelkie luki znalezione przez WebScarab są dodawane do listy zgłoszonych problemów. Repozytorium zostało zarchiwizowane w kwietniu 2024 roku i jest teraz dostępne tylko do odczytu.
- OWASP WSFuzzer:WSFuzzer to program napisany na licencji GPL Python która była ukierunkowana na usługi sieciowe i w swojej ostatniej wersji bazowała na protokole HTTP Usługi SOAP był głównym celem. Został wydany jako część WebScarab i wraz z nim wycofany; OWASP ZAP i jego dodatek Fuzzer są zalecaną wymianą.
- Utrzymane alternatywy: AFL++ oraz libFuzzer są standardowymi silnikami opartymi na pokryciu dla kodu natywnego, OSS-Fuzz uruchamia je nieprzerwanie i bezpłatnie w przypadku projektów typu open source, buczenie obejmuje rozmycie protokołu sieciowego w Python. Szersza lista jest zebrana w przewodniku narzędzia do testowania bezpieczeństwa.
Najlepsze praktyki testowania rozmytego
Fuzzer skierowany na cel i pozostawiony sam sobie rzadko znajduje cokolwiek. Poniższe praktyki odróżniają kampanię generującą zgłoszone defekty od kampanii, która jedynie zużywa czas procesora.
- Zacznij od dobrego korpusu nasion. Zbieraj prawdziwe, prawidłowe dane wejściowe, które aplikacja już akceptuje. Mutowanie oryginalnego pliku pozwala na uzyskanie kodu parsującego znacznie szybciej niż mutowanie losowych bajtów.
- Napisz małą, szybką uprząż. Punkt wejścia powinien wykonywać jedną czynność na raz, unikać wywołań sieciowych i zapisów na dysku oraz szybko wracać, ponieważ przepustowość mierzy się liczbą wykonań na sekundę.
- Włącz środki dezynfekujące. Ciche uszkodzenie pamięci często nie powoduje awarii. AddressSanitizer i UndefinedBehaviorSanitizer przekształcają je w natychmiastową, możliwą do zdiagnozowania awarię.
- Biegaj długo i bez przerwy. Jedno- lub dwugodzinne skanowanie wyłapuje płytkie błędy; wykrycie głębokich ścieżek zajmuje zwykle wiele godzin, dlatego też skanowanie metodą fuzzingu powinno odbywać się w ramach nocnego zadania ciągłej integracji, a nie w ramach sesji ręcznej.
- Zminimalizuj i usuń duplikaty każdej awarii. Zmniejsz błędne dane wejściowe do najmniejszej formy i zgrupuj awarie według stosu trace, w przeciwnym wypadku jeden błąd pojawi się w postaci setek biletów.
- Utrzymuj korpus regresji. Dodaj każde odtwarzane wejście do stałego zestawu, który będzie uruchamiany przy każdej kompilacji, dzięki czemu naprawiony błąd nie będzie mógł niepostrzeżenie powrócić.
- Określ cel zgodnie z prawem. Próba zamaskowania działającej usługi innej firmy bez jej pisemnej zgody jest nieodróżnialna od ataku.
Zalety testów fuzzowych
Stosowane w połączeniu z realistycznymi oczekiwaniami, fuzzing dodaje wartości, której inne techniki mają problem dorównać.
- Testowanie niejasne poprawia bezpieczeństwo oprogramowania.
- Błędy wykryte w analizie rozmytej są niekiedy poważne i często pokrywają się z tymi, których używają atakujący, w tym awarie, wycieki pamięci i nieobsłużone wyjątki.
- Jeśli testerzy nie zauważą jakichś błędów z powodu ograniczeń czasowych i zasobowych, błędy te zostaną wykryte również podczas testów nieprecyzyjnych.
- Dane wejściowe są generowane maszynowo, więc zasięg rośnie z dnia na dzień, bez konieczności dodatkowego wysiłku ręcznego.
Wady testów fuzzowych
Te same cechy, które sprawiają, że fuzzing jest tani, ograniczają również to, co można za jego pomocą udowodnić.
- Samo testowanie nieścisłe nie jest w stanie dać pełnego obrazu ogólnego zagrożenia bezpieczeństwa lub zbioru błędów.
- Testowanie niejasne jest mniej skuteczne w przypadku zagrożeń bezpieczeństwa, które nie powodują awarii programów, takich jak niektóre wirusy, robaki i konie trojańskie.
- Testowanie rozmyte pozwala wykryć jedynie stosunkowo proste błędy lub zagrożenia i nie uwzględnia logiki biznesowej.
- Aby działać efektywnie, maszyny potrzebują znacznej ilości czasu.
- Ustawianie warunku wartości brzegowej przy użyciu losowych danych wejściowych jest bardzo problematyczne, chociaż testerzy rozwiązują obecnie wiele z tych problemów za pomocą deterministycznych algorytmów opartych na danych wejściowych użytkownika.
Testowanie rozmyte a testy penetracyjne
Obie te czynności mają na celu wykrycie luk w zabezpieczeniach, jednak odpowiadają na różne pytania i rzadko można je stosować zamiennie.
| kryteria | Testowanie Fuzza | Testowanie penetracyjne |
| Prowadzony przez | Zautomatyzowany silnik generujący nieprawidłowe dane wejściowe | Doświadczony tester analizujący system |
| Szuka | Awarie, zawieszanie się i błędy bezpieczeństwa pamięci | Słabości, które można wykorzystać, w tym błędy logiczne i konfiguracyjne |
| Głębokość | Bardzo szeroki zakres danych wejściowych, płytkie rozumowanie | Wąskie pokrycie, głębokie rozumowanie |
| Wydajność | Odtwarzanie danych wejściowych i stosu traces | Raport z wynikami zawierający ścieżki eksploatacji i oceny ryzyka |
| Najlepszy moment | Ciągle, w procesie kompilacji | Okresowo, w odniesieniu do wersji Release Candidate |
W praktyce te dwie rzeczy wzajemnie się napędzają: testowanie rozmywające usuwa tanie, zautomatyzowane awarie, dzięki czemu ograniczony czas testera może zostać wykorzystany na analizę błędów, które zauważy tylko człowiek.

