Web Application Security Testing
white box testing example

Badanie cyberbezpieczeństwa aplikacji CakePHP – analiza podatności PHAR Deserialization w PHP: przykład testów white box

W tym artykule przyjrzymy się podatności PHAR deserialization w PHP, którą Dawid odkrył podczas testów typu white box. Zanim jednak przejdziemy do szczegółów podatności, omówimy najpierw, czym jest PHAR, a następnie wyjaśnimy, na czym polega sama podatność.

Czym jest PHAR?

PHP Archive (PHAR) to funkcjonalność umożliwiająca umieszczenie wielu plików PHP w jednym archiwum w celu łatwej dystrybucji i instalacji. Działa podobnie jak pliki JAR w ekosystemie Javy. Dodatkowo interpreter PHP udostępnia strumieniowy wrapper „phar://”, który pozwala na dostęp do konkretnych plików wewnątrz archiwum PHAR. Przykładowo, aby załadować plik file.php z archiwum myphar.phar, można użyć następującego kodu PHP:

phar code example

Wiele domyślnych funkcji PHP obsługujących operacje na plikach może analizować archiwa PHAR i wyodrębniać z nich żądane pliki PHP. Przykładami takich funkcji są file_exists i fopen.

Czym jest podatność PHAR Deserialization w PHP?

Gdy interpreter PHP napotka wrapper phar:// w jednej z tych funkcji, ładuje archiwum PHAR. Następnie deserializuje zawartość archiwum, co może prowadzić do wykonania potencjalnie niebezpiecznych operacji. Deserializacja to proces odtwarzania obiektu PHP z jego zapisanej reprezentacji. Umożliwia konwersję ciągu znaków lub pliku w określonym formacie do obiektu PHP. W przypadku braku odpowiednich zabezpieczeń atakujący może stworzyć spreparowany obiekt, wykorzystując mechanizmy instancjonowania i autoloadingu interpretera PHP. Może to prowadzić do wykonania dowolnego kodu PHP w podatnej aplikacji webowej.

PHAR deserialization PHP vulnerability

Kiedy należy się martwić?

Podatność PHAR deserialization występuje głównie wtedy, gdy spełnione są następujące warunki:

  • Aplikacja używa funkcji PHP obsługujących pliki w oparciu o dane kontrolowane przez użytkownika.
  • Użytkownik ma wpływ na początkową część ścieżki do pliku.
  • Użytkownik może przesyłać dowolne pliki na serwer.
  • Użytkownik zna bezwzględną ścieżkę do przesłanego pliku.
  • Wrapper phar:// nie został wyrejestrowany.
  • Atakujący ma wiedzę o istniejących klasach w aplikacji, co pozwala mu skonstruować spreparowany obiekt.

Jak wygląda wykorzystanie tej podatności w PHP?

Poniższe kroki opisują typowy proces eksploatacji:

  • Atakujący dowiaduje się, jakie klasy są ładowane przez aplikację. Może to nastąpić poprzez analizę kodu źródłowego aplikacji (jeśli jest dostępny) lub poprzez zrozumienie, jakich bibliotek i frameworków używa aplikacja. Innym sposobem jest próba wykorzystania klas typowych dla powszechnie stosowanych bibliotek.
  • Atakujący tworzy złośliwy plik phar i przesyła go na serwer.
  • Atakujący ustala bezwzględną ścieżkę do wcześniej przesłanego pliku.
  • Atakujący przesyła do podatnego punktu końcowego aplikacji bezwzględną ścieżkę do przesłanego pliku, poprzedzoną prefiksem phar://.
  • Aplikacja wykorzystuje podaną przez użytkownika ścieżkę z prefiksem phar:// do operacji na pliku, np. sprawdzania jego istnienia za pomocą funkcji file_exists.
  • Interpreter PHP rozpakowuje plik phar i odczytuje jego metadane.
  • Interpreter PHP deserializuje metadane spreparowane przez atakującego.
  • Podczas instancjonowania, automatycznego ładowania lub niszczenia obiektu interpreter PHP wykonuje złośliwe operacje na kontrolowanych przez atakującego danych, np. wykonanie kodu w systemie operacyjnym.

