Deserialization
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Podstawowe informacje
Serializacja jest rozumiana jako metoda konwertowania obiektu na format, który można zachować, z zamiarem przechowywania obiektu lub przesyłania go jako część procesu komunikacji. Technika ta jest powszechnie stosowana, aby zapewnić, że obiekt może być odtworzony w późniejszym czasie, zachowując swoją strukturę i stan.
Deserializacja, przeciwnie, jest procesem, który przeciwdziała serializacji. Polega na wzięciu danych, które zostały ustrukturyzowane w określonym formacie i odbudowaniu ich z powrotem w obiekt.
Deserializacja może być niebezpieczna, ponieważ potencjalnie pozwala atakującym manipulować zserializowanymi danymi w celu wykonania szkodliwego kodu lub spowodowania nieoczekiwanego zachowania w aplikacji podczas procesu odbudowy obiektu.
PHP
W PHP podczas procesów serializacji i deserializacji wykorzystywane są specyficzne metody magiczne:
__sleep
: Wywoływana, gdy obiekt jest serializowany. Metoda ta powinna zwracać tablicę nazw wszystkich właściwości obiektu, które powinny być serializowane. Jest powszechnie używana do zatwierdzania oczekujących danych lub wykonywania podobnych zadań porządkowych.__wakeup
: Wywoływana, gdy obiekt jest deserializowany. Używana do przywracania wszelkich połączeń z bazą danych, które mogły zostać utracone podczas serializacji oraz do wykonywania innych zadań ponownej inicjalizacji.__unserialize
: Ta metoda jest wywoływana zamiast__wakeup
(jeśli istnieje) podczas deserializacji obiektu. Daje większą kontrolę nad procesem deserializacji w porównaniu do__wakeup
.__destruct
: Ta metoda jest wywoływana, gdy obiekt ma zostać zniszczony lub gdy skrypt się kończy. Zwykle używana do zadań porządkowych, takich jak zamykanie uchwytów plików lub połączeń z bazą danych.__toString
: Ta metoda pozwala traktować obiekt jako ciąg znaków. Może być używana do odczytu pliku lub innych zadań opartych na wywołaniach funkcji w nim, skutecznie zapewniając tekstową reprezentację obiektu.
Jeśli spojrzysz na wyniki, możesz zobaczyć, że funkcje __wakeup
i __destruct
są wywoływane, gdy obiekt jest deserializowany. Zauważ, że w kilku samouczkach znajdziesz, że funkcja __toString
jest wywoływana, gdy próbujesz wydrukować jakiś atrybut, ale najwyraźniej to już się nie dzieje.
Metoda __unserialize(array $data)
jest wywoływana zamiast __wakeup()
, jeśli jest zaimplementowana w klasie. Umożliwia to deserializację obiektu, dostarczając zserializowane dane jako tablicę. Możesz użyć tej metody do deserializacji właściwości i wykonania wszelkich niezbędnych zadań po deserializacji.
Możesz przeczytać wyjaśniony przykład PHP tutaj: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, tutaj https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf lub tutaj https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
PHP Deserial + Autoload Classes
Możesz nadużyć funkcjonalności autoload PHP, aby załadować dowolne pliki php i więcej:
PHP - Deserialization + Autoload ClassesSerializing Referenced Values
Jeśli z jakiegoś powodu chcesz zserializować wartość jako referencję do innej wartości zserializowanej, możesz:
PHPGGC (ysoserial dla PHP)
PHPGGC może pomóc w generowaniu ładunków do nadużywania deserializacji PHP.
Zauważ, że w wielu przypadkach nie będziesz w stanie znaleźć sposobu na nadużycie deserializacji w kodzie źródłowym aplikacji, ale możesz być w stanie nadużyć kodu zewnętrznych rozszerzeń PHP.
Więc, jeśli możesz, sprawdź phpinfo()
serwera i przeszukaj internet (a nawet gadżety PHPGGC) w poszukiwaniu możliwych gadżetów, które możesz nadużyć.
phar:// deserializacja metadanych
Jeśli znalazłeś LFI, który tylko odczytuje plik i nie wykonuje kodu php w nim, na przykład używając funkcji takich jak file_get_contents(), fopen(), file() lub file_exists(), md5_file(), filemtime() lub filesize(). Możesz spróbować nadużyć deserializacji występującej podczas odczytu pliku za pomocą protokołu phar. Aby uzyskać więcej informacji, przeczytaj następujący post:
phar:// deserializationPython
Pickle
Gdy obiekt zostanie odpakowany, funkcja __reduce__ zostanie wykonana. Gdy zostanie wykorzystana, serwer może zwrócić błąd.
Przed sprawdzeniem techniki obejścia, spróbuj użyć print(base64.b64encode(pickle.dumps(P(),2)))
, aby wygenerować obiekt, który jest zgodny z python2, jeśli używasz python3.
Aby uzyskać więcej informacji na temat ucieczki z pickle jails, sprawdź:
Bypass Python sandboxesYaml & jsonpickle
Następna strona przedstawia technikę wykorzystania niebezpiecznej deserializacji w bibliotekach pythonowych yaml i kończy się narzędziem, które można wykorzystać do generowania ładunków deserializacji RCE dla Pickle, PyYAML, jsonpickle i ruamel.yaml:
Python Yaml DeserializationZanieczyszczenie klas (Python Prototype Pollution)
Class Pollution (Python's Prototype Pollution)NodeJS
Funkcje magiczne JS
JS nie ma "magicznych" funkcji jak PHP czy Python, które będą wykonywane tylko w celu utworzenia obiektu. Ale ma kilka funkcji, które są często używane nawet bez bezpośredniego wywoływania ich, takich jak toString
, valueOf
, toJSON
.
Jeśli wykorzystasz deserializację, możesz skompromentować te funkcje, aby wykonać inny kod (potencjalnie wykorzystując zanieczyszczenie prototypu), możesz wykonać dowolny kod, gdy zostaną wywołane.
Inny "magiczny" sposób na wywołanie funkcji bez bezpośredniego jej wywoływania to skompromentowanie obiektu, który jest zwracany przez funkcję asynchroniczną (obietnica). Ponieważ, jeśli przekształcisz ten obiekt zwracany w inną obietnicę z właściwością o nazwie "then" typu funkcji, zostanie wykonany tylko dlatego, że jest zwracany przez inną obietnicę. Śledź ten link po więcej informacji.
__proto__
i zanieczyszczenie prototype
__proto__
i zanieczyszczenie prototype
Jeśli chcesz nauczyć się o tej technice zobacz następujący samouczek:
NodeJS - __proto__ & prototype PollutionTa biblioteka pozwala na serializację funkcji. Przykład:
Obiekt serializowany będzie wyglądał następująco:
Możesz zobaczyć w przykładzie, że gdy funkcja jest serializowana, flaga _$$ND_FUNC$$_
jest dołączana do obiektu serializowanego.
W pliku node-serialize/lib/serialize.js
możesz znaleźć tę samą flagę i sposób, w jaki kod jej używa.
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F600722126-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJtticLwENZ4i7WwgHiQe%252Fuploads%252Fgit-blob-d89235d198f102c0e6cced327275e3c30748e6b3%252Fimage%2520%28351%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=a675f034&sv=1)
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F600722126-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJtticLwENZ4i7WwgHiQe%252Fuploads%252Fgit-blob-0506854eb1b4acce39194c86afc0b61f096816c7%252Fimage%2520%28446%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=84dc7383&sv=1)
Jak możesz zobaczyć w ostatnim kawałku kodu, jeśli flaga jest znaleziona, używane jest eval
do deserializacji funkcji, więc zasadniczo dane wejściowe użytkownika są używane wewnątrz funkcji eval
.
Jednak samego serializowania funkcji nie wykona, ponieważ konieczne byłoby, aby jakaś część kodu wywoływała y.rce
w naszym przykładzie, a to jest wysoce mało prawdopodobne.
Tak czy inaczej, możesz po prostu zmodyfikować obiekt serializowany, dodając nawiasy, aby automatycznie wykonać serializowaną funkcję, gdy obiekt jest deserializowany.
W następnym kawałku kodu zauważ ostatni nawias i jak funkcja unserialize
automatycznie wykona kod:
Jak wcześniej wskazano, ta biblioteka pobierze kod po _$$ND_FUNC$$_
i wykona go za pomocą eval
. Dlatego, aby automatycznie wykonać kod, możesz usunąć część tworzenia funkcji oraz ostatni nawias i po prostu wykonać jedną linię JS jak w poniższym przykładzie:
Możesz znaleźć tutaj dalsze informacje na temat tego, jak wykorzystać tę lukę.
Ciekawym aspektem funcster jest niedostępność standardowych obiektów wbudowanych; znajdują się one poza dostępnym zakresem. To ograniczenie uniemożliwia wykonanie kodu, który próbuje wywołać metody na obiektach wbudowanych, prowadząc do wyjątków takich jak "ReferenceError: console is not defined"
gdy używane są polecenia takie jak console.log()
lub require(something)
.
Pomimo tego ograniczenia, przywrócenie pełnego dostępu do kontekstu globalnego, w tym wszystkich standardowych obiektów wbudowanych, jest możliwe dzięki specyficznemu podejściu. Wykorzystując kontekst globalny bezpośrednio, można obejść to ograniczenie. Na przykład, dostęp można przywrócić za pomocą następującego fragmentu:
Aby uzyskać więcej informacji, przeczytaj to źródło.
Pakiet serialize-javascript jest zaprojektowany wyłącznie do celów serializacji, nie posiada żadnych wbudowanych możliwości deserializacji. Użytkownicy są odpowiedzialni za wdrożenie własnej metody deserializacji. Bezpośrednie użycie eval
jest sugerowane przez oficjalny przykład do deserializacji danych serializowanych:
Jeśli ta funkcja jest używana do deserializacji obiektów, możesz łatwo to wykorzystać:
Aby uzyskać więcej informacji, przeczytaj to źródło.
Biblioteka Cryo
Na poniższych stronach znajdziesz informacje o tym, jak nadużywać tej biblioteki do wykonywania dowolnych poleceń:
Java - HTTP
W Javie wywołania zwrotne deserializacji są wykonywane podczas procesu deserializacji. To wykonanie może być wykorzystywane przez atakujących, którzy tworzą złośliwe ładunki, które wyzwalają te wywołania zwrotne, prowadząc do potencjalnego wykonania szkodliwych działań.
Odciski palców
Biała skrzynka
Aby zidentyfikować potencjalne luki w serializacji w kodzie, poszukaj:
Klas implementujących interfejs
Serializable
.Użycia funkcji
java.io.ObjectInputStream
,readObject
,readUnshared
.
Zwróć szczególną uwagę na:
XMLDecoder
wykorzystywany z parametrami definiowanymi przez zewnętrznych użytkowników.Metodę
fromXML
wXStream
, szczególnie jeśli wersja XStream jest mniejsza lub równa 1.46, ponieważ jest podatna na problemy z serializacją.ObjectInputStream
połączony z metodąreadObject
.Implementację metod takich jak
readObject
,readObjectNodData
,readResolve
lubreadExternal
.ObjectInputStream.readUnshared
.Ogólne użycie
Serializable
.
Czarna skrzynka
W przypadku testowania czarnej skrzynki, poszukaj specyficznych sygnatur lub "Magic Bytes", które oznaczają obiekty serializowane w Javie (pochodzące z ObjectInputStream
):
Wzór szesnastkowy:
AC ED 00 05
.Wzór Base64:
rO0
.Nagłówki odpowiedzi HTTP z
Content-type
ustawionym naapplication/x-java-serialized-object
.Wzór szesnastkowy wskazujący na wcześniejsze kompresowanie:
1F 8B 08 00
.Wzór Base64 wskazujący na wcześniejsze kompresowanie:
H4sIA
.Pliki internetowe z rozszerzeniem
.faces
i parametremfaces.ViewState
. Odkrycie tych wzorów w aplikacji internetowej powinno skłonić do zbadania, jak opisano w poście o deserializacji Java JSF ViewState.
Sprawdź, czy jest podatny
Jeśli chcesz dowiedzieć się, jak działa exploit deserializacji w Javie, powinieneś zapoznać się z Podstawową deserializacją Javy, Deserializacją DNS w Javie oraz Ładunkiem CommonsCollection1.
Test białej skrzynki
Możesz sprawdzić, czy zainstalowana jest jakakolwiek aplikacja z znanymi podatnościami.
Możesz spróbować sprawdzić wszystkie biblioteki, które są znane jako podatne i dla których Ysoserial może dostarczyć exploit. Możesz również sprawdzić biblioteki wskazane na Java-Deserialization-Cheat-Sheet. Możesz także użyć gadgetinspector, aby wyszukać możliwe łańcuchy gadgetów, które można wykorzystać. Podczas uruchamiania gadgetinspector (po zbudowaniu) nie przejmuj się mnóstwem ostrzeżeń/błędów, przez które przechodzi, i pozwól mu zakończyć. Zapisze wszystkie wyniki w gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Proszę zauważyć, że gadgetinspector nie stworzy exploita i może wskazywać fałszywe pozytywy.
Test Black Box
Używając rozszerzenia Burp gadgetprobe, możesz zidentyfikować które biblioteki są dostępne (a nawet ich wersje). Z tą informacją może być łatwiej wybrać ładunek do wykorzystania podatności.
Przeczytaj to, aby dowiedzieć się więcej o GadgetProbe.
GadgetProbe koncentruje się na deserializacjach ObjectInputStream
.
Używając rozszerzenia Burp Java Deserialization Scanner, możesz zidentyfikować podatne biblioteki możliwe do wykorzystania z ysoserial i wykorzystać je.
Przeczytaj to, aby dowiedzieć się więcej o Java Deserialization Scanner.
Java Deserialization Scanner koncentruje się na deserializacjach ObjectInputStream
.
Możesz także użyć Freddy, aby wykryć podatności deserializacji w Burp. Ten plugin wykryje nie tylko podatności związane z ObjectInputStream
, ale także podatności z bibliotek deserializacji Json i Yml. W trybie aktywnym spróbuje je potwierdzić, używając ładunków sleep lub DNS.
Możesz znaleźć więcej informacji o Freddy tutaj.
Test Serializacji
Nie wszystko polega na sprawdzaniu, czy jakakolwiek podatna biblioteka jest używana przez serwer. Czasami możesz być w stanie zmienić dane wewnątrz zserializowanego obiektu i obejść niektóre kontrole (może przyznać ci uprawnienia administratora w aplikacji webowej). Jeśli znajdziesz zserializowany obiekt java wysyłany do aplikacji webowej, możesz użyć SerializationDumper, aby wydrukować w bardziej czytelny sposób zserializowany obiekt, który jest wysyłany. Wiedząc, jakie dane wysyłasz, łatwiej będzie je zmodyfikować i obejść niektóre kontrole.
Exploity
ysoserial
Głównym narzędziem do wykorzystywania deserializacji Java jest ysoserial (pobierz tutaj). Możesz także rozważyć użycie ysoseral-modified, które pozwoli ci używać złożonych poleceń (na przykład z użyciem pipe'ów).
Zauważ, że to narzędzie jest skoncentrowane na wykorzystywaniu ObjectInputStream
.
Zalecałbym rozpoczęcie od ładunku "URLDNS" przed ładunkiem RCE, aby sprawdzić, czy wstrzyknięcie jest możliwe. Tak czy inaczej, zauważ, że może ładunek "URLDNS" nie działa, ale inny ładunek RCE może działać.
Kiedy tworzysz ładunek dla java.lang.Runtime.exec(), nie możesz używać znaków specjalnych takich jak ">" lub "|" do przekierowania wyjścia z wykonania, "$()" do wykonywania poleceń, ani nawet przekazywać argumentów do polecenia oddzielonych spacjami (możesz zrobić echo -n "hello world"
, ale nie możesz zrobić python2 -c 'print "Hello world"'
). Aby poprawnie zakodować ładunek, możesz użyć tej strony.
Czuj się swobodnie, aby użyć następnego skryptu do stworzenia wszystkich możliwych ładunków wykonania kodu dla Windows i Linux, a następnie przetestować je na podatnej stronie internetowej:
serialkillerbypassgadgets
Możesz użyć https://github.com/pwntester/SerialKillerBypassGadgetCollection razem z ysoserial, aby stworzyć więcej exploitów. Więcej informacji na temat tego narzędzia znajduje się w prezentacji, w której narzędzie zostało zaprezentowane: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1
marshalsec
marshalsec może być używane do generowania ładunków do eksploatacji różnych Json i Yml bibliotek serializacji w Javie.
Aby skompilować projekt, musiałem dodać te zależności do pom.xml
:
Zainstaluj maven, a następnie skompiluj projekt:
FastJSON
Przeczytaj więcej o tej bibliotece Java JSON: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html
Labs
Jeśli chcesz przetestować kilka ładunków ysoserial, możesz uruchomić tę aplikację webową: https://github.com/hvqzao/java-deserialize-webapp
Why
Java używa dużo serializacji do różnych celów, takich jak:
Żądania HTTP: Serializacja jest szeroko stosowana w zarządzaniu parametrami, ViewState, ciasteczkami itp.
RMI (Remote Method Invocation): Protokół Java RMI, który w całości opiera się na serializacji, jest fundamentem komunikacji zdalnej w aplikacjach Java.
RMI przez HTTP: Ta metoda jest powszechnie używana przez aplikacje webowe oparte na Java, wykorzystując serializację do wszystkich komunikacji obiektów.
JMX (Java Management Extensions): JMX wykorzystuje serializację do przesyłania obiektów przez sieć.
Protokóły niestandardowe: W Javie standardową praktyką jest przesyłanie surowych obiektów Java, co zostanie zaprezentowane w nadchodzących przykładach exploitów.
Prevention
Obiekty transientne
Klasa, która implementuje Serializable
, może oznaczyć jako transient
każdy obiekt wewnątrz klasy, który nie powinien być serializowany. Na przykład:
Unikaj serializacji klasy, która musi implementować Serializable
W scenariuszach, w których niektóre obiekty muszą implementować interfejs Serializable
z powodu hierarchii klas, istnieje ryzyko niezamierzonej deserializacji. Aby temu zapobiec, upewnij się, że te obiekty są nie-deserializowalne, definiując final
metodę readObject()
, która zawsze rzuca wyjątek, jak pokazano poniżej:
Zwiększanie bezpieczeństwa deserializacji w Javie
Dostosowanie java.io.ObjectInputStream
to praktyczne podejście do zabezpieczania procesów deserializacji. Metoda ta jest odpowiednia, gdy:
Kod deserializacji jest pod twoją kontrolą.
Klasy oczekiwane do deserializacji są znane.
Nadpisz metodę resolveClass()
, aby ograniczyć deserializację tylko do dozwolonych klas. Zapobiega to deserializacji jakiejkolwiek klasy, z wyjątkiem tych wyraźnie dozwolonych, jak w poniższym przykładzie, który ogranicza deserializację tylko do klasy Bicycle
:
Używanie agenta Java do zwiększenia bezpieczeństwa oferuje rozwiązanie awaryjne, gdy modyfikacja kodu nie jest możliwa. Metoda ta dotyczy głównie czarnej listy szkodliwych klas, przy użyciu parametru JVM:
Zapewnia sposób na dynamiczne zabezpieczenie deserializacji, idealny dla środowisk, w których natychmiastowe zmiany w kodzie są niepraktyczne.
Sprawdź przykład w rO0 by Contrast Security
Implementacja filtrów serializacji: Java 9 wprowadziła filtry serializacji za pomocą interfejsu ObjectInputFilter
, co zapewnia potężny mechanizm do określania kryteriów, które obiekty serializowane muszą spełniać przed deserializacją. Filtry te mogą być stosowane globalnie lub na poziomie strumienia, oferując szczegółową kontrolę nad procesem deserializacji.
Aby skorzystać z filtrów serializacji, możesz ustawić filtr globalny, który stosuje się do wszystkich operacji deserializacji lub skonfigurować go dynamicznie dla konkretnych strumieni. Na przykład:
Wykorzystanie zewnętrznych bibliotek dla zwiększonego bezpieczeństwa: Biblioteki takie jak NotSoSerial, jdeserialize i Kryo oferują zaawansowane funkcje do kontrolowania i monitorowania deserializacji w Javie. Te biblioteki mogą zapewnić dodatkowe warstwy bezpieczeństwa, takie jak białe lub czarne listy klas, analizowanie obiektów serializowanych przed deserializacją oraz wdrażanie niestandardowych strategii serializacji.
NotSoSerial przechwytuje procesy deserializacji, aby zapobiec wykonaniu nieufnego kodu.
jdeserialize umożliwia analizę serializowanych obiektów Java bez ich deserializacji, co pomaga w identyfikacji potencjalnie złośliwej zawartości.
Kryo to alternatywna ramka do serializacji, która kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serializacji, które mogą zwiększyć bezpieczeństwo.
Odniesienia
Deserializacja i prezentacja ysoserial: http://frohoff.github.io/appseccali-marshalling-pickles/
Prezentacja o gadgetinspector: https://www.youtube.com/watch?v=wPbW6zQ52w8 oraz slajdy: https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf
Artykuł Marshalsec: https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true
Artykuł o deserializacji Java i .Net JSON: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf, prezentacja: https://www.youtube.com/watch?v=oUAeWhW5b8c oraz slajdy: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf
CVE deserializacji: https://paper.seebug.org/123/
Wstrzykiwanie JNDI i log4Shell
Znajdź, czym jest Wstrzykiwanie JNDI, jak je wykorzystać za pomocą RMI, CORBA i LDAP oraz jak wykorzystać log4shell (i przykład tej podatności) na następującej stronie:
JNDI - Java Naming and Directory Interface & Log4ShellJMS - Java Message Service
API Java Message Service (JMS) to API middleware oparte na wiadomościach w Javie, służące do wysyłania wiadomości między dwoma lub więcej klientami. Jest to implementacja do rozwiązania problemu producenta i konsumenta. JMS jest częścią platformy Java Platform, Enterprise Edition (Java EE) i została zdefiniowana przez specyfikację opracowaną w Sun Microsystems, ale od tego czasu była kierowana przez Java Community Process. Jest to standard komunikacji, który pozwala komponentom aplikacji opartym na Java EE tworzyć, wysyłać, odbierać i odczytywać wiadomości. Umożliwia to luźne powiązanie, niezawodną i asynchroniczną komunikację między różnymi komponentami rozproszonej aplikacji. (Z Wikipedia).
Produkty
Istnieje kilka produktów wykorzystujących to middleware do wysyłania wiadomości:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F600722126-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJtticLwENZ4i7WwgHiQe%252Fuploads%252Fgit-blob-b3e1a62dbca112b44bc5a3562a23bd41339330a3%252Fimage%2520%28314%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=ec345c0c&sv=1)
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F600722126-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJtticLwENZ4i7WwgHiQe%252Fuploads%252Fgit-blob-7243a6f1e63ed244c00d065975469904da99aad6%252Fimage%2520%281056%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=5deae836&sv=1)
Wykorzystanie
Tak więc, zasadniczo istnieje wiele usług korzystających z JMS w niebezpieczny sposób. Dlatego, jeśli masz wystarczające uprawnienia do wysyłania wiadomości do tych usług (zazwyczaj będziesz potrzebować ważnych poświadczeń), możesz być w stanie wysłać złośliwe obiekty serializowane, które będą deserializowane przez konsumenta/subskrybenta. Oznacza to, że w tym wykorzystaniu wszystkie klienty, które będą korzystać z tej wiadomości, zostaną zainfekowane.
Powinieneś pamiętać, że nawet jeśli usługa jest podatna (ponieważ niebezpiecznie deserializuje dane wejściowe użytkownika), nadal musisz znaleźć ważne gadżety, aby wykorzystać tę podatność.
Narzędzie JMET zostało stworzone, aby połączyć się i zaatakować te usługi, wysyłając kilka złośliwych obiektów serializowanych przy użyciu znanych gadżetów. Te exploity będą działać, jeśli usługa nadal będzie podatna i jeśli którykolwiek z używanych gadżetów znajduje się w podatnej aplikacji.
Odniesienia
Prezentacja JMET: https://www.youtube.com/watch?v=0h8DWiOWGGA
.Net
W kontekście .Net, exploity deserializacji działają w sposób podobny do tych w Javie, gdzie gadżety są wykorzystywane do uruchamiania określonego kodu podczas deserializacji obiektu.
Odcisk palca
WhiteBox
Kod źródłowy powinien być sprawdzany pod kątem wystąpień:
TypeNameHandling
JavaScriptTypeResolver
Skup się na serializerach, które pozwalają na określenie typu przez zmienną pod kontrolą użytkownika.
BlackBox
Poszukiwania powinny koncentrować się na zakodowanym w Base64 ciągu AAEAAAD///// lub jakimkolwiek podobnym wzorze, który może być deserializowany po stronie serwera, dając kontrolę nad typem, który ma być deserializowany. Może to obejmować, ale nie ogranicza się do, struktur JSON lub XML zawierających TypeObject
lub $type
.
ysoserial.net
W tym przypadku możesz użyć narzędzia ysoserial.net, aby tworzyć exploity deserializacji. Po pobraniu repozytorium git powinieneś skompilować narzędzie na przykład za pomocą Visual Studio.
Jeśli chcesz dowiedzieć się, jak ysoserial.net tworzy swoje exploity, możesz sprawdzić tę stronę, na której wyjaśniono gadżet ObjectDataProvider + ExpandedWrapper + Json.Net formatter.
Główne opcje ysoserial.net to: --gadget
, --formatter
, --output
i --plugin
.
--gadget
używane do wskazania gadżetu do wykorzystania (wskazuje klasę/funkcję, która będzie wykorzystywana podczas deserializacji do wykonania poleceń).--formatter
, używane do wskazania metody do serializacji exploita (musisz wiedzieć, która biblioteka jest używana w backendzie do deserializacji ładunku i użyć tej samej do jego serializacji).--output
używane do wskazania, czy chcesz, aby exploit był w formacie raw czy base64. Zauważ, że ysoserial.net będzie kodować ładunek używając UTF-16LE (domyślne kodowanie w systemie Windows), więc jeśli pobierzesz wersję raw i po prostu zakodujesz ją z konsoli linuxowej, możesz napotkać problemy z kompatybilnością kodowania, które uniemożliwią poprawne działanie exploita (w przypadku HTB JSON box ładunek działał zarówno w UTF-16LE, jak i ASCII, ale to nie oznacza, że zawsze będzie działać).--plugin
ysoserial.net obsługuje wtyczki do tworzenia exploitów dla konkretnych frameworków jak ViewState.
Więcej parametrów ysoserial.net
--minify
dostarczy mniejszy ładunek (jeśli to możliwe)--raf -f Json.Net -c "anything"
To wskaże wszystkie gadżety, które mogą być używane z podanym formatterem (Json.Net
w tym przypadku)--sf xml
możesz wskazać gadżet (-g
), a ysoserial.net będzie szukać formatterów zawierających "xml" (niezależnie od wielkości liter)
Przykłady ysoserial do tworzenia exploitów:
ysoserial.net ma również bardzo interesujący parametr, który pomaga lepiej zrozumieć, jak działa każdy exploit: --test
Jeśli wskażesz ten parametr, ysoserial.net spróbuje eksploatacji lokalnie, abyś mógł przetestować, czy twój ładunek zadziała poprawnie.
Ten parametr jest pomocny, ponieważ jeśli przejrzysz kod, znajdziesz fragmenty kodu takie jak ten (z ObjectDataProviderGenerator.cs):
To oznacza, że aby przetestować exploit, kod wywoła serializersHelper.JsonNet_deserialize
W poprzednim kodzie występuje luka w zabezpieczeniach, która została stworzona. Jeśli znajdziesz coś podobnego w aplikacji .Net, oznacza to, że prawdopodobnie ta aplikacja również jest podatna.
Dlatego parametr --test
pozwala nam zrozumieć które fragmenty kodu są podatne na exploit deserializacji, który ysoserial.net może stworzyć.
ViewState
Zobacz ten POST o tym, jak spróbować wykorzystać parametr __ViewState w .Net, aby wykonać dowolny kod. Jeśli już znasz sekrety używane przez maszynę ofiary, przeczytaj ten post, aby dowiedzieć się, jak wykonać kod.
Zapobieganie
Aby zminimalizować ryzyko związane z deserializacją w .Net:
Unikaj pozwalania strumieniom danych na definiowanie swoich typów obiektów. Wykorzystuj
DataContractSerializer
lubXmlSerializer
, gdy to możliwe.Dla
JSON.Net
, ustawTypeNameHandling
naNone
: %%%TypeNameHandling = TypeNameHandling.None%%%Unikaj używania
JavaScriptSerializer
zJavaScriptTypeResolver
.Ogranicz typy, które mogą być deserializowane, rozumiejąc inherentne ryzyko związane z typami .Net, takimi jak
System.IO.FileInfo
, które mogą modyfikować właściwości plików serwera, co potencjalnie prowadzi do ataków typu denial of service.Bądź ostrożny z typami mającymi ryzykowne właściwości, jak
System.ComponentModel.DataAnnotations.ValidationException
z jego właściwościąValue
, która może być wykorzystana.Bezpiecznie kontroluj instancjonowanie typów, aby zapobiec wpływowi atakujących na proces deserializacji, co sprawia, że nawet
DataContractSerializer
lubXmlSerializer
mogą być podatne.Wdrażaj kontrole białej listy przy użyciu niestandardowego
SerializationBinder
dlaBinaryFormatter
iJSON.Net
.Bądź na bieżąco z znanymi niebezpiecznymi gadżetami deserializacji w .Net i upewnij się, że deserializatory nie instancjonują takich typów.
Izoluj potencjalnie ryzykowny kod od kodu z dostępem do internetu, aby uniknąć narażenia znanych gadżetów, takich jak
System.Windows.Data.ObjectDataProvider
w aplikacjach WPF, na niezaufane źródła danych.
Referencje
Artykuł o deserializacji JSON w Javie i .Net: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf, wykład: https://www.youtube.com/watch?v=oUAeWhW5b8c i slajdy: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf
Ruby
W Ruby, serializacja jest ułatwiana przez dwie metody w bibliotece marshal. Pierwsza metoda, znana jako dump, jest używana do przekształcania obiektu w strumień bajtów. Proces ten nazywa się serializacją. Z kolei druga metoda, load, jest stosowana do przywracania strumienia bajtów z powrotem do obiektu, co nazywa się deserializacją.
Aby zabezpieczyć zserializowane obiekty, Ruby wykorzystuje HMAC (Hash-Based Message Authentication Code), zapewniając integralność i autentyczność danych. Klucz używany do tego celu jest przechowywany w jednym z kilku możliwych miejsc:
config/environment.rb
config/initializers/secret_token.rb
config/secrets.yml
/proc/self/environ
Ogólna deserializacja Ruby 2.X do łańcucha gadżetów RCE (więcej informacji w https://www.elttam.com/blog/ruby-deserialization/):
Inne łańcuchy RCE do wykorzystania w Ruby On Rails: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/
Metoda Ruby .send()
Jak wyjaśniono w tym raporcie o podatności, jeśli nieprzetworzony input od użytkownika dotrze do metody .send()
obiektu ruby, ta metoda pozwala na wywołanie dowolnej innej metody obiektu z dowolnymi parametrami.
Na przykład, wywołanie eval, a następnie kodu ruby jako drugiego parametru pozwoli na wykonanie dowolnego kodu:
Ponadto, jeśli tylko jeden parametr .send()
jest kontrolowany przez atakującego, jak wspomniano w poprzednim opisie, możliwe jest wywołanie dowolnej metody obiektu, która nie potrzebuje argumentów lub której argumenty mają wartości domyślne.
W tym celu można enumerować wszystkie metody obiektu, aby znaleźć interesujące metody, które spełniają te wymagania.
Inne biblioteki
Ta technika została wzięta z tego wpisu na blogu.
Istnieją inne biblioteki Ruby, które mogą być używane do serializacji obiektów i które mogą być nadużywane w celu uzyskania RCE podczas niebezpiecznej deserializacji. Poniższa tabela pokazuje niektóre z tych bibliotek oraz metodę, którą wywołuje załadowana biblioteka, gdy jest deserializowana (funkcja do nadużycia w celu uzyskania RCE w zasadzie):
Biblioteka | Dane wejściowe | Metoda uruchamiająca wewnątrz klasy |
Marshal (Ruby) | Binary |
|
Oj | JSON |
|
Ox | XML |
|
Psych (Ruby) | YAML |
|
JSON (Ruby) | JSON |
|
Podstawowy przykład:
W przypadku próby nadużycia Oj, możliwe było znalezienie klasy gadget, która wewnątrz swojej funkcji hash
wywoła to_s
, co wywoła spec, które wywoła fetch_path, co było możliwe do zrobienia, aby pobrać losowy URL, co stanowi doskonały detektor tego rodzaju nieoczyszczonych podatności na deserializację.
Ponadto stwierdzono, że przy użyciu poprzedniej techniki w systemie tworzony jest również folder, co jest wymagane do wykorzystania innego gadżetu w celu przekształcenia tego w pełne RCE z czymś takim jak:
Sprawdź więcej szczegółów w oryginalnym poście.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Last updated