.NET 反序列化 GetterSettingsPropertyValue 攻击链

0x01 链路1 SettingsPropertyValue

SettingsPropertyValue位于命名空间 System.Configuration,用于应用程序存储和检索设置的值,此类具有Name、IsDirty、Deserialized、PropertyValue、SerializedValue等多个公共成员,其中SerializedValue属性用于获取或者设置序列化的值,便于持久化存储,内部调用方法SerializePropertyValue,如下图

调用BinaryFormatter格式化器进行序列化,因此从构造反序列化漏洞的视角看,需要将Ysoserail.Net生成的BinaryFormatter攻击载荷赋值给SerializedValue成员

而反序列化触发漏洞由此类的另外一个成员PropertyValue负责实现,当该属性被外部使用时会触发getter,从而触发内部this.Deserialize()方法

0x02 链路2 Winform

此条攻击链路涉及ComboBox、ListBox、CheckedListBox这三个不同的Windows Froms桌面应用开发常见的用户控件类,反序列化漏洞链路实现上均类似,因此以ComboBox链作为样本进行原理分析。

从图上我们发现ComboBox继承于父类ListControl,ListControl是一切列表控件的基类,其中DisplayMember成员属性返回一个string类型,getter时通过this.displayMember.BindingMember可绑定SettingsPropertyValue链路触发反序列化操作的PropertyValue属性名称,如下图所示

另外ComboBox类在声明时拥有多个特性,其中成员Items和Text被指定为默认特性,分别为[DefaultProperty("Items")]、[DefaultBindingProperty("Text")],因此在getter和setter时会执行一些默认的行为。

Text成员

首先Text在setting时内部调用base.GetItemText获取item每项中的文本值,经过一系列调用,最后FilterItemOnProperty通过PropertyDescriptor对象获取item的属性描述,然后使用GetValue方法获取每项的值

因此当攻击者控制item选项以及在DisplayMember属性绑定了恶意的值时会变得非常不安全。

因此当攻击者控制item选项以及在DisplayMember属性绑定了恶意的值时会变得非常不安全。

Items成员

再回过头来看ComboBox类另外一个成员Items,内部实现上调用ObjectCollection,如下图所示

实际上是一组可以存储任意类型的列表项集合,因此我们可以控制Items集合添加SettingPropertyValue反序列化链。

0x03 编码实践

根据上述两条链路的原理性分析,我们可以尝试着构造用于恶意反序列化的攻击代码如下

payload = @"{
    '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089',
    'Items':[
        " + spvPayload + @"
    ], 
    'DisplayMember':'PropertyValue',
    'Text':'watever'
}";

ComboBox的DisplayMember属性值为SettingPropertyValue属性PropertyValue,根据前文得知PropertyValue被访问时会调用BinaryFormatter执行反序列化。Items集合由包含了攻击载荷的变量spvPayload 构建,具体代码如下

string spvPayload = @"{
    '$type':'System.Configuration.SettingsPropertyValue, System',
    'Name':'test',
    'IsDirty':false,
    'SerializedValue':
        {
            '$type':'System.Byte[], mscorlib',
            '$value':'" + b64encoded + @"'
        },
    'Deserialized':false
}";

SerializedValue是一组进行Base64编码后基于BinaryFormatter生成的攻击载荷,最后通过JsonConvert.DeserializeObject(s1, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }),完成整条攻击链路的反序列化,成功启动本地计算器进程,如下图所示

欢迎加入星球

为了更好地应对基于.NET技术栈的风险识别和未知威胁,dotNet安全矩阵星球从创建以来一直聚焦于.NET领域的安全攻防技术,定位于高质量安全攻防星球社区,也得到了许多师傅们的支持和信任,通过星球深度连接入圈的师傅们,一起推动.NET安全高质量的向前发展。经过运营团队成员商议一致同意给到师傅们最大优惠力度,只需129元就可以加入我们。

星球汇聚了各行业安全攻防技术大咖,并且每日分享.NET安全技术干货以及交流解答各类技术等问题,社区中发布很多高质量的.NET安全资源,可以说市面上很少见,都是干货。其中主题包括.NET Tricks、漏洞分析、内存马、代码审计、预编译、反序列化、webshell免杀、命令执行、C#工具库等等,后续还会倾力打造专刊、视频等配套学习资源,循序渐进的方式引导加深安全攻防技术提高以及岗位内推等等服务。

 

posted @ 2023-10-30 19:29  Ivan1ee  阅读(60)  评论(0编辑  收藏  举报