Deserialization
Last updated
Last updated
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)
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.
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. Służy 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 jest 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/
Możesz nadużyć funkcjonalności autoload PHP, aby załadować dowolne pliki php i więcej:
PHP - Deserialization + Autoload ClassesJeśli z jakiegoś powodu chcesz zserializować wartość jako referencję do innej wartości zserializowanej, możesz:
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ć.
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:// deserializationGdy 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 sandboxesNastę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 DeserializationJS nie ma "magicznych" funkcji jak PHP czy Python, które są 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 są one wywoływane.
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 funkcja, zostanie on wykonany tylko dlatego, że jest zwracany przez inną obietnicę. Śledź ten link po więcej informacji.
__proto__
i zanieczyszczenie prototype
Jeśli chcesz dowiedzieć się więcej na temat tej techniki 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.
Jak możesz zobaczyć w ostatnim kawałku kodu, jeśli flaga zostanie 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, co jest bardzo mało prawdopodobne.
Tak czy inaczej, możesz po prostu zmodyfikować obiekt serializowany, dodając nawiasy, aby automatycznie wykonać serializowaną funkcję, gdy obiekt zostanie 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"
podczas używania poleceń takich 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.
Na poniższych stronach znajdziesz informacje o tym, jak nadużywać tej biblioteki do wykonywania dowolnych poleceń:
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ń.
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
w XStream
, szczególnie jeśli wersja XStream jest mniejsza lub równa 1.46, ponieważ jest podatna na problemy z serializacją.
ObjectInputStream
w połączeniu z metodą readObject
.
Implementację metod takich jak readObject
, readObjectNodData
, readResolve
lub readExternal
.
ObjectInputStream.readUnshared
.
Ogólne użycie Serializable
.
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 na application/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 parametrem faces.ViewState
. Odkrycie tych wzorów w aplikacji internetowej powinno skłonić do zbadania, jak opisano w poście o deserializacji Java JSF ViewState.
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.
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.
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.
Głównym narzędziem do eksploatacji 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 potoków).
Zauważ, że to narzędzie jest skoncentrowane na eksploatacji ObjectInputStream
.
Zacząłbym od użycia ł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.
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:
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 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:
Przeczytaj więcej o tej bibliotece Java JSON: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html
Jeśli chcesz przetestować kilka ładunków ysoserial, możesz uruchomić tę aplikację webową: https://github.com/hvqzao/java-deserialize-webapp
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ół RMI w Javie, 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 Javie, wykorzystując serializację do wszystkich komunikacji obiektów.
JMX (Java Management Extensions): JMX wykorzystuje serializację do przesyłania obiektów przez sieć.
Niestandardowe protokoły: W Javie standardową praktyką jest przesyłanie surowych obiektów Java, co zostanie zaprezentowane w nadchodzących przykładach exploitów.
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:
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:
Dostosowanie java.io.ObjectInputStream
to praktyczne podejście do zabezpieczania procesów deserializacji. Ta metoda 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 i 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 platforma do serializacji, która kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serializacji, które mogą zwiększyć bezpieczeństwo.
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 JSON w Javie i .Net: 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 dotyczące deserializacji: https://paper.seebug.org/123/
Znajdź, czym jest Wstrzykiwanie JNDI, jak je wykorzystać za pomocą RMI, CORBA i LDAP oraz jak wykorzystać log4shell (i przykład tej luki) na poniższej stronie:
JNDI - Java Naming and Directory Interface & Log4ShellAPI 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-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).
Istnieje kilka produktów wykorzystujących to middleware do wysyłania wiadomości:
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 od użytkownika), nadal musisz znaleźć ważne gadżety, aby wykorzystać lukę.
Narzędzie JMET zostało stworzone, aby łączyć się i atakować 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 jakikolwiek z użytych gadżetów znajduje się w podatnej aplikacji.
Prezentacja JMET: https://www.youtube.com/watch?v=0h8DWiOWGGA
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.
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.
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
.
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 + formatter Json.Net.
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 Windows), więc jeśli pobierzesz raw i po prostu zakodujesz go 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
--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ć.
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.
Aby zminimalizować ryzyko związane z deserializacją w .Net:
Unikaj pozwalania strumieniom danych na definiowanie swoich typów obiektów. Wykorzystuj DataContractSerializer
lub XmlSerializer
, gdy to możliwe.
Dla JSON.Net
, ustaw TypeNameHandling
na None
: %%%TypeNameHandling = TypeNameHandling.None%%%
Unikaj używania JavaScriptSerializer
z JavaScriptTypeResolver
.
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 na serwerze, 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
lub XmlSerializer
mogą być podatne.
Wdrażaj kontrole białej listy przy użyciu niestandardowego SerializationBinder
dla BinaryFormatter
i JSON.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.
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
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/
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 wyenumerować wszystkie metody obiektu, aby znaleźć interesujące metody, które spełniają te wymagania.
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):
Biblioteka
Dane wejściowe
Metoda uruchamiająca wewnątrz klasy
Marshal (Ruby)
Binarny
_load
Oj
JSON
hash
(klasa musi być umieszczona w hash(map) jako klucz)
Ox
XML
hash
(klasa musi być umieszczona w hash(map) jako klucz)
Psych (Ruby)
YAML
hash
(klasa musi być umieszczona w hash(map) jako klucz)
init_with
JSON (Ruby)
JSON
json_create
([zobacz notatki dotyczące json_create na końcu](#table-vulnerable-sinks))
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 zrealizowania, 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)