Obsługa incydentów – kilka luźnych uwag

Wszystkie prezentacje mają to do siebie, że z zasady nie wyczerpują tematu, obejmują zwykle jedynie jego fragment. Czasami po prezentacji pozostaje kilka tematów, które chciałoby się rozwinąć. Z tego powodu mam kilka uwag do prezentacji Przemka Skowrona pod tytułem Obsługa incydentów: Ataki na aplikacje webowe z SEConference 2k10. Uwagi te, a w zasadzie uzupełnienia, bo sama prezentacja bardzo mi się podobała, dotyczą następujących kwestii:

W trakcie prezentacji Przemek krótko tłumaczył na czym polega CSRF (patrz też: Lekcja 4: Cross Site Request Forgery). Zwrócił przy tym uwagę na typowy dla wielu użytkowników zwyczaj posiadania otwartych wielu zakładek w przeglądarce (patrz też: Taby są ZŁE!). Wszystko po to, by zwrócić uwagę na fakt, że cookies zawierające identyfikatory sesji są współdzielone przez wszystkie zakładki. Jest to prawda, aczkolwiek dla pełniejszego obrazu należy dodać, że zamknięcie zakładki nie powoduje “zniknięcie” cookies, które zostały ustawione przez stronę otwartą w tej konkretnej zakładce.

Warto przyjrzeć się nieco bliżej czasowi życia cookie sesyjnego. Ustawienie takiego cookie wygląda w sposób następujący:

HTTP/1.1 200 OK Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: close Content-Type: text/html; charset=UTF-8 Date: Sat, 10 Apr 2010 13:13:10 GMT Expires: Thu, 19 Nov 1981 08:52:00 GMT Pragma: no-cache Server: IdeaWebServer/v0.70 Set-Cookie: PHPSESSID=25afa75bd04af60aafff213206c48744; path=/; HttpOnly Vary: Accept-Encoding Content-Length: 63749

Jak łatwo zauważyć w Set-Cookie (zwykle) nie jest ustawiany czas jego życia , nie ma ustawionego atrybutu expires. Oznacza to, że cookie ginie w chwili zamknięcia procesu przeglądarki. Jeśli w obrębie jednego procesu uruchomionych jest wiele okien lub wiele zakładek, zamknięcie okna lub zakładki nie powoduje usunięcia cookie. Jest to pewne uproszczenie, zwłaszcza w odniesieniu do przeglądarek, które wykorzystują model wielu procesów do realizacji sandboxa (Chrome, IE), ale szczegóły w tym przypadku nie są specjalnie istotne. W uproszczeniu można przyjąć, że cookie sesyjne po stronie przeglądarki żyje tak długo, jak sama przeglądarka, o ile nie zostanie usunięte na przykład podczas wylogowania z aplikacji.

Biorąc pod uwagę to, co wyżej napisałem, na wzrost skuteczności (szans na powodzenie) ataków CSRF wpływ ma nie tylko zwyczaj otwierania równolegle wielu zakładek, ale również:

Po prostu użytkownicy coraz rzadziej wyłączają komputery, zamiast tego stosują hibernację systemu. Skoro system nie jest restartowany, procesy mają coraz dłuższy czas życia, często praktycznie od uruchomienia do zamknięcia systemu, czyli przez czas, który można liczyć w dniach, tygodniach, miesiącach... Tak długo żyją również cookie sesyjne pamiętane w przeglądarce. Jeśli cookie nie zostanie unieważnione przez wylogowanie lub przez ograniczenie czasu życia sesji po stronie serwera, teoretycznie czas między odwiedzeniem strony przez użytkownika, a atakiem CSRF może wynosić kilka dni(!)

W ramach ochrony przed skutkami podatności na CSRF (konkretniej: w celu ograniczenia prawdopodobieństwa skutecznego wykorzystania takiej podatności), warto:

Pierwszy punkt dotyczy konfiguracji aplikacji i nie jest zależny od użytkownika. Punkt drugi jest już jak najbardziej w zasięgu każdego użytkownika, po prostu warto pamiętać o tym, by się wylogować z aplikacji po zakończeniu pracy. Posiadanie tylko jednej otwartej zakładki bynajmniej nie chroni przed CSRF.

Warto też wspomnieć o opisywanej przez Joannę Rutkowską konfiguracji, z której przez pewien czas korzystała w Windows Vista: Running Vista Every Day!, jak również o koncepcji security by isolation oraz systemie Qubes OS (patrz: Introducing Qubes OS).

Phishing z użyciem XSS na formatce logowania

W trakcie prezentacji Przemek dał przykład phishingu wykonanego z pomocą podatności XSS. Payload modyfikuje działanie aplikacji, w tym przypadku formatki logowania, przez co wpisane przez użytkownika dane trafiają pod inny adres niż trafić miały. Z sali pojawiła się wówczas sugestia, że ten scenariusz nie zadziała w przeglądarce Chrome (prawdopodobnie chodzi o taki przypadek). Sprawdziłem – zadziała. Większy problem może sprawić wbudowany w Internet Explorer filtr XSS.

Stosowny przykład dostępny jest pod adresem http://bootcamp.threats.pl/lesson21/ lub https://bootcamp.threats.pl/lesson21/. Certyfikat SSL nie jest prawidłowy, ale z tym problemem można dość łatwo się uporać. Wystarczy przepuścić Chrome przez Fiddlera (Chrome korzysta z ustawień IE, więc jeśli Fiddler jest aktywny, Chrome automatycznie z niego skorzysta), oraz dodać certyfikat generowany przez Fiddlera do zaufanych urzędów certyfikacji. Chrome wówczas certyfikat podstawiony przez Fiddler uzna za zaufany:

W ramach ćwiczenia można spróbować osadzić na stronie XSS, który będzie modyfikował działanie formatki logowania w taki sposób, że dane wpisane przez użytkownika trafią pod inny adres. Podpowiem, że payload należy osadzić w parametrze o nazwie, która powinna kojarzyć się z open redirect.

Z moich testów wynika, że Chrome nawet nie zająknie się w takim przypadku i posłusznie wyśle dane uwierzytelniające pod wskazany przez atakującego adres. Mogę to zrobić co najmniej na dwa sposoby:

Przy okazji nie bardzo mam pomysł jak przeglądarka miałaby się bronić przed tego typu scenariuszem ataku. Przeglądarka nie wie co strona powinna robić zgodnie z zamierzeniami twórcy, a jaka część jej funkcji jest dorzucona przez atakującego (z dokładnością do rozwiązań, w których strona informuje przeglądarkę w tym temacie, patrz content security policy, przy czym nie wiem, czy w takim scenariuszu CSP okazałoby się skuteczne).

Każdą funkcję przeglądarek, która zwiększa bezpieczeństwo użytkowników należy powitać z radością. Jednocześnie trzeba pamiętać, że użytkownik może korzystać z dowolnej przeglądarki o dowolnie zmodyfikowanej (często: zepsutej) konfiguracji pracującej pod kontrolą dowolnego systemu operacyjnego. Zakładanie, że jakiś atak jest mniej istotny, bo w jakiejś przeglądarce istnieje rozwiązanie, które najprawdopodobniej go powstrzyma, jest nieuzasadnione (a co najmniej ryzykowne).

Skuteczność IDS/IPS w wykrywaniu części ataków

Czy jest coś gorszego od braku mechanizmów bezpieczeństwa? Tak, ślepa wiara w skuteczność tych już stosowanych. Czasami taki przypadek objawia się w postaci ślepej wiary w skuteczność ”(...) droższych IPS (...)”. Choć IPS może być przydatnym narzędziem, nie rozwiązuje on wszystkich problemów z bezpieczeństwem. Z niektórymi tematami sobie po prostu nie radzi. Zresztą moje doświadczenia z wdrożeniami IPS wskazują, że bardzo często wdrożenie jest złe. IPS wpinany jest w zupełnie nieodpowiednim miejscu sieci, a jego konfiguracja pozostaje niezmienna przez lata, przy czym konfiguracja pierwotna też nie jest dostosowana do obserwowanego/chronionego środowiska, lecz jest po prostu domyślna.

Załóżmy jednak, że wdrożenie wykonane jest lepiej, konfiguracja jest dostosowana do środowiska, jest wykorzystywana funkcja automatycznego uczenia się przez IPS aplikacji. Pytanie – czy w takim przypadku IPS może skutecznie wykrywać błędy (w zasadzie – wykorzystanie błędów) w kontroli dostępu do danych i do funkcji? W ogólnym przypadku odpowiedź na to pytanie brzmi: nie, nie może.

Działanie IPS czy WAF jest w zasadzie podobne – obserwowanie ruchu i reagowanie w przypadku, gdy “coś” będzie nie tak. Może to być wykrycie sygnatury znanego ataku, ale może to być również zachowanie odstające od ustalonego wzorca. Problem w tym, że w przypadku błędów kontroli dostępu trudno mówić o odstępstwie od ustalonego wzorca. Wszystkie żądania są prawidłowe w kontekście całości aplikacji, o fakcie błędu w kontroli dostępu świadczy to, że użytkownik A może wykonać żądanie, którego normalnie nie powinien wykonać, ale które normalnie może wykonać użytkownik B. Do tego dodać trzeba fakt, że aplikacja żyje, pojawiają się nowi użytkownicy, użytkownicy generują nowe dane.

Jak IPS ma stwierdzić, czy utworzony dopiero co użytkownik Jan Kowalski ma mieć dostęp do funkcji A, B oraz D , ale ma nie posiadać dostępu do funkcji C , która z kolei jest jedyną funkcją dostępną dla użytkownika Emanuel Niezaufany , a który to Emanuel jeszcze wczoraj miał dostęp do funkcji E , ale został mu on cofnięty?

Jak ten IPS ma wiedzieć, że użytkownik A wykonuje przelew, który otrzyma identyfikator 53123 , do którego następnie powinien mieć dostęp w historii operacji? Ale nie do przelewu o identyfikatorze 53124 , który należy już do zupełnie innego użytkownika?

Tak, mogę sobie wyobrazić takiego IPS. Podejrzewam, że można go nawet zaimplementować z wykorzystaniem ModSecurity. Można przypomnieć projekt OWASP Securing WebGoat using ModSecurity Project, na przykład przypadek związany z kontrolą dostępu OWASP ModSecurity Securing WebGoat Section4 Sublesson 02.3. Ale to trochę inne podejście niż puścić IPS w trybie uczenia się, a później będzie dobrze.

Przemek pewnie mógłby coś więcej na temat niepełnej skuteczności WAF powiedzieć, w końcu dzięki temu stał się posiadaczem iPoda. Ze swojej strony przypominam o zadaniach związanych z kontrolą dostępu na bootcamp.

Oryginał tego wpisu dostępny jest pod adresem Obsługa incydentów – kilka luźnych uwag

Autor: Paweł Goleń