wprowadzenie¶
Ten artykuł koncentruje się na dostarczaniu jasnych, praktycznych wskazówek dotyczących bezpiecznego deserializacji niezaufanych danych w aplikacjach.
czym jest Deserializacja¶
serializacja to proces przekształcania jakiegoś obiektu w format danych, który można później przywrócić. Ludzie często serializują obiekty, aby zapisać je do przechowywania lub wysłać jako część komunikacji.,
Deserializacja jest odwrotnością tego procesu, pobierając dane ustrukturyzowane z jakiegoś formatu i przekształcając je w obiekt. Obecnie najpopularniejszym formatem danych do serializacji danych jest JSON. Wcześniej był to XML.
jednak wiele języków programowania oferuje natywne możliwości serializacji obiektów. Te natywne formaty zwykle oferują więcej funkcji niż JSON lub XML, w tym możliwość dostosowania procesu serializacji.
Niestety, funkcje tych natywnych mechanizmów deserializacji mogą zostać zmienione pod kątem złośliwego działania podczas pracy na niezaufanych danych., Stwierdzono, że ataki na deserializery umożliwiają ataki typu odmowa usługi, Kontrola dostępu i zdalne wykonywanie kodu (RCE).
Wskazówki dotyczące bezpiecznego deserializacji obiektów¶
poniższe wskazówki dotyczące języka próbują wyliczyć bezpieczne metody deserializacji danych, którym nie można ufać.
PHP¶
przegląd Whiteboxów¶
Sprawdź użycie funkcji unserialize() i sprawdź, jak parametry zewnętrzne są akceptowane., Użyj bezpiecznego, standardowego formatu wymiany danych, takiego jak JSON (poprzez json_decode()
I json_encode()
), jeśli chcesz przekazać użytkownikowi serializowane dane.
Python¶
Blackbox Review¶
Jeśli dane o ruchu zawierają symbol kropki.
na końcu, jest bardzo prawdopodobne, że dane zostały wysłane w serializacji.
przegląd Whiteboxa¶
poniższe API w Pythonie będzie podatne na atak serializacji. Wyszukaj kod poniższego wzoru.,
- zastosowania
pickle/c_pickle/_pickle
zload/loads
:
import pickledata = """ cos.system(S'dir')tR. """pickle.loads(data)
- zastosowania
PyYAML
zload
:
import yamldocument = "!!python/object/apply:os.system "print(yaml.load(document))
- używa
jsonpickle
zencode
lubstore
Java¶
poniższe techniki są dobre do zapobiegania atakom deserializacji na format Serializowalny Javy.,
Porady dotyczące implementacji:
- w kodzie Nadpisz metodę
ObjectInputStream#resolveClass()
, aby zapobiec deserializacji dowolnych klas. To bezpieczne zachowanie może być zawinięte w bibliotekę taką jak SerialKiller. - użyj bezpiecznego zamiennika metody generycznej
readObject()
, jak pokazano tutaj. Zauważ, że dotyczy to ataków typu „billion laughs”, sprawdzając długość wejścia i liczbę deserializowanych obiektów.
przegląd Whiteboxa¶
należy pamiętać o następujących zastosowaniach Java API do potencjalnej luki w serializacji.,
XMLdecoder
with external user defined parameters
XStream
with fromXML
method (xstream version <= v1.46 is vulnerable to the serialization issue)
ObjectInputStream
with readObject
4.,rns może sugerować, że dane zostały wysłane w strumieniach serializacji Java
-
AC ED 00 05
W Hex -
Content-type
nagłówek odpowiedzi HTTP ustawiony naapplication/x-java-serialized-object
rO0
w Base64
zapobieganie wyciekom danych i zatykaniu zaufanych pól¶
jeśli istnieją elementy danych obiektu, które nigdy nie powinny być kontrolowane przez użytkowników końcowych podczas deserializacji lub narażone na użytkowników podczas serializacji, należy je zadeklarować jako słowo kluczowe transient
(sekcja ochrona poufnych informacji).,
dla klasy zdefiniowanej jako Serializowalna, zmienna informacji wrażliwych powinna być zadeklarowana jakoprivate transient
.
na przykład, klasa myAccount, zmienna 'profit' i 'margin' zostały zadeklarowane jako przejściowe, aby uniknąć serializacji:
public class myAccount implements Serializable{ private transient double profit; // declared transient private transient double margin; // declared transient ....
zapobiegają deserializacji obiektów domeny¶
niektóre obiekty aplikacji mogą być zmuszone do implementacji Serializowalnej ze względu na ich hierarchię., Aby zagwarantować, że obiekty aplikacji nie mogą zostać deserializowane, należy zadeklarować metodę readObject()
(z modyfikatorem final
), która zawsze wyświetla wyjątek:
utwardzaj swój własny obiekt java.io.ObjectInputStream¶
java.io.ObjectInputStream
div > class służy do deserializacji obiektów. Możliwe jest utwardzenie jego zachowania przez podklasę., Jest to najlepsze rozwiązanie, jeśli:
- możesz zmienić kod, który deserializuje
- wiesz, jakie klasy oczekujesz deserializacji
ogólna idea polega na nadpisaniuObjectInputStream.html#resolveClass()
w celu ograniczenia, które klasy mogą być deserializowane.
ponieważ to wywołanie dzieje się przed wywołaniem readObject()
, możesz być pewien, że nie wystąpi żadna aktywność deserializacyjna, chyba że typ jest taki, na który chcesz zezwolić.,
prosty przykład tego pokazany tutaj, gdzie Klasa LookAheadObjectInputStream
gwarantuje, że nie deserializuje żadnego innego typu poza klasą Bicycle
:
bardziej kompletne implementacje tego podejścia zostały zaproponowane przez różnych członków społeczności:
- NibbleSec – biblioteka, która pozwala na Czarna lista klas, które mogą być deserializowane
- IBM – przełomowa Ochrona, napisana wiele lat przed stworzeniem najbardziej niszczycielskich scenariuszy eksploatacji.,
- klasy IO Apache Commons
utwardzają wszystkie użycie java.io.ObjectInputStream za pomocą agenta¶
jak wspomniano powyżej, Klasa java.io.ObjectInputStream
jest używana do deserializacji obiektów. Możliwe jest utwardzenie jego zachowania przez podklasę. Jeśli jednak nie posiadasz kodu lub nie możesz czekać na łatkę, najlepszym rozwiązaniem jest użycie agenta do splotu w utwardzaniu do java.io.ObjectInputStream
.,
globalna zmianaObjectInputStream
jest Bezpieczna tylko dla znanych złośliwych typów z czarnej listy, ponieważ nie jest możliwe poznanie dla wszystkich aplikacji, jakie mają być deserializowane klasy. Na szczęście na czarnej liście jest bardzo niewiele klas potrzebnych do ochrony przed wszystkimi znanymi wektorami ataku.
to nieuniknione, że więcej „gadżetów” klasy zostaną odkryte, które mogą być nadużywane. Jednak obecnie istnieje niesamowita ilość podatnego oprogramowania, które potrzebuje poprawki., W niektórych przypadkach „naprawienie” luki może obejmować przebudowę systemów przesyłania wiadomości i złamanie wstecznej kompatybilności, gdy deweloperzy zmierzają w kierunku nieakceptowania serializowanych obiektów.
aby włączyć tych agentów, po prostu dodaj nowy parametr JVM:
-javaagent:name-of-agent.jar
agenci stosujący to podejście zostali zwolnieni przez różnych członków społeczności:
- Ro0 przez kontrast zabezpieczenia
podobne, ale mniej skalowalne podejście byłoby ręczne łatanie i bootstrap JVM ' s objectinputstream. Wskazówki dotyczące tego podejścia są dostępne tutaj.
.,Net CSharp¶
WHITEBOX Review¶
Wyszukaj kod źródłowy dla następujących terminów:
TypeNameHandling
JavaScriptTypeResolver
poszukaj dowolnych serializatorów, w których typ jest ustawiany przez zmienną sterowaną przez użytkownika.,
przegląd BlackBox¶
wyszukaj następującą zakodowaną zawartość base64 zaczynającą się od:
AAEAAAD/////
wyszukaj zawartość o następującym tekście:
TypeObject
$type:
ogólne środki ostrożności¶
nie zezwalaj na definiowanie przez strumień danych typu obiektu, do którego strumień będzie deserializowany. Możesz temu zapobiec, na przykład używając DataContractSerializer
lub XmlSerializer
, jeśli to w ogóle możliwe.,
GdzieJSON.Net
jest używany upewnij się, że TypeNameHandling
jest ustawiony tylko na None
.
TypeNameHandling = TypeNameHandling.None
JeśliJavaScriptSerializer
ma być używany, nie należy go używać zJavaScriptTypeResolver
.
Jeśli musisz deserializować strumienie danych definiujące ich własny typ, ogranicz typy, które mogą być deserializowane. Należy mieć świadomość, że jest to nadal ryzykowne, ponieważ wiele natywnych typów. Net potencjalnie niebezpieczne same w sobie. np.,
System.IO.FileInfo
FileInfo
obiekty, które odwołują się do plików na serwerze, mogą po deserializacji zmienić właściwości tych plików, np. na tylko do odczytu, tworząc potencjalny atak typu denial of service.
nawet jeśli ograniczyłeś typy, które mogą być deserializowane, pamiętaj, że niektóre typy mają właściwości, które są ryzykowne. System.ComponentModel.DataAnnotations.ValidationException
, na przykład ma właściwość Value
typu Object
., jeśli ten typ jest typem dozwolonym do deserializacji, atakujący może ustawić właściwość Value
na dowolny typ obiektu, który wybierze.
należy uniemożliwić atakującym kierowanie typem, który zostanie utworzony. Jeśli jest to możliwe, nawetDataContractSerializer
lubXmlSerializer
można wywrócić, np.
// Action below is dangerous if the attacker can change the data in the databasevar typename = GetTransactionTypeFromDatabase();var serializer = new DataContractJsonSerializer(Type.GetType(typename));var obj = serializer.ReadObject(ms);
wykonanie może wystąpić w niektórych typach.Net podczas deserializacji. Tworzenie takiej kontroli jak pokazana poniżej jest nieskuteczne.,
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);//Check below is too late! Execution may have already occurred.if (suspectObject is SomeDangerousObjectType){ //generate warnings and dispose of suspectObject}
DlaBinaryFormatter
IJSON.Net
możliwe jest utworzenie bezpieczniejszej formy kontroli białej listy przy użyciu niestandardowegoSerializationBinder
.
staraj się być na bieżąco ze znanymi gadżetami deserializacji.Net i zwracaj szczególną uwagę na to, gdzie takie typy mogą być tworzone przez procesy deserializacji. Deserializer może tworzyć tylko typy, o których wie.
staraj się oddzielać każdy kod, który może tworzyć potencjalne gadżety od dowolnego kodu, który ma łączność z Internetem., Na przykład System.Windows.Data.ObjectDataProvider
używany w aplikacjach WPF jest znanym gadżetem, który umożliwia dowolne wywołanie metody. Byłoby ryzykowne, gdyby miało to odniesienie do tego zespołu w projekcie usługi REST, który deserializuje niezaufane dane.
znane .,NET RCE Gadgets¶
System.Configuration.Install.AssemblyInstaller
System.Activities.Presentation.WorkflowDesigner
System.Windows.ResourceDictionary
System.Windows.Data.ObjectDataProvider
System.Windows.Forms.BindingSource
Microsoft.Exchange.Management.SystemManager.WinForms.ExchangeSettingsProvider
System.Data.DataViewManager, System.Xml.XmlDocument/XmlDataDocument
System.Management.Automation.PSObject
Language-Agnostic Methods for Deserializing Safely¶
Using Alternative Data Formats¶
A great reduction of risk is achieved by avoiding native (de)serialization formats., Przełączając się na czysty format danych, taki jak JSON lub XML, zmniejszasz szansę na zmianę niestandardowej logiki deserializacji w kierunku złośliwych celów.
wiele aplikacji opiera się na wzorcu obiektu transferu danych, który polega na utworzeniu oddzielnej domeny obiektów w celu wyraźnego przesyłania danych. Oczywiście nadal możliwe jest, że aplikacja popełni błędy bezpieczeństwa po przetworzeniu obiektu pure data.,
Deserializuje tylko podpisane dane¶
Jeśli aplikacja wie przed deserializacją, które wiadomości będą musiały zostać przetworzone, może je podpisać jako część procesu serializacji. Aplikacja może wtedy wybrać, aby nie deserializować żadnej wiadomości, która nie miała uwierzytelnionego podpisu.,
narzędzia/Biblioteki łagodzące¶
- Java secure deserialization library
- SWAT (Serial Whitelist Application Trainer)
- NotSoSerial
narzędzia do wykrywania¶
- Java deserialization cheat sheet skierowany do testerów pióra
- narzędzie do generowania ładunków wykorzystujących niebezpieczne deserializacje obiektów Java.
- Java de-serialization toolkits
- Java de-serialization tool
- .,n
- JavaSerialKiller
- Java deserialization Scanner
- Burp-ysoserial
- SuperSerial
- SuperSerial-Active
Referencje¶
- Java-Deserialization-Cheat-Sheet
- Deserializacja niezaufanych danych
- Java deserialization attacks – German OWASP Day 2016
- Appseccali 2015 – marshalling Pickles
- foxglove Security – Vulnerability announcement
- Java deserialization cheat sheet skierowany do testerów pióra
- narzędzie proof-of-Concept do generowania ładunków, które wykorzystują niebezpieczne Java object deserialization.,
- Java de-serialization toolkits
- Java de-serialization tool
- Burp Suite extension
- Java secure deserialization library
- Serianalyzer is a static bytecode analyzer for deserialization
- Payload generator
- Android Java Deserialization Vulnerability Tester
- Burp Suite Extension
- JavaSerialKiller
- skaner deserializacji Javy
- Burp-ysoserial
- superserial
- superserial-active
li>
- . NET
- .,Serializacja sieci: wykrywanie i obrona wrażliwych punktów końcowych
- James Forshaw – Black Hat USA 2012 – Czy Jesteś w moim typie? Łamanie piaskownicy. NET poprzez serializację
- Jonathan Birch BlueHat v17 – niebezpieczne treści – zabezpieczanie deserializacji. Net
- Alvaro Muñoz& Oleksandr Mirosh – Friday the 13th: Attacking JSON – AppSecUSA 2017