pwntester / ysoserial.net

Deserialization payload generator for a variety of .NET formatters

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ActivitySurrogateSelector gadget fixed in DotNet 4.8+

monoxgas opened this issue · comments

It appears that Forshaw's SurrogateSelector gadget has been fixed in newer versions of DotNet. The patch notes are here for reference. I have yet to dig into exactly what has been corrected, but my guess would be some sort of type filtering to prevent the serialization of arbitrary objects.

Attempting to generate a payload on a host with 4.8 installed will produce the following error:

ysoserial.exe -g ActivitySurrogateSelector -f BinaryFormatter -o base64 -c none --test

Unhandled Exception: System.ArgumentException: obj
   at System.Workflow.ComponentModel.Serialization.ActivitySurrogateSelector.ObjectSurrogate.GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   at ysoserial.Generators.PayloadClass.GetObjectData(SerializationInfo info, StreamingContext context) in C:\ysoserial.net\ysoserial\Generators\ActivitySurrogateSelectorGenerator.cs:line 117
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   at ysoserial.Generators.GenericGenerator.Serialize(Object cmdobj, String formatter, Boolean test) in C:\ysoserial.net\ysoserial\Generators\GenericGenerator.cs:line 37
   at ysoserial.Generators.ActivitySurrogateSelectorGenerator.Generate(String cmd, String formatter, Boolean test) in C:\ysoserial.net\ysoserial\Generators\ActivitySurrogateSelectorGenerator.cs:line 143
   at ysoserial.Program.Main(String[] args) in C:\ysoserial.net\ysoserial\Program.cs:line 135

Would the preferred "fix" simply be a note in the help text for the time being?

My hunch was correct, I have just validated that a fix was inserted into the GetObjectData method of the ObjectSurrogate class. There is now a type white list (ActivityBind or DependencyObject) that will apply unless an application flag is set.

private sealed class ObjectSurrogate : ISerializationSurrogate
{
	public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
	{
		if (!AppSettings.DisableActivitySurrogateSelectorTypeCheck &&
			!(obj is ActivityBind) && !(obj is DependencyObject))
		{
		   throw new ArgumentException("obj");
		}
		// ...
	}
}

Interesting! thanks for sharing! Since you are providing a fix in a PR, will close this issue.
Thanks!