Introduzione¶
Questo articolo è incentrato sulla fornitura di una guida chiara e attuabile per deserializzare in modo sicuro i dati non attendibili nelle applicazioni.
Cos’è la deserializzazione¶
La serializzazione è il processo di trasformare un oggetto in un formato di dati che può essere ripristinato in seguito. Le persone spesso serializzano gli oggetti per salvarli nello storage o per inviarli come parte delle comunicazioni.,
La deserializzazione è il contrario di quel processo, prendendo dati strutturati da qualche formato e ricostruendoli in un oggetto. Oggi, il formato di dati più popolare per la serializzazione dei dati è JSON. Prima di allora, era XML.
Tuttavia, molti linguaggi di programmazione offrono una capacità nativa per la serializzazione degli oggetti. Questi formati nativi di solito offrono più funzionalità di JSON o XML, inclusa la personalizzazione del processo di serializzazione.
Purtroppo, le caratteristiche di questi meccanismi di deserializzazione nativi possono essere riproposti per effetto dannoso quando si opera su dati non attendibili., Gli attacchi contro i deserializzatori sono stati trovati per consentire attacchi denial-of-service, controllo degli accessi e esecuzione di codice remoto (RCE).
Guida sulla deserializzazione sicura degli oggetti¶
La seguente guida specifica per la lingua tenta di enumerare metodologie sicure per la deserializzazione dei dati non attendibili.
PHP¶
Recensione WhiteBox¶
Controllare l’uso della funzione unserialize() e rivedere come i parametri esterni sono accettati., Utilizzare un formato di interscambio dati sicuro e standard come JSON (tramitejson_decode()
ejson_encode()
) se è necessario passare dati serializzati all’utente.
Python¶
Recensione BlackBox¶
Se i dati sul traffico contengono il simbolo dot.
alla fine, è molto probabile che i dati siano stati inviati in serializzazione.
WhiteBox Review¶
La seguente API in Python sarà vulnerabile agli attacchi di serializzazione. Cerca il codice per il modello qui sotto.,
- Gli usi del
pickle/c_pickle/_pickle
conload/loads
:
import pickledata = """ cos.system(S'dir')tR. """pickle.loads(data)
- Usa di
PyYAML
conload
:
import yamldocument = "!!python/object/apply:os.system "print(yaml.load(document))
- Usa di
jsonpickle
conencode
ostore
metodi.
Java¶
Le seguenti tecniche sono tutte utili per prevenire attacchi contro la deserializzazione contro il formato serializzabile di Java.,
Consigli di implementazione:
- Nel codice, sovrascrivere il metodo
ObjectInputStream#resolveClass()
per impedire la deserializzazione di classi arbitrarie. Questo comportamento sicuro può essere racchiuso in una libreria come SerialKiller. - Utilizzare una sostituzione sicura per il metodo generico
readObject()
come visto qui. Si noti che questo risolve gli attacchi di tipo “miliardi di risate” controllando la lunghezza dell’input e il numero di oggetti deserializzati.
Recensione WhiteBox¶
Essere consapevoli dei seguenti usi API Java per potenziale vulnerabilità serializzazione.,
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 può suggerire che i dati inviati in serializzazione Java flussi
-
AC ED 00 05
in Hex -
rO0
in Base64 -
Content-type
intestazione di una risposta HTTP impostato suapplication/x-java-serialized-object
Prevenire la Perdita di Dati e di Fiducia Campo Stracciando¶
Se ci sono dei membri di un oggetto che non deve mai essere controllato da parte degli utenti finali durante la deserializzazione o esposti agli utenti durante la serializzazione, dovrebbero essere dichiarati come il transient
parola chiave (sezione Protezione delle Informazioni Sensibili).,
Per una classe definita come serializzabile, la variabile di informazioni sensibili deve essere dichiarata comeprivate transient
.
Ad esempio, la classe MyAccount, la variabile ‘profit’ e ‘margin’ sono state dichiarate come transitorie per evitare di essere serializzate:
public class myAccount implements Serializable{ private transient double profit; // declared transient private transient double margin; // declared transient ....
Impedire la deserializzazione degli Oggetti di dominio¶
Alcuni degli oggetti dell’applicazione potrebbero essere costretti a implementare Serializzabili a causa della loro gerarchia., Per garantire che gli oggetti dell’applicazione non possano essere deserializzati, è necessario dichiarare un metodo readObject()
(con un modificatore final
) che genera sempre un’eccezione:
Indurire il proprio java.io.ObjectInputStream¶
Il java.io.ObjectInputStream
classe viene utilizzata per deserializzare gli oggetti. È possibile indurire il suo comportamento sottoclassandolo., Questa è la soluzione migliore se:
- Puoi cambiare il codice che fa la deserializzazione
- Sai quali classi ti aspetti di deserializzare
L’idea generale è di sovrascrivere ObjectInputStream.html#resolveClass()
per limitare quali classi possono essere deserializzate.
Poiché questa chiamata avviene prima che venga chiamato unreadObject()
, puoi essere sicuro che non si verificherà alcuna attività di deserializzazione a meno che il tipo non sia quello che desideri consentire.,
Un semplice esempio di questo mostrate qui, dove il LookAheadObjectInputStream
classe è garantito per deserializzare qualsiasi altro tipo oltre il Bicycle
classe:
Più completo implementazioni di questo approccio sono stati proposti da vari membri della comunità:
- NibbleSec – una libreria che permette di whitelist e blacklist di classi che possono essere deserializzato
- IBM – seminale di protezione, scritto anni prima, la più devastante sfruttamento scenari erano contemplati.,
- Apache Commons IO classes
Harden All java.io.ObjectInputStream Usage with an Agent¶
Come menzionato sopra, la classejava.io.ObjectInputStream
viene utilizzata per deserializzare gli oggetti. È possibile indurire il suo comportamento sottoclassandolo. Tuttavia, se non si possiede il codice o non si può aspettare una patch, utilizzare un agente per tessere in indurimento a java.io.ObjectInputStream
è la soluzione migliore.,
Cambiare globalmente ObjectInputStream
è sicuro solo per i tipi dannosi noti nella blacklist, perché non è possibile sapere per tutte le applicazioni quali sono le classi previste da deserializzare. Fortunatamente, ci sono pochissime classi necessarie nella lista nera per essere al sicuro da tutti i vettori di attacco noti, oggi.
È inevitabile che vengano scoperte più classi di “gadget” che possono essere abusate. Tuttavia, c’è una quantità incredibile di software vulnerabili esposti oggi, che hanno bisogno di una correzione., In alcuni casi, “correggere” la vulnerabilità può comportare la riprogettazione dei sistemi di messaggistica e la rottura della retrocompatibilità man mano che gli sviluppatori si spostano verso la non accettazione di oggetti serializzati.
Per attivare questi agenti, aggiungi semplicemente una nuova JVM parametro:
-javaagent:name-of-agent.jar
gli Agenti l’assunzione di questo approccio sono stati rilasciati da vari membri della comunità:
- rO0 dal Contrasto di Sicurezza
Una simile, ma meno scalabile approccio potrebbe essere quello di correggere manualmente e bootstrap JVM è ObjectInputStream. Le linee guida su questo approccio sono disponibili qui.
.,Net CSharp¶
WhiteBox Review¶
Cerca nel codice sorgente i seguenti termini:
TypeNameHandling
JavaScriptTypeResolver
Cerca qualsiasi serializzatore in cui il tipo è impostato da una variabile controllata dall’utente.,
BlackBox Recensione¶
Ricerca per il seguente contenuto codificato base64 che inizia con:
AAEAAAD/////
Ricerca per il contenuto con il seguente testo:
TypeObject
$type:
Precauzioni Generali¶
non lasciare che il flusso di dati per definire il tipo di oggetto che il flusso sarà deserializzato per. È possibile impedirlo ad esempio utilizzando DataContractSerializer
o XmlSerializer
se possibile.,
Dove viene utilizzatoJSON.Net
assicurarsi cheTypeNameHandling
sia impostato solo suNone
.
TypeNameHandling = TypeNameHandling.None
SeJavaScriptSerializer
deve essere utilizzato, non utilizzarlo con unJavaScriptTypeResolver
.
Se è necessario deserializzare i flussi di dati che definiscono il proprio tipo, limitare i tipi che possono essere deserializzati. Si dovrebbe essere consapevoli che questo è ancora rischioso come molti tipi.Net nativi potenzialmente pericolosi di per sé. ad esempio,
System.IO.FileInfo
FileInfo
gli oggetti che fanno riferimento ai file effettivamente sul server possono, quando deserializzati, modificare le proprietà di tali file, ad esempio in sola lettura, creando un potenziale attacco denial of service.
Anche se hai limitato i tipi che possono essere deserializzati ricorda che alcuni tipi hanno proprietà rischiose. System.ComponentModel.DataAnnotations.ValidationException
, ad esempio ha una proprietàValue
di tipoObject
., se questo tipo è il tipo consentito per la deserializzazione, un utente malintenzionato può impostare la proprietàValue
su qualsiasi tipo di oggetto scelto.
Agli aggressori dovrebbe essere impedito di indirizzare il tipo che verrà istanziato. Se ciò è possibile, anche DataContractSerializer
oXmlSerializer
può essere sovvertito, ad esempio
// 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);
L’esecuzione può verificarsi all’interno di determinati tipi.Net durante la deserializzazione. La creazione di un controllo come quello mostrato di seguito è inefficace.,
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}
PerBinaryFormatter
eJSON.Net
è possibile creare una forma più sicura di controllo white list utilizzando unSerializationBinder
personalizzato.
Cerca di tenerti aggiornato sui gadget di deserializzazione insicuri.Net noti e presta particolare attenzione quando tali tipi possono essere creati dai tuoi processi di deserializzazione. Un deserializzatore può solo istanziare tipi di cui è a conoscenza.
Cerca di mantenere qualsiasi codice che possa creare potenziali gadget separato da qualsiasi codice dotato di connettività Internet., Ad esempioSystem.Windows.Data.ObjectDataProvider
utilizzato nelle applicazioni WPF è un gadget noto che consente l’invocazione arbitraria del metodo. Sarebbe rischioso avere questo riferimento a questo assembly in un progetto di servizio REST che deserializza i dati non attendibili.
Noto .,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., Passando a un formato di dati puro come JSON o XML, si riduce la possibilità che la logica di deserializzazione personalizzata venga riproposta verso fini dannosi.
Molte applicazioni si basano su un modello di oggetto di trasferimento dati che comporta la creazione di un dominio separato di oggetti per il trasferimento dei dati scopo esplicito. Naturalmente, è ancora possibile che l’applicazione commetta errori di sicurezza dopo l’analisi di un oggetto dati puro.,
Deserializza solo i dati firmati¶
Se l’applicazione sa prima della deserializzazione quali messaggi dovranno essere elaborati, potrebbe firmarli come parte del processo di serializzazione. L’applicazione potrebbe quindi scegliere di non deserializzare alcun messaggio che non avesse una firma autenticata.,
Strumenti di Mitigazione e/o Librerie¶
- Java secure deserializzazione libreria
- SWAT (di Serie Whitelist Applicazione Trainer)
- NotSoSerial
Strumenti di Rilevamento¶
- Java deserializzazione cheat sheet volto a penna tester
- Un proof-of-concept strumento per la generazione di carichi che sfruttare pericoloso oggetto Java deserializzazione.
- Strumenti di de-serializzazione Java
- Strumento di de-serializzazione Java
- .,n
- JavaSerialKiller
- Java Deserializzazione Scanner
- Burp-ysoserial
- SuperSerial
- SuperSerial-Active
Riferimenti¶
- Java-Deserializzazione-Cheat-Sheet
- la Deserializzazione dei dati non attendibili
- Java Deserializzazione Attacchi – tedesco OWASP Day 2016
- AppSecCali 2015 – Marshalling Sottaceti
- FoxGlove di Sicurezza – Vulnerabilità Annuncio
- Java deserializzazione cheat sheet volto a penna tester
- Un proof-of-concept strumento per la generazione di carichi che sfruttare pericoloso oggetto Java deserializzazione.,
- Java De-serializzazione toolkit
- Java de-serializzazione strumento
- Burp Suite estensione
- Java secure deserializzazione libreria
- Serianalyzer statica del bytecode analizzatore per la deserializzazione
- Payload generatore
- Android Java Deserializzazione Vulnerabilità Tester
- Burp Suite Estensione
- JavaSerialKiller
- Java Deserializzazione Scanner
- Burp-ysoserial
- SuperSerial
- SuperSerial-Active
- .Net
- Alvaro Muñoz: .,Serializzazione NETTA: rilevamento e difesa degli endpoint vulnerabili
- James Forshaw – Black Hat USA 2012-Sei il mio tipo? Rompere sandbox. net attraverso la serializzazione
- Jonathan Birch BlueHat v17 – Contenuti pericolosi – Protezione Deserializzazione. Net
- Alvaro Muñoz & Oleksandr Mirosh – Venerdì 13: Attaccare JSON – AppSecUSA 2017