Introduction¶
Este artículo se centra en proporcionar una guía clara y procesable para deserializar de forma segura los datos no confiables en sus aplicaciones.
Qué es deserialización¶
serialización es el proceso de convertir un objeto en un formato de datos que se puede restaurar más tarde. Las personas a menudo serializan objetos para guardarlos en el almacenamiento o para enviarlos como parte de las comunicaciones.,
la deserialización es lo contrario de ese proceso, tomando datos estructurados de algún formato y reconstruyéndolos en un objeto. Hoy en día, el formato de datos más popular para serializar datos es JSON. Antes de eso, era XML.
sin embargo, muchos lenguajes de programación ofrecen una capacidad nativa para serializar objetos. Estos formatos nativos suelen ofrecer más características que JSON o XML, incluida la personalización del proceso de serialización.
desafortunadamente, las características de estos mecanismos nativos de deserialización se pueden reutilizar para efectos maliciosos cuando se opera en datos no confiables., Se ha encontrado que los ataques contra deserializers permiten ataques de denegación de servicio, control de acceso y ejecución remota de código (RCE).
guía para deserializar objetos de forma segura¶
la siguiente guía específica del lenguaje intenta enumerar metodologías seguras para deserializar datos que no se pueden confiar.
PHP¶
WhiteBox Review¶
Compruebe el uso de la función unserialize () y revise cómo se aceptan los parámetros externos., Utilice un formato seguro y estándar de intercambio de datos como JSON (a través de json_decode()
y json_encode()
) si necesita pasar datos serializados al usuario.
Python¶
BlackBox Review¶
Si los datos de tráfico contienen el símbolo dot .
al final, es muy probable que los datos se hayan enviado en serialización.
WhiteBox Review¶
la siguiente API en Python será vulnerable al ataque de serialización. Código de búsqueda para el patrón de abajo.,
- El uso de
pickle/c_pickle/_pickle
load/loads
:
import pickledata = """ cos.system(S'dir')tR. """pickle.loads(data)
- Utiliza de
PyYAML
load
:
import yamldocument = "!!python/object/apply:os.system "print(yaml.load(document))
- Utiliza de
jsonpickle
encode
ostore
métodos.
Java¶
las siguientes técnicas Son todas buenas para prevenir ataques contra la deserialización contra el formato Serializable de Java.,
consejos de implementación:
- en su código, anule el método
ObjectInputStream#resolveClass()
para evitar que las clases arbitrarias se deserialicen. Este comportamiento seguro puede ser envuelto en una biblioteca como SerialKiller. - Use un reemplazo seguro para el método genérico
readObject()
como se ve aquí. Tenga en cuenta que esto aborda los ataques de tipo «billion laughs» al verificar la longitud de entrada y el número de objetos deserializados.
WhiteBox Review¶
tenga en cuenta los siguientes usos de la API de Java para una posible vulnerabilidad de serialización.,
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 puede sugerir que los datos se enviaron en flujos de serialización Java
-
AC ED 00 05
en Hex -
rO0
en Base64 -
Content-type
cabecera de una respuesta HTTP establecida enapplication/x-java-serialized-object
evitar fugas de datos y clobbering de campos de confianza¶
Si hay miembros de datos de un objeto que nunca deben ser controlados por los usuarios finales durante la deserialización o expuestos a los usuarios durante la serialización, deben declararse como la palabra clave transient
(sección protección de información confidencial).,
para una clase que se define como Serializable, la variable de información sensible debe declararse como private transient
.
por ejemplo, la clase myAccount, la variable ‘profit’ y ‘margin’ fueron declaradas como transitorias para evitar ser serializadas:
public class myAccount implements Serializable{ private transient double profit; // declared transient private transient double margin; // declared transient ....
evitar la deserialización de objetos de dominio¶
algunos de sus objetos de aplicación pueden ser forzados a implementar serializables debido a su jerarquía., Para garantizar que los objetos de su aplicación no se pueden deserializar, se debe declarar un método readObject()
(con un modificador final
) que siempre arroja una excepción:
endurezca su propio java.io.ObjectInputStream¶
el java.io.ObjectInputStream
class se usa para deserializar objetos. Es posible endurecer su comportamiento por la subclasificación., Esta es la mejor solución si:
- Puede cambiar el código que hace la deserialización
- sabe qué clases espera deserializar
la idea general es anular ObjectInputStream.html#resolveClass()
para restringir qué clases se permiten deserializar.
debido a que esta llamada ocurre antes de que se llame a readObject()
, puede estar seguro de que no se producirá ninguna actividad de deserialización a menos que el tipo sea uno que desee permitir.,
un ejemplo simple de esto se muestra aquí, donde la clase LookAheadObjectInputStream
se garantiza que no deserializará ningún otro tipo además de la clase Bicycle
:
implementaciones más completas de este enfoque han sido propuestas por varios miembros de la comunidad:
- nibblesec – una biblioteca que permite lista negra de clases a las que se permite deserializar
- IBM – la protección seminal, escrita años antes de que se vislumbraran los escenarios de explotación más devastadores.,
- Las Clases IO de Apache Commons
endurecen todo el uso de java.io.ObjectInputStream con un agente¶
como se mencionó anteriormente, la clasejava.io.ObjectInputStream
se usa para deserializar objetos. Es posible endurecer su comportamiento por la subclasificación. Sin embargo, si no posee el código o no puede esperar a un parche, usar un agente para tejer en endurecimiento a java.io.ObjectInputStream
es la mejor solución.,
cambiar globalmente ObjectInputStream
solo es SEGURO para incluir en listas negras tipos maliciosos conocidos, porque no es posible saber para todas las aplicaciones cuáles son las clases que se espera que se deserialicen. Afortunadamente, hay muy pocas clases necesarias en la lista negra para estar a salvo de todos los vectores de ataque conocidos, hoy en día.
es inevitable que se descubran más clases «gadget» que pueden ser abusadas. Sin embargo, hay una increíble cantidad de software vulnerable expuesto hoy en día, en necesidad de una solución., En algunos casos, «arreglar» la vulnerabilidad puede implicar la re-arquitectura de los sistemas de mensajería y romper la compatibilidad hacia atrás a medida que los desarrolladores avanzan hacia no aceptar objetos serializados.
para habilitar estos agentes, simplemente agregue un nuevo parámetro JVM:
-javaagent:name-of-agent.jar
varios miembros de la comunidad han lanzado agentes que toman este enfoque:
- rO0 por contraste de seguridad
un enfoque similar, pero menos escalable, sería parchear manualmente y arrancar el ObjectInputStream de su JVM. Se puede consultar orientación sobre este enfoque aquí.
.,Net csharp¶
WhiteBox Review¶
busque en el código fuente los siguientes términos:
TypeNameHandling
JavaScriptTypeResolver
Busque cualquier serializador donde el tipo esté establecido por una variable controlada por el usuario.,
BlackBox Revisión¶
Búsqueda de la siguiente codificación base64 contenido que comienza con:
AAEAAAD/////
Búsqueda de contenido con el siguiente texto:
TypeObject
$type:
Precauciones Generales¶
no permitir que el flujo de datos para definir el tipo de objeto de que el flujo se deserializa a. Puede evitar esto, por ejemplo, usando DataContractSerializer
o XmlSerializer
si es posible.,
donde se utiliza JSON.Net
asegúrese de que TypeNameHandling
solo esté establecido en None
.
TypeNameHandling = TypeNameHandling.None
Si JavaScriptSerializer
es para ser utilizado luego no la use con un JavaScriptTypeResolver
.
si debe deserializar flujos de datos que definan su propio tipo, restrinja los tipos que se permite deserializar. Uno debe ser consciente de que esto sigue siendo arriesgado ya que muchos tipos nativos de.Net potencialmente peligrosos en sí mismos. E. G.,
System.IO.FileInfo
FileInfo
los objetos que hacen referencia a archivos realmente en el servidor pueden, cuando se deserializan, cambiar las propiedades de esos archivos, por ejemplo, a solo lectura, creando un posible ataque de denegación de servicio.
incluso si ha limitado los tipos que se pueden deserializar recuerde que algunos tipos tienen propiedades que son riesgosas. System.ComponentModel.DataAnnotations.ValidationException
, por ejemplo, tiene una propiedad Value
de tipo Object
., si este tipo es el tipo permitido para la deserialización, un atacante puede establecer la propiedad Value
a cualquier tipo de objeto que elija.
Se debe evitar que los atacantes dirijan el tipo que se instanciará. Si esto es posible, incluso DataContractSerializer
o XmlSerializer
se puede subvertir, por ejemplo
// 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);
la ejecución puede ocurrir dentro de ciertos tipos.Net durante la deserialización. Crear un control como el que se muestra a continuación es ineficaz.,
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}
For BinaryFormatter
and JSON.Net
it is possible to create a safer form of white list control using a custom SerializationBinder
.
Trate de mantenerse al día sobre los gadgets de deserialización insegura conocidos de.Net y preste especial atención a dónde estos tipos pueden ser creados por sus procesos de deserialización. Un deserializador solo puede crear instancias de los tipos que conoce.
Trate de mantener cualquier código que pueda crear gadgets potenciales separados de cualquier código que tenga conectividad a internet., Como ejemplo System.Windows.Data.ObjectDataProvider
utilizado en aplicaciones WPF es un gadget conocido que permite la invocación de métodos arbitrarios. Sería arriesgado tener esto una referencia a este ensamblado en un proyecto de servicio REST que deserializa datos no confiables.
Conocido .,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., Al cambiar a un formato de datos puro como JSON o XML, disminuye la posibilidad de que la lógica de deserialización personalizada se reutilice para fines maliciosos.
Muchas aplicaciones se basan en un patrón de objetos de transferencia de datos que implica la creación de un dominio separado de objetos para la transferencia de datos de propósito explícito. Por supuesto, todavía es posible que la aplicación cometa errores de seguridad después de analizar un objeto de datos puros.,
solo deserializar datos firmados¶
si la aplicación sabe antes de la deserialización qué mensajes necesitarán ser procesados, podría firmarlos como parte del proceso de serialización. La aplicación puede optar por no deserializar ningún mensaje que no tenga una firma autenticada.,
Mitigation Tools/Libraries¶
- Java secure deserialization library
- SWAT (serial Whitelist Application Trainer)
- NotSoSerial
Detection Tools¶
- Java deserialization cheat sheet aimed at pen testers
- Una herramienta de prueba de concepto para generar cargas útiles que explotan la deserialización de objetos Java insegura.
- Java de-serialization toolkits
- Java de-serialization tool
- .,n
- JavaSerialKiller
- Java Deserialization Scanner
- Burp-Ysoserial
- SuperSerial
- SuperSerial-Active
References¶
- Java-Deserialization-Cheat-Sheet
- Deserialization of untrusted data
- Java Deserialization attacks – German OWASP Day 2016
- appseccali 2015 – marshalling pickles
- Foxglove security – vulnerability announcement
- Java deserialization Cheat Sheet aimed at PEN testers
- Una herramienta de prueba de concepto para generar cargas útiles que explotan la deserialización de objetos Java insegura.,
- Java de-serialization toolkits
- Java de-serialization tool
- Burp Suite extension
- Java secure deserialization library
- Serianalyzer es un analizador de bytecode estático para deserialization
- Payload generator
- Android Java Deserialization Vulnerability Tester
- Burp Suite Extension
- JavaSerialKiller
- Java deserialization Scanner
- burp-ysoserial
- superserial
- Superserial-active
- . NET
- Alvaro Muñoz:.,Serialización neta: detección y defensa de endpoints vulnerables
- James Forshaw – Black Hat USA 2012 – ¿Eres Mi tipo? Rompiendo las cajas de arena de. net a través de la serialización
- Jonathan Birch BlueHat v17 – contenido peligroso-asegurando la deserialización de. Net
- Alvaro Muñoz & Oleksandr Mirosh – viernes 13: atacando JSON – AppSecUSA 2017