como se ha visto anteriormente, el código da un error «Exception in thread» main » java.lang.ClassCastException: testserialization.ExploitDeser no puede ser lanzado a testserialization.Empleado», lo que significa que la conversión de tipos no es adecuada, sin embargo, el código todavía se ejecuta. La función readObject de la clase DeserializeDemo es capaz de ejecutar la implementación personalizada de la clase readObject de ExploitDeser.,
esto es lo que es la deserialización insegura aquí, que a pesar de que hay un error de conversión de tipos aún si se proporcionan datos serializados de una clase personalizada con una implementación personalizada de readObject como entrada, se ejecuta como se muestra arriba.
esto es lo que hacen las cadenas de gadgets utilizadas por ysoserial y otras herramientas de explotación de deserialización java donde buscan encadenar clases para finalmente aterrizar en una implementación personalizada de readObject que puede ejecutar código a nivel de sistema proporcionado como parte de la entrada del usuario.,
remediación
ahora, que hemos tenido un vistazo a lo que es deserialización y cómo se explota, vamos a ver la remediación a esto.
la remediación que vamos a discutir aquí se llama «validación de clase anticipada», donde podemos incluir en la lista blanca la lista de clases que queremos deserializar. Por ejemplo. en nuestro escenario, esperaríamos permitir que solo los datos de objetos de clase de empleado se deserialicen y, para permanecer, no debería permitir la deserialización.,
entonces, básicamente lo que hace este método es, sobrescribe la función «resolveClass» que es una parte de la clase «ObjectInputStream»(utilizada durante la deserialización) y realiza una lista blanca de la lista de classess que necesita ser deserializada.
ahora que hemos terminado con la teoría, vamos a saltar a la implementación.,
vamos a crear una nueva clase «LookAheadObjectInputStream» extenderlo a la clase ObjectInputSteam para que podamos sobreescribir la función miembro resolveClass:
en el código anterior la línea:
if (!desc.getName().equals(Employee.class.getName())) {
básicamente está buscando si el contenido serializado contiene objeto de la clase empleado de lo contrario proporciona error «intento de deserialización no autorizado» y evita su ejecución.,
ahora, el código modificado final para «DeserializedDemo» es como se muestra a continuación: