Inleiding¶
Dit artikel is gericht op het verstrekken van duidelijke, bruikbare richtlijnen voor het veilig deserialiseren van niet-vertrouwde gegevens in uw toepassingen.
Wat is deserialisatie¶
serialisatie is het proces van het omzetten van een object in een gegevensformaat dat later kan worden hersteld. Mensen serialiseren vaak objecten om ze op te slaan in opslag, of om te verzenden als onderdeel van communicatie.,
deserialisatie is het omgekeerde van dat proces, waarbij gegevens gestructureerd worden vanuit een bepaald formaat, en het herbouwen tot een object. Vandaag de dag is de meest populaire dataformaat voor het serialiseren van gegevens JSON. Daarvoor was het XML.
echter, veel programmeertalen bieden een native mogelijkheid voor het serialiseren van objecten. Deze native formaten bieden meestal meer functies dan JSON of XML, inclusief aanpasbaarheid van het serialisatieproces.
helaas kunnen de functies van deze eigen deserialisatiemechanismen worden hergebruikt voor kwaadaardig effect wanneer wordt gewerkt op niet-vertrouwde gegevens., Aanvallen tegen deserializers zijn gevonden om denial-of-service, access control en remote code execution (RCE) aanvallen toe te staan.
Guidance on deserializing Objects Safely¶
de volgende taalspecifieke richtlijnen proberen veilige methodologieën op te sommen voor het deserialiseren van gegevens die niet kunnen worden vertrouwd.
PHP¶
Whitebox Review¶
controleer het gebruik van de functie unserialize () en bekijk hoe de externe parameters worden geaccepteerd., Gebruik een veilig, standaard data interchange format zoals JSON (via json_decode()
en json_encode()
) Als u serialized data aan de gebruiker wilt doorgeven.
Python¶
Blackbox Review¶
als de verkeersgegevens het symbool dot .
aan het einde bevatten, is het zeer waarschijnlijk dat de gegevens in serialisatie zijn verzonden.
Whitebox Review¶
de volgende API in Python zal kwetsbaar zijn voor serialisatie aanvallen. Zoek code voor het patroon hieronder.,
- Het gebruik van
pickle/c_pickle/_pickle
metload/loads
:
import pickledata = """ cos.system(S'dir')tR. """pickle.loads(data)
- bij Gebruik van
PyYAML
metload
:
import yamldocument = "!!python/object/apply:os.system "print(yaml.load(document))
- bij Gebruik van
jsonpickle
metencode
ofstore
methoden.
Java¶
de volgende technieken zijn allemaal goed voor het voorkomen van aanvallen tegen deserialisatie tegen Java ‘ s Serialiseerbare formaat.,
Implementatieadviezen:
- overschrijf in uw code de
ObjectInputStream#resolveClass()
methode om te voorkomen dat willekeurige klassen worden gedeserialiseerd. Dit veilige gedrag kan worden verpakt in een bibliotheek zoals SerialKiller. - gebruik een veilige vervanging voor de generieke
readObject()
methode zoals hier te zien is. Merk op dat dit adressen “miljard lacht” type aanvallen door het controleren van de invoer lengte en het aantal objecten gedeserialiseerd.
Whitebox Review¶
wees bewust van de volgende Java API-toepassingen voor potentiële kwetsbaarheid voor serialisatie.,
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 kan suggereren dat de gegevens verzonden in Java serialisatie streams
-
AC ED 00 05
in de modus Hex -
rO0
Base64 -
Content-type
koptekst van een HTTP response ingesteld opapplication/x-java-serialized-object
het Voorkomen van Lekken van Gegevens en Vertrouwde Veld Werken¶
Als er gegevens leden van een object dat mag nooit worden gecontroleerd door de eindgebruikers tijdens deserialisatie of blootgesteld aan gebruikers tijdens serialisatie, ze moeten worden verklaard als de transient
trefwoord (§het Beschermen van Gevoelige Informatie).,
voor een klasse die is gedefinieerd als serialiseerbaar, moet de variabele gevoelige informatie worden gedeclareerd als private transient
.
bijvoorbeeld, de class myAccount, de variabele ‘ profit ‘en’ margin ‘ werden als tijdelijk gedeclareerd om serialisatie te vermijden:
public class myAccount implements Serializable{ private transient double profit; // declared transient private transient double margin; // declared transient ....
voorkomen deserialisatie van Domeinobjecten¶
sommige van uw toepassingsobjecten kunnen worden gedwongen serialiseerbaar te implementeren vanwege hun hiërarchie., Om te garanderen dat uw applicatieobjecten niet gedeserialiseerd kunnen worden, moet een readObject()
methode worden gedeclareerd (met een final
modifier) die altijd een uitzondering geeft:
Harden uw eigen java.Io.ObjectInputStream¶
De java.io.ObjectInputStream
klasse wordt gebruikt om objecten te deserialiseren. Het is mogelijk om zijn gedrag te verharden door het onder te classificeren., Dit is de beste oplossing als:
- u de code kunt wijzigen die de deserialisatie uitvoert
- u weet welke klassen u verwacht te deserialiseren
het algemene idee is om ObjectInputStream.html#resolveClass()
te overschrijven om te beperken welke klassen mogen worden gedeserialiseerd.
omdat deze aanroep plaatsvindt voordat een readObject()
wordt aangeroepen, kunt u er zeker van zijn dat er geen deserialisatie-activiteit zal plaatsvinden tenzij het type dat u wilt toestaan.,
een eenvoudig voorbeeld hiervan wordt hier getoond, waarbij de klasse LookAheadObjectInputStream
gegarandeerd geen ander type zal deserialiseren behalve de klasse Bicycle
klasse:
vollediger implementaties van deze aanpak zijn voorgesteld door verschillende leden van de gemeenschap:
- NibbleSec – een bibliotheek die een whitelisting en een blacklisting van klassen toestaat die IBM – the seminal protection, geschreven jaren voordat de meest verwoestende exploitatiescenario ‘ s werden voorzien.,
- Apache Commons IO-klassen
verharden alle java.Io.ObjectInputStream-gebruik met een Agent¶
zoals hierboven vermeld, wordt de klasse java.io.ObjectInputStream
gebruikt om objecten te deserialiseren. Het is mogelijk om zijn gedrag te verharden door het onder te classificeren. Echter, als je de code niet bezit of niet kunt wachten op een patch, is het gebruik van een agent om te weven in Harding tot java.io.ObjectInputStream
de beste oplossing.,
globaal veranderen ObjectInputStream
is alleen veilig voor een zwarte lijst van bekende kwaadaardige types, omdat het niet mogelijk is om voor alle toepassingen te weten wat de verwachte klassen zijn die moeten worden gedeserialiseerd. Gelukkig, er zijn zeer weinig klassen nodig in de zwarte lijst om veilig te zijn van alle bekende aanval vectoren, vandaag.
Het is onvermijdelijk dat er meer “gadget” klassen zullen worden ontdekt die kunnen worden misbruikt. Echter, er is een ongelooflijke hoeveelheid kwetsbare software blootgesteld vandaag, in de behoefte aan een oplossing., In sommige gevallen,” vaststelling ” van de kwetsbaarheid kan betrekking hebben op re-architecting messaging systemen en het breken van backwards compatibiliteit als ontwikkelaars bewegen in de richting van het niet accepteren van geserialiseerde objecten.
Om deze agenten, gewoon het toevoegen van een nieuwe JVM parameter:
-javaagent:name-of-agent.jar
Agenten nemen van deze aanpak zijn vrijgegeven door verschillende leden van de gemeenschap:
- rO0 Daarentegen Beveiliging
Een soortgelijke, maar minder schaalbare aanpak zou zijn om handmatig patch en bootstrap JVM ‘ s ObjectInputStream. Richtsnoeren voor deze aanpak zijn hier beschikbaar.
.,Net csharp¶
Whitebox Review¶
zoek in de broncode naar de volgende termen:
TypeNameHandling
JavaScriptTypeResolver
zoek naar serializers waar het type is ingesteld door een door de gebruiker gecontroleerde variabele.,
de BlackBox Review¶
Zoek de volgende base64-gecodeerde inhoud die begint met:
AAEAAAD/////
content te Zoeken met de volgende tekst:
TypeObject
$type:
Algemene Voorzorgsmaatregelen¶
niet toestaan dat de datastroom aan het definiëren van het type object dat de stream zal worden gedeserialiseerd aan. U kunt dit voorkomen door bijvoorbeeld DataContractSerializer
of XmlSerializer
te gebruiken indien mogelijk.,
waarbij JSON.Net
wordt gebruikt zorg ervoor dat TypeNameHandling
alleen is ingesteld op None
.
TypeNameHandling = TypeNameHandling.None
indien JavaScriptSerializer
moet worden gebruikt, gebruik het dan niet met eenJavaScriptTypeResolver
.
Als u gegevensstromen moet deserialiseren die hun eigen type definiëren, beperk dan de typen die mogen worden gedeserialiseerd. Men moet zich ervan bewust dat dit is nog steeds riskant als veel native.net types potentieel gevaarlijk in zichzelf. bijv.,
System.IO.FileInfo
FileInfo
objecten die verwijzen naar bestanden die daadwerkelijk op de server staan, kunnen bij deserialisatie de eigenschappen van die bestanden wijzigen, bijvoorbeeld in alleen-lezen, waardoor een potentiële denial of service-aanval wordt gecreëerd.
zelfs als u de typen hebt beperkt die kunnen worden gedeserialiseerd, onthoud dan dat sommige typen eigenschappen hebben die riskant zijn. System.ComponentModel.DataAnnotations.ValidationException
, bijvoorbeeld heeft een eigenschap Value
van het type Object
., als dit type het type is dat is toegestaan voor deserialisatie, dan kan een aanvaller de eigenschap Value
instellen op elk objecttype dat hij kiest.
aanvallers moeten worden verhinderd het type te besturen dat zal worden ingesteld. Als dit mogelijk is, kan zelfs DataContractSerializer
of XmlSerializer
worden gesubverteerd, bijvoorbeeld
// 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);
uitvoering kan optreden binnen bepaalde.net types tijdens deserialisatie. Het creëren van een controle zoals hieronder weergegeven is ineffectief.,
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}
Voor BinaryFormatter
en JSON.Net
Het is mogelijk om een veiliger vorm van witte lijst controle te maken met behulp van een aangepaste SerializationBinder
.
probeer up-to-date te blijven over bekende.Net onveilige deserialisatie gadgets en besteed speciale aandacht waar dergelijke types kunnen worden gemaakt door uw deserialisatie processen. Een deserializer kan alleen types instantiëren die hij kent.
probeer elke code die potentiële gadgets kan maken gescheiden te houden van elke code met internetverbinding., Als voorbeeld System.Windows.Data.ObjectDataProvider
gebruikt in WPF-toepassingen is een bekende gadget die willekeurige methode aanroep toestaat. Het zou riskant zijn om dit te laten verwijzen naar deze vergadering in een rust service project dat onbetrouwbare gegevens deserialiseert.
bekend .,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., Door over te schakelen naar een pure data-formaat zoals JSON of XML, je vermindert de kans op aangepaste deserialisatie logica wordt hergebruikt in de richting van kwaadaardige doeleinden.
veel toepassingen vertrouwen op een gegevensoverdrachtobjectpatroon waarbij een apart domein van objecten wordt gecreëerd voor het expliciete doel gegevensoverdracht. Natuurlijk is het nog steeds mogelijk dat de applicatie beveiligingsfouten zal maken nadat een zuiver gegevensobject is ontleed.,
alleen ondertekende gegevens deserialiseren¶
als de toepassing vóór de deserialisatie weet welke berichten moeten worden verwerkt, kunnen ze deze ondertekenen als onderdeel van het serialisatieproces. De toepassing kon dan kiezen om geen bericht te deserialiseren dat geen geverifieerde handtekening had.,
Mitigatietools/bibliotheken¶
- Java secure deserialization library
- SWAT (Serial Whitelist Application Trainer)
- NotSoSerial
Detectietools¶
- Java deserialization spiekbrief gericht op pen testers
- een proof-of-concept tool voor het genereren van payloads die onveilige java-objectdeserialisatie exploiteren.
- Java de-serialisatietoolkits
- Java de-serialisatietool
- .,n
- JavaSerialKiller
- Java Deserialisatie-Scanner
- Burp-ysoserial
- SuperSerial
- SuperSerial-Actief
Referenties¶
- Java-Deserialisatie-Cheat-Sheet
- Deserialisatie van onbetrouwbare gegevens
- Java Deserialisatie-Aanvallen – duitse OWASP Dag 2016
- AppSecCali 2015 – Marshalling Pickles
- Vingerhoedskruid Security – Kwetsbaarheid Aankondiging
- Java deserialisatie cheat sheet gericht op het pen-testers
- Een proof-of-concept tool voor het genereren van payloads die misbruik maken van onveilige Java-object deserialisatie.,
- Java-De-serialisatie toolkits
- Java-de-serialisatie tool
- Burp Suite extension
- Java secure deserialisatie bibliotheek
- Serianalyzer is een statische bytecode analyzer voor deserialisatie
- Laadvermogen generator
- Android Java Deserialisatie Kwetsbaarheid Tester
- Burp Suite Extension
- JavaSerialKiller
- Java Deserialisatie-Scanner
- Burp-ysoserial
- SuperSerial
- SuperSerial-Actief
- .Netto
- Alvaro Muñoz: .,NET serialisatie: detecteren en verdedigen van kwetsbare eindpunten
- James Forshaw-Black Hat USA 2012-Are You My Type? . Net Sandboxes breken door serialisatie
- Jonathan Birch BlueHat v17-Dangerous Contents-Securing. net Deserialization
- Alvaro Muñoz & Oleksandr Mirosh-Friday the 13th: Attacking JSON – AppSecUSA 2017