利用链分析
TextFormattingRunProperties
实现了System.Runtime.Serialization.ISerializable
接口,故其在序列化以及反序列化过程中会自动执行GetObjectData
以及特定的构造方法internal TextFormattingRunProperties(SerializationInfo info, StreamingContext context)

我们直接从反序列化时执行的特殊构造方法创建对象的过程开始。
在调用构造方法创建对象期间会调用GetObjectFromSerializationInfo
方法从serializationInfo
中获取属性值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| internal TextFormattingRunProperties(SerializationInfo info, StreamingContext context) { this._foregroundBrush = (Brush)this.GetObjectFromSerializationInfo("ForegroundBrush", info); this._backgroundBrush = (Brush)this.GetObjectFromSerializationInfo("BackgroundBrush", info); this._size = (double?)this.GetObjectFromSerializationInfo("FontRenderingSize", info); this._hintingSize = (double?)this.GetObjectFromSerializationInfo("FontHintingSize", info); this._foregroundOpacity = (double?)this.GetObjectFromSerializationInfo("ForegroundOpacity", info); this._backgroundOpacity = (double?)this.GetObjectFromSerializationInfo("BackgroundOpacity", info); this._italic = (bool?)this.GetObjectFromSerializationInfo("Italic", info); this._bold = (bool?)this.GetObjectFromSerializationInfo("Bold", info); this._textDecorations = (TextDecorationCollection)this.GetObjectFromSerializationInfo("TextDecorations", info); this._textEffects = (TextEffectCollection)this.GetObjectFromSerializationInfo("TextEffects", info); string text = (string)this.GetObjectFromSerializationInfo("CultureInfoName", info); this._cultureInfo = ((text == null) ? null : new CultureInfo(text)); FontFamily fontFamily = this.GetObjectFromSerializationInfo("FontFamily", info) as FontFamily; bool flag = fontFamily != null; ... }
|
在GetObjectFromSerializationInfo
方法中会调用XamlReader.Parse
方法对从serializationInfo
获取的字符串进行解析,通过上一篇文章从三味书屋到百草堂,从XmlSerializer到BinnaryFormatter之XmlSerializer反序列化漏洞ObjectDataProvider利用链我们知道
XamlReader
的Parse
方法可以解析XAML
字符串并导致命令执行。所以我们只需要将TextFormattingRunProperties
某一个字段的值设置为符合XamlReader
解析条件的Payload
即可进行反序列化漏洞攻击。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| private object GetObjectFromSerializationInfo(string name, SerializationInfo info) { string @string = info.GetString(name); bool flag = @string == "null"; object result; if (flag) { result = null; } else { result = XamlReader.Parse(@string); }
|
serializationInfo
中的值由GetObjectData
方法在序列化的时候设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public void GetObjectData(SerializationInfo info, StreamingContext context) { bool flag = info == null; if (flag) { throw new ArgumentNullException("info"); } info.AddValue("BackgroundBrush", this.BackgroundBrushEmpty ? "null" : XamlWriter.Save(this.BackgroundBrush)); info.AddValue("ForegroundBrush", this.ForegroundBrushEmpty ? "null" : XamlWriter.Save(this.ForegroundBrush)); info.AddValue("FontHintingSize", this.FontHintingEmSizeEmpty ? "null" : XamlWriter.Save(this.FontHintingEmSize)); info.AddValue("FontRenderingSize", this.FontRenderingEmSizeEmpty ? "null" : XamlWriter.Save(this.FontRenderingEmSize)); info.AddValue("TextDecorations", this.TextDecorationsEmpty ? "null" : XamlWriter.Save(this.TextDecorations)); info.AddValue("TextEffects", this.TextEffectsEmpty ? "null" : XamlWriter.Save(this.TextEffects)); info.AddValue("CultureInfoName", this.CultureInfoEmpty ? "null" : XamlWriter.Save(this.CultureInfo.Name)); info.AddValue("FontFamily", this.TypefaceEmpty ? "null" : XamlWriter.Save(this.Typeface.FontFamily)); info.AddValue("Italic", this.ItalicEmpty ? "null" : XamlWriter.Save(this.Italic)); info.AddValue("Bold", this.BoldEmpty ? "null" : XamlWriter.Save(this.Bold)); info.AddValue("ForegroundOpacity", this.ForegroundOpacityEmpty ? "null" : XamlWriter.Save(this.ForegroundOpacity)); info.AddValue("BackgroundOpacity", this.BackgroundOpacityEmpty ? "null" : XamlWriter.Save(this.BackgroundOpacity)); bool flag2 = !this.TypefaceEmpty; if (flag2) { info.AddValue("Typeface.Style", XamlWriter.Save(this.Typeface.Style)); info.AddValue("Typeface.Weight", XamlWriter.Save(this.Typeface.Weight)); info.AddValue("Typeface.Stretch", XamlWriter.Save(this.Typeface.Stretch)); } }
|
因为在TextFormattingRunProperties
对象创建时第一个被获取的属性是ForegroundBrush
,所以我们在创建TextFormattingRunProperties
对象时可以将ForegroundBrush
设置为我们的Payload
`