< Powrót do Artykułów
◆ Case study · Deserializacja / RCE

Od sesji użytkownika
do krytycznego łańcucha.

Zanonimizowany opis podatności klasy deserialization/RCE: fingerprinting, konfiguracja, bezpieczny PoC, wpływ architektoniczny i konkretne rekomendacje naprawcze.

TRYB Black-box + weryfikacjaKLASA CWE-502WPŁYW RCE / eskalacjaPRIORYTET Critical
SER
niebezpieczna
deserializacja
SA
nadmiarowe
uprawnienia
CFG
sekrety i legacy
konfiguracja
RCE
scenariusz
krytyczny

Łańcuch ataku jest groźniejszy niż pojedyncza luka

Najbardziej wartościowe pentesty nie kończą się na informacji „komponent jest podatny”. Prawdziwa wartość zaczyna się wtedy, gdy pokazujemy, jak kilka pozornie osobnych słabości układa się w łańcuch: zewnętrzny endpoint, mechanizm sesji, sekrety w konfiguracji, nadmiarowe uprawnienia i brak segmentacji.

Ten case jest mocno zanonimizowany. Nie podajemy nazwy biblioteki, wersji, hostów, nazw procedur, prawdziwych ścieżek ani payloadów deserializacyjnych. Pokazujemy architekturę ryzyka i typowe sygnały, które powinny zainteresować zespół bezpieczeństwa.

Co było w zakresie

scope — application + infra context
[+] aplikacja webowa dostępna z Internetu [+] zwykłe konto testowe [+] analiza konfiguracji dostarczonej w bezpiecznym trybie po potwierdzeniu wstępnego ryzyka [-] brak dostępu produkcyjnego do bazy [-] brak publikacji exploit payloadów # Cel: ocenić, czy błąd w obsłudze sesji może prowadzić do RCE lub eskalacji wpływu.

Początkowo wyglądało to jak standardowy test aplikacji webowej. Dopiero analiza zachowania sesji i nagłówków odpowiedzi pokazała, że aplikacja korzysta z zewnętrznego magazynu sesji i serializuje obiekty po stronie serwera. To jest miejsce, w którym pentester zwalnia i zaczyna rysować przepływ danych.

Sygnały ostrzegawcze w ruchu HTTP

sanitized observations
GET /account HTTP/2 Cookie: app_session=sess_REDACTED HTTP/2 200 OK Set-Cookie: app_session=sess_ROTATED; HttpOnly; Secure; SameSite=Lax X-App-Node: web-02-redacted X-Cache-Session: external-store # Objawy: # - stan użytkownika utrzymuje się między nodami # - rotacja cookie nie zmienia obiektów sesji # - błędy 500 pojawiają się po nietypowych zmianach stanu koszyka/profilu

Nie ma tu „magicznego exploita”. Najpierw trzeba ustalić, gdzie powstaje i gdzie jest odczytywany stan. Jeżeli aplikacja wkłada do sesji złożone obiekty, a potem je odtwarza, pytanie brzmi: jaki serializer, jakie typy, jakie ograniczenia i czy jakikolwiek fragment wejścia użytkownika wpływa na zserializowany stan?

Sekrety i uprawnienia zwiększyły wagę podatności

Po zgłoszeniu wstępnej hipotezy klient udostępnił wycinek konfiguracji w trybie bezpiecznym. Nie chodziło o „szukanie hasła w repo”, tylko o potwierdzenie, czy nawet ograniczona możliwość manipulacji sesją może doprowadzić do wykonania kodu albo dostępu do zasobów wewnętrznych.

redacted configuration excerpt
SessionStore.Provider = ExternalSessionStateProvider SessionStore.Serializer = BinaryObjectSerializer SessionStore.TypeValidation = disabled_or_legacy SessionStore.Connection = store://session-cache-redacted:6379/0 Database.User = app_service_redacted Database.Role = db_owner_like_permissions Feature.LegacyCallbacks = enabled [!] Nazwy, hosty i wartości zastąpione opisami. To nie jest konfiguracja klienta.
Czerwone flagi

Niebezpieczna deserializacja rzadko występuje sama. Groźna robi się wtedy, gdy serializer akceptuje szeroki zestaw typów, aplikacja ma legacy callbacki, a konto serwisowe ma uprawnienia większe niż wymagane do pracy systemu.

Jak potwierdzić ryzyko odpowiedzialnie

Nie publikujemy i nie przekazujemy poza raportem pełnego payloadu. W bezpiecznym PoC chodziło o potwierdzenie kontrolowanego efektu ubocznego, a nie o uruchamianie poleceń systemowych. W praktyce użyliśmy markera, który pozwalał odróżnić zwykły błąd aplikacji od próby odtworzenia nieoczekiwanego typu.

