Sé que esto es realmente, muy tarde en el juego, pero sí , existe una vulnerabilidad específica que se relaciona directamente con la deserialización de datos no confiables. Funciona de la misma manera que lo hacen los ataques de "Inyección de objetos PHP", al abusar de las clases que realizan acciones en sus etapas de finalización y eliminación.
Considera la siguiente clase:
[Serializable]
class TempFile : IDisposable
{
private readonly string _fileName;
public TempFile()
{
_fileName = Path.GetTempFileName();
}
~TempFile()
{
Dispose();
}
public FileStream GetStream()
{
return new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
public void Dispose()
{
try
{
if (File.Exists(_fileName))
File.Delete(_fileName);
} catch {}
}
}
Ahora, imagine que hay una clase serializable realmente aburrida llamada Message
que solo contiene algunas cadenas. Nada realmente interesante en absoluto. Estás utilizando esta clase para pasar mensajes a través de la red, de esta manera:
public void ProcessNetworkMessage(byte[] message)
{
var bf = new BinaryFormatter();
Message msg = null;
try
{
using (var ms = new MemoryStream(message))
{
msg = (Message) bf.Deserialise(ms);
}
}
catch (Exception ex)
{
AppLog.WriteLine("Exception: " + ex.Message);
}
if (msg != null)
{
ProcessMessage(msg);
}
}
Parece inocuo, ¿no? Pero, ¿qué sucede si un atacante pasa una versión serializada binaria de un objeto TempFile
a través de la red, en lugar del objeto Message
esperado?
Suceden cuatro cosas:
- El BinaryFormatter deserializa los datos en una instancia de objeto.
- El objeto devuelto se convierte sin éxito en un objeto de Mensaje, lanzando una excepción de conversión.
- El método sale sin usar el objeto devuelto, dejando la representación interna con cero referencias en el árbol GC.
- El recolector de basura se deshace del objeto.
¿Por qué es explotable? Bueno, cuando la lógica de finalización es llamada por el GC, el destructor llama a TempFile.Dispose()
y borra el archivo especificado por el campo _fileName
. Dado que el valor de ese campo se establece dentro del blob serializado binario, el atacante puede controlarlo. Póngalo todo junto y tendrá un error de eliminación de archivo arbitrario.
Esto parece un poco exagerado, pero a menudo encontrarás consultas SQL y todo tipo de otras cosas en Dispose()
o destructores de clases serializables.
Editar: Hice una búsqueda rápida de la fuente de referencia, y resulta que System.CodeDo
m.Compiler.TempFileCollection
contiene exactamente el problema que mostré anteriormente. Puedes llenarlo con una lista de archivos y luego de destruirlo. los elimina a todos.