Eksploatacja tej podatności bardzo często prowadzi do zdalnego wykonania kodu (RCE) na serwerze aplikacji. Ma to wpływ na poufność, integralność i dostępność systemu, ponieważ atakujący uzyskuje wewnętrzny dostęp do systemu operacyjnego aplikacji.

Co dokładnie odkryliśmy?

Podczas przeprowadzonej przez nas analizy bezpieczeństwa metodą White Box Testing w otwartoźródłowej aplikacji do analizy zagrożeń MISP odkryliśmy wiele obszarów podatnych na phar deserialization. Poniższa tabela przedstawia te obszary:

phar deserialization vulnerable areas

Innym miejscem podatnym na phar deserialization był wtyczka CertAuth. Metoda getRestUser klasy CertificateAuthenticate w pliku app/Plugin/CertAuth/Controller/Component/Auth/CertificateAuthenticate.php w linii 262 wydaje się ładować plik z podanego URL-a. Adres ten jest przechowywany w zmiennej konfiguracyjnej w linii 223. Administrator mógłby potencjalnie zmodyfikować tę zmienną, co mogłoby prowadzić do wykorzystania tej podatności.

Przykładowy scenariusz: Eksploatacja integracji z Apache Kafka

Jeśli znasz MISP, prawdopodobnie słyszałeś o wtyczce do publikowania zdarzeń w Apache Kafka. Jednak możesz nie wiedzieć, że jeśli ta wtyczka jest włączona, złośliwy administrator MISP może wykorzystać ją do wykonania dowolnego kodu w systemie operacyjnym.

Przeanalizujmy krok po kroku, jak można wykorzystać tę podatność:

  1. Wygeneruj złośliwy plik phar.
  2. Prześlij plik phar na serwer.
  3. Włącz wtyczkę Apache Kafka w MISP.
  4. Podaj ścieżkę do przesłanego pliku phar jako konfigurację wtyczki.
  5. Skonfiguruj nasłuchiwacza.
  6. Opublikuj dowolne zdarzenie.

Krok 1 – Generowanie złośliwego pliku phar

Do wygenerowania złośliwego pliku phar użyliśmy oprogramowania PHPGGC:

generating malicious phar file

Polecenie zawarte w pliku „exploit.phar” inicjuje połączenie odwrotne (reverse shell) na porcie 1111, host dawid, który należy traktować jako maszynę kontrolowaną przez atakującego.

Należy pamiętać, że plik php.ini dla CLI na hoście, na którym odbywa się generowanie, musi zawierać następującą linię:

CLI php.ini file line

Krok 2 – Przesyłanie wygenerowanego pliku phar

W ramach tego przykładu testów bezpieczeństwa typu white-box wybraliśmy przesłanie złośliwego pliku jako logo organizacji. Można to zrobić pod następującym adresem URL:
http://<MISP-SERVER>/admin/organisations/edit/1

uploading the generated phar file

Krok 3 – Włączanie wtyczki Kafka w MISP

Aby włączyć wtyczkę Kafka, wykonaliśmy następujące kroki:

  • Przejdź do https://<MISP-SERVER>/servers/serverSettings/Plugin
  • Rozwiń sekcję „Kafka”.
enabling Kafka plugin
  • Włącz następujące ustawienia:
    • Plugin.Kafka_enable
enabling Kafka plugin

o Plugin.Kafka_event_publish_notifications_enable

enabling kafka plugin

Krok 4 – Ustawienie poprawnej ścieżki konfiguracji Kafka

Przesłany plik phar był dostępny pod adresem URL:
http://<MISP-SERVER>/img/orgs/1.png

MISP został zainstalowany w domyślnej ścieżce systemu plików. W związku z tym obraz organizacji został przesłany do następującej ścieżki serwera:
phar:///var/www/MISP/app/webroot/img/orgs/1.png

Tę ścieżkę podaliśmy w następującym ustawieniu Kafka:
Plugin.Kafka_rdkafka_config

Krok 5 – Ustawienie nasłuchu

Aby odbierać połączenie z serwera, uruchomiliśmy nasłuch na maszynie atakującego (dawid) za pomocą polecenia netcat:

