Często informacji (i usługom/aplikacjom) przypisuje się trzy atrybuty: poufność, integralność oraz dostępność (triada CIA). Atak denial-of-service to oczywiście atak na dostępność danych/usług. Mam wrażenie, że ostatnimi czasy atak DoS w powszechnej świadomości utożsamia się z atakiem DDoS i botnetami, a szkoda, bo czasami atak tego typu jest dużo łatwiejszy.
Atak DoS bywa łatwy
Korzystanie z języków wysokiego poziomu ukrywa przed programistą szczegóły implementacji poszczególnych algorytmów i struktur danych, co powoduje, że zagadnienie złożoności obliczeniowej nie zyskuje odpowiedniej uwagi. Już kilka lat temu prowadzone były badania mające na celu wykorzystanie złożoności obliczeniowej algorytmów do ataków typu DoS. Ataki te polegały głównie na tym, że generowane były dane wejściowe zgodne z tak zwanym worst case, czyli takie, dla których dany algorytm zachowuje się najgorzej (przykład).
Ja chciałem podać inne przykłady. Pierwszy przykład to atak przez parser XML. XML jest fajnym językiem, w połączeniu ze schematami DTD czy XSD pozwala na dokładny opis struktury danych i jej weryfikację. Problem w tym, że złożoność obliczeniowa tego zadania nie jest pomijalna. Jeśli więc aplikacja przyjmuje dane w formacie XML z niezaufanego źródła i przeprowadza ich walidację na zgodność z XSD/DTD jest potencjalnie podatna na atak DoS. Do jego wykonania wystarczy spreparowany poprawny plik XML (nie koniecznie zgodny ze schematem), najlepiej jeśli jest duży i złożony. Jak się przed tym bronić? To już zależy od wykorzystanych bibliotek. Jeśli chodzi o .NET Framework, stosowna uwaga znajduje się w dokumentacji dla klasy XmlReader (sekcja Security Considerations).
Drugi przykład to PHP (lub inne CGI). Nie wdając się w szczegóły (np. opcje konfiguracji) możliwe jest dość skuteczne zablokowanie serwera zmuszając skrypt PHP do:
- wykonywania się przez długi czas,
- zajęcia przy tym możliwie dużej ilości pamięci,
Oba te parametry są do pewnego stopnia ograniczone, zwykle serwery są skonfigurowane w taki sposób, by skrypty mogły wykonywać się maksymalnie przez określony czas i zajmować nie więcej niż określoną ilość pamięci. Nie jest to jednak do końca skuteczne zabezpieczenie, w końcu mogę uruchomić większą ilość "złych" skryptów, z których każdy będzie mieścił się poniżej limitu maksymalnego zużycia pamięci, ale sumarycznie zajmą ją wystarczająco dużo, by skutecznie zdestabilizować pracę serwera. Fajny efekt może wywołać na przykład podwójna pętla for i tworzenie dużej, dwuwymiarowej tablicy... Albo nawet tworzenie tablicy jednowymiarowej i wykonywanie operacji na poszczególnych elementach. W każdym razie warto zastanowić się, jak będzie zachowywała się aplikacja dla nieoczekiwanych (dużych) danych wejściowych i wbudować pewne ograniczenia. Na przykład jeśli aplikacja oczekuje, że ilość kroków jakiejś operacji otrzyma w parametrze od użytkownika i oczekuje, że będzie to nie więcej niż 100, to warto sprawdzić co się stanie, jeśli otrzyma 10000. A jeszcze lepiej po prostu sprawdzić, czy otrzymane dane mieszczą się w oczekiwanym zakresie i w innym wypadku tchórzliwie odmówić współpracy (na przykład tak, jak tar): $ tar -c tar: Cowardly refusing to create an empty archive Try `tar --help' or `tar --usage' for more information.
Ten wpis jest nieco przewrotnym komentarzem do wpisu Przemka:Testowanie logiki biznesowej. Mam dość szukania SQLi i XSSów, bo jest to umiarkowanie efektywne podejście, dodatkowo często uwsteczniające intelektualnie, monotonne i nużące. Skupiając się na te
Przesłany: Oct 13, 20:42