sanitized PoC flow
# Krok 1: przygotowanie stanu sesji przez normalne funkcje aplikacji POST /profile/preferences HTTP/2 Cookie: app_session=sess_REDACTED Content-Type: application/json {"layout":"default","marker":"BSTA_SAFE_MARKER_001"} # Krok 2: wymuszenie ścieżki, która odtwarza obiekt sesji GET /dashboard/widgets HTTP/2 Cookie: app_session=sess_REDACTED HTTP/2 500 Internal Server Error X-Correlation-Id: corr_REDACTED # Log aplikacyjny przekazany klientowi w raporcie: # Deserialization attempted for unexpected type: [REDACTED] # Marker observed in object graph: BSTA_SAFE_MARKER_001

Taki PoC jest wystarczający, aby udowodnić klasę problemu i potrzebę natychmiastowej naprawy, bez publikowania gadget chainów, komend, shelli czy szczegółów biblioteki. Dla klienta przygotowaliśmy osobny, poufny załącznik techniczny z reprodukcją w środowisku testowym.

Dlaczego CVSS poszedł wysoko

attack chain — sanitized
1. Użytkownik wpływa na fragment stanu zapisywanego w sesji 2. Stan trafia do zewnętrznego magazynu sesji 3. Backend odtwarza obiekty bez twardej walidacji typów 4. Legacy callbacks zwiększają powierzchnię skutków ubocznych 5. Konto serwisowe ma nadmiarowe uprawnienia do bazy 6. Brak segmentacji pozwala aplikacji rozmawiać z usługami wewnętrznymi Impact: od DoS i manipulacji stanem do scenariuszy RCE/eskalacji w zależności od środowiska.
Severity: Critical

Nawet jeżeli pełne RCE wymaga dodatkowych warunków, kombinacja niebezpiecznej deserializacji, nadmiarowych uprawnień i sekretów w konfiguracji zasługuje na priorytet krytyczny. To podatność architektoniczna, nie kosmetyka kodu.

RCE rzadko zaczyna się od reverse shell-a.
Częściej zaczyna się od błędnego założenia, że sesja jest zaufana.

Co sprawdzamy w takich projektach

SER

Serializer i typy

Czy deserializacja dopuszcza dowolne typy, legacy bindery, automatyczne resolvery klas albo obiekty z efektami ubocznymi.

MAPOWANIE → CWE-502: Deserialization of Untrusted Data
SEC

Sekrety i konfiguracja

Czy connection stringi, hasła i klucze są w plikach konfiguracyjnych, repozytoriach lub artefaktach deploymentu.

MAPOWANIE → CWE-798 / Secrets Management
IAM

Least privilege

Czy konto aplikacyjne ma tylko niezbędne prawa, czy może tworzyć procedury, wykonywać joby, czytać tabele techniczne albo zarządzać schematem.

MAPOWANIE → Least Privilege / Defense in Depth
NET

Segmentacja

Czy kompromitacja aplikacji daje lateral movement do cache, kolejki, bazy, storage i paneli administracyjnych.

MAPOWANIE → Network Segmentation

Nie wystarczy “zaktualizować paczkę”

1. Wyłącz niebezpieczną deserializację. Używaj bezpiecznych formatów danych, jawnych DTO, allowlist typów i serializerów bez możliwości odtwarzania arbitralnych klas.

2. Odetnij wpływ użytkownika na obiekty sesji. Sesja powinna przechowywać minimalny stan, najlepiej identyfikatory i flagi, a nie rozbudowane grafy obiektów.

3. Odbierz nadmiarowe uprawnienia. Konto aplikacyjne nie powinno mieć praw administracyjnych do bazy ani możliwości wykonywania niepotrzebnych funkcji systemowych.

4. Dodaj detekcję. Loguj wyjątki deserializacji, nietypowe typy, nagłe wzrosty błędów 500 i koreluj je z sesją/użytkownikiem/IP.

detection ideas
alert when: exception.class contains "Deserialization" OR "TypeResolver" OR "SerializationBinder" AND endpoint in [dashboard, profile, cart, session-bound-flow] AND same session triggers > 3 errors / 5 min alert when: session object size grows abnormally OR unexpected type name appears in session telemetry OR service account executes schema-changing queries
◆ BSTA · testpenetracyjny.pl

Masz legacy .NET/Java/PHP i zewnętrzne sesje?

Sprawdzimy, czy mechanizmy sesji, cache, kolejki i serializacji nie tworzą łańcucha prowadzącego do RCE albo eskalacji uprawnień.

Zamów test bezpieczeństwa →
Zakres + wycena w 2 dni robocze · raport techniczny + executive summary · pełna anonimizacja danych