setting up listener

Krok 6 – Publikowanie zdarzenia

Utworzyliśmy puste zdarzenie w Event Actions > Add events, a następnie opublikowaliśmy je, klikając „Publish Event” w widoku zdarzenia.

W rezultacie połączenie zostało nawiązane, co pozwoliło nam uzyskać dostęp do powłoki systemu operacyjnego, na którym zainstalowano aplikację MISP:

publishing event phar desarialization

Plik kodu źródłowego MISP/app/Model/AppModel.php jest podatny na atak w linii 2590 (metoda getKafkaPubTool):

kafka code
Jaki jest wpływ tej podatności w PHP?

Należy podkreślić, że tę podatność mogą wykorzystać wyłącznie administratorzy MISP. Sam ten fakt obniża poziom jej krytyczności.

Jednakże podobną podatność odkrył Ianis Bernard z NATO Cyber Security Centre – mogła ona zostać wykorzystana również przez użytkowników nieposiadających uprawnień administratora. Więcej informacji można znaleźć pod tym linkiem.

Podatność w MISP ma poważne konsekwencje. Jako kluczowa aplikacja do wymiany informacji o zagrożeniach i współpracy, MISP jest szeroko stosowany przez organizacje i instytucje z różnych sektorów, w tym rządowego, finansowego, opieki zdrowotnej oraz obronnego. Podatność może umożliwić atakującym nieautoryzowany dostęp do wrażliwych danych przechowywanych w MISP, w tym szczegółów dotyczących trwających dochodzeń, wykrytych podatności oraz innych poufnych informacji.

Podatność w PHP może pozwolić atakującym na zdalne wykonanie dowolnego kodu, co może skutkować całkowitym przejęciem instancji MISP i potencjalnym kompromitowaniem innych systemów i sieci do niej podłączonych. Może to obejmować kradzież poufnych danych, instalację złośliwego oprogramowania lub backdoorów, a także zakłócenie działania kluczowych systemów i usług.

Co więcej, ze względu na charakter MISP jako platformy do współdzielenia informacji o zagrożeniach, skutki naruszenia bezpieczeństwa mogą wykraczać poza jedną organizację. Jeśli atakujący uzyska dostęp do instancji MISP, może potencjalnie uzyskać i wyprowadzić poufne dane od innych organizacji korzystających z platformy. Może to mieć poważne konsekwencje dla bezpieczeństwa narodowego, ochrony danych osobowych i bezpieczeństwa publicznego.

Co może się stać, jeśli Twoja aplikacja jest podatna na deserializację PHAR?

Oto lista możliwych skutków:

  • Zdalne wykonanie kodu: Jeśli atakujący wykorzysta podatność PHAR deserialization, może wykonać dowolny kod na zdalnym systemie. Może to skutkować przejęciem kontroli nad systemem, kradzieżą poufnych danych lub użyciem systemu do dalszych ataków.
  • Atak typu Denial of Service (DoS): Atakujący może wykorzystać podatność PHAR do przeprowadzenia ataku DoS, co może doprowadzić do awarii systemu lub jego unieruchomienia, czyniąc go bezużytecznym dla legalnych użytkowników.
  • Kradzież danych: Podatność PHAR deserialization może umożliwić kradzież danych, takich jak dane uwierzytelniające użytkowników, numery kart kredytowych oraz inne wrażliwe informacje przechowywane w systemie.
  • Infekcja złośliwym oprogramowaniem: Atakujący może wykorzystać podatność PHAR do wstrzyknięcia złośliwego oprogramowania, które następnie może być używane do szpiegowania użytkowników, kradzieży danych lub przeprowadzania dalszych ataków.
  • Utrata reputacji: Udany atak na system może spowodować poważne szkody wizerunkowe dla dotkniętej organizacji. Może to skutkować utratą klientów, przychodów i wiarygodności.

Aby zapobiec tej podatności, organizacje mogą podjąć kilka kroków:

  • Wyrejestrowanie wrappera PHAR – Jeśli nie jest używany, warto go wyrejestrować, aby uniknąć potencjalnych luk w zabezpieczeniach. Można to zrobić za pomocą funkcji stream_wrapper_unregister().
  • Ograniczenie dostępu do plików PHAR – Należy ograniczyć dostęp do plików PHAR zarówno na poziomie systemu plików, jak i kodu aplikacji. Upewnij się, że tylko zaufani użytkownicy mogą odczytywać i modyfikować archiwa PHAR.
  • Używanie wyłącznie bazowej nazwy ścieżki jako wejścia – Podczas otwierania archiwum PHAR należy podawać jedynie jego bazową nazwę, a nie pełną ścieżkę. Pozwala to zapobiec atakom polegającym na przechodzeniu po katalogach (directory traversal) i zapewnia, że archiwum PHAR jest otwierane wyłącznie z określonej lokalizacji.
  • Dodanie prefiksu do ścieżki – Ścieżkę do archiwum PHAR warto poprzedzić stałym ciągiem znaków, aby upewnić się, że jest ono otwierane z właściwej lokalizacji. Może to również pomóc w zapobieganiu atakom typu directory traversal.
  • Biała lista rozszerzeń ścieżek/URL podanych przez użytkownika – Warto stosować białą listę rozszerzeń ścieżek lub adresów URL podawanych przez użytkowników, aby zagwarantować, że otwierane są jedynie prawidłowe archiwa PHAR. Zapobiega to wykorzystaniu aplikacji do wstrzykiwania złośliwych ładunków w metadanych archiwum PHAR.
  • Aktualizacja oprogramowania – Należy regularnie aktualizować zarówno aplikację, jak i wszystkie używane biblioteki, ponieważ nowe łatki i poprawki bezpieczeństwa są wydawane w celu eliminacji podatności takich jak ta.
  • Monitorowanie logów aplikacji – Warto monitorować logi aplikacji w celu wykrywania podejrzanej aktywności, np. nieautoryzowanych prób dostępu do plików PHAR lub nietypowego użycia funkcji unserialize().
  • Regularne audyty bezpieczeństwa – Przeprowadzanie regularnych audytów bezpieczeństwa pozwala na wykrycie podatności i ich eliminację, zanim zostaną wykorzystane przez atakujących. Organizacje powinny okresowo testować swoje aplikacje pod kątem bezpieczeństwa, aby zapewnić ich zgodność z aktualnymi standardami.

Wdrożenie tych środków lub całkowite wyłączenie wrappera strumieniowego PHAR może znacząco zmniejszyć ryzyko wykorzystania tej podatności przez atakujących i uzyskania przez nich nieautoryzowanego dostępu do wrażliwych danych. Organizacje muszą przyjąć proaktywne podejście do bezpieczeństwa i wdrożyć kompleksową strategię ochrony swoich kluczowych aplikacji i zasobów.

Podsumowanie

Podatność ta stanowi poważne zagrożenie, które organizacje korzystające z aplikacji webowych opartych na PHP powinny niezwłocznie zaadresować. Może ona umożliwić atakującym uzyskanie nieautoryzowanego dostępu do poufnych danych i potencjalnie doprowadzić do poważnych strat. Warto jednak zaznaczyć, że tego rodzaju podatność w PHP nie jest problemem, z którym spotykamy się przy każdym przykładzie testów white-box czy rzeczywistych testach penetracyjnych.

Aby zapobiec tego typu atakom, konieczne jest regularne aktualizowanie aplikacji o najnowsze poprawki bezpieczeństwa oraz stosowanie najlepszych praktyk w zakresie bezpiecznego wdrażania oprogramowania. Organizacje powinny także przeprowadzać cykliczne audyty swoich systemów w celu wykrycia potencjalnych luk, które mogłyby zostać wykorzystane przez atakujących. Ponadto kluczowe jest posiadanie skutecznego planu reagowania na incydenty, który umożliwi szybkie identyfikowanie i neutralizowanie potencjalnych zagrożeń.

Porozmawiajmy o przeprowadzaniu badań bezpieczeństwa aplikacji internetowej

Umów się na rozmowę z ekspertem ds. cyberbezpieczeństwa

    Czy artykuł jest pomocny? Podziel się nim ze swoimi znajomymi.

    Author

    Ulaş Deniz İlhan