一、前言
最近几天国外安全研究员Soroush Dalili(@irsdl)公布了.NET Remoting应用程序可能存在反序列化安全风险,当服务端使用HTTP信道中的SoapServerFormatterSinkProvider类作为信道接收器并且将自动反序列化TypeFilterLevel属性设置为Full的时候,会造成反序列化漏洞,从而实现远程RCE攻击。本文笔者从原理和代码审计的视角做了相关介绍和复现,并且归纳成.NET反序列化漏洞系列课程中的第五课。
前文回顾:
.NET高级代码审计之XmlSerializer反序列化漏洞
二、 .NETRemoting概念
.NET Remoting是一种分布式应用解决方案,它允许不同AppDomain(应用程序域)之间进行通信,这里的通信可以是在同一个进程中进行或者一个系统中的不同进程间进行的通信。.NET Remoting框架也提供了多种服务,包括激活和生存期支持,以及负责与远程应用程序进行消息传输的通道。应用程序可在重视性能的场景下使用二进制数据传输,在需要与其他远程处理框架进行交互的场景下使用 XML 数据传输。在从一个AppDomain向另一个AppDomain传输消息时,所有的XML数据都使用 SOAP 协议,总体看.NET Remoting有以下三点优势:
三、 .NETRemoting信道和协议
信道是Server和Client进行通信用的,在.NET Remoting中提供了三种信道类型,
IpcChannel提供了使用Windows进程间通信(IPC)系统在同一计算机上的应用程序域之间传输消息的机制。在同一计算机上的应用程序域之间进行通信时,IPC信道比TCP或HTTP信道要快得多。但是IPC只在本机应用之间通信。所以,在客户端和服务端在同一台机器时,我们可以通过注册IpcChannel来提高Remoting的性能。但如果客户端和服务端不在同一台机器时,我们不能注册IPCChannel,在此不多介绍。
TcpChannel提供了基于Socket 的传输工具,使用Tcp协议来跨越Remoting边界传输序列化的消息流。默认使用二进制格式序列化消息对象,具有更高的传输性能,适用于局域网。

四、 攻击原理
研究漏洞之前先普及下HttpChannel的相关基础知识,HttpChannel类使用 SOAP 协议在远程对象之间传输消息,并且符合SOAP1.1的标准,所有的消息都是通过SoapFormatter传递,此格式化器会将消息转换为 XML数据并进行序列化,同时向数据流中添加所需的SOAP标头。如果指定了二进制格式化程序,则会创建二进制数据流。随后,将使用 HTTP 协议将数据流传输至目标URI。HttpChannel分类如图



4.1 远程对象
图中的RemoteObject类,这是一个远程对象,看下微软官方的定义
RemoteObject继承自MarshalByRefObject类,MarshalByRefObject类(按引用封送)支持远程处理的应用程序中跨应用程序域(AppDomain)边界访问对象,同一应用程序域中的对象直接通信。不同应用程序域中的对象的通信方式有两种:跨应用程序域边界传输对象副本、通过代理交换消息,MarshalByRefObject类本质上通过引用代理交换消息来跨应用程序域边界进行通信的对象的基类。
4.2 服务端
创建服务端的信道分为HttpServerChannel、HttpChannel,其中HttpServerChannel类有多个重载方法,需要知道和漏洞相关的两个重载是发生在参数IServerChannelSinkProvider,它表示服务端远程消息流的信道接收器
IServerChannelSinkProvider派生出多个类,例如BinaryServerFormatterSinkProvider、SoapServerFormatterSinkProvider类,如下图





使用下列三种重载方法实现传入参数SoapServerFormatterSinkProvider
Ø 满足攻击者需求的第1个攻击重载方法是publicHttpServerChannel(IDictionary properties, IServerChannelSinkProvidersinkProvider);
这里笔者用VulnerableDotNetHTTPRemoting项目中的VulnerableDotNetHTTPRemotingServer类来改写官方Demo 。IDictionary集合存放当前通道的配置信息,如图
Ø 满足攻击者需求的第2个攻击重载方法是publicHttpServerChannel(string name, int port, IServerChannelSinkProvidersinkProvider);
Ø 满足攻击者需求的第3个攻击方法是位于HttpChannel类下的 public HttpChannel(IDictionary properties,IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProviderserverSinkProvider)
VulnerableDotNetHTTPRemoting项目中用到就是第三种攻击方法,由于.NET Remoting客户端在攻击中用途不大,故笔者不做赘述。
五、打造Poc
国外研究者发现Microsoft.VisualStudio.Text.UI.Wpf.dll 中的Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties类实现了ISerializable接口,这个接口可以对序列化/反序列化的数据进行完全的控制,并且还避免了反射机制, 但有个问题Microsoft.VisualStudio.Text.UI.Wpf.dll需要安装VisualStudio,在非开发主机上不会安装,但研究者后来发现Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties类在Windows默认安装的Microsoft.PowerShell.Editor.dll里也同样存在,反编译得到源码,







还有一处需要注意,HTTP请求有个扩展方法M-POST,其中的其中的M表示Mandatory(必须遵循的,强制的),如果一个HTTP请求包含至少一个强制的扩充声明,那么这个请求就称为强制的请求。强制请求的请求方法名字必须带有“M-”前缀,例如,强制的POST方法称为M-POST,这样的请求方式或许能更好的躲避和穿透防护设备。
六、代码审计
6.1 SoapServerFormatterSinkProvider
从SoapServerFormatterSinkProvider类分析来看,需要满足属性TypeFilterLevel的值等于TypeFilterLevel.Full,可触发的通道包括了HttpChannel类、HttpServerChannel类,这个攻击点的好处在于发送HTTP SOAP消息,可很好的穿透防火墙。
6.2 BinaryServerFormatterSinkProvider
从BinaryServerFormatterSinkProvider类分析来看,也需要满足属性TypeFilterLevel的值等于TypeFilterLevel.Full,可触发的通道包括了TcpChannel类、TcpServerChannel类,这个攻击点可反序列化二进制文件,笔者由于时间仓促,暂时不做分析跟进,有兴趣的朋友可自行研究。
七、复盘
笔者将VulnerableDotNetHTTPRemoting项目部署到虚拟机,运行Server端,打开了本地端口1234

八、总结
.NET Remoting技术已经出来很多年了,现在微软主推WCF来替代它,在开发中使用概念越来越低,从漏洞本身看只要没有设置SoapServerFormatterSinkProvider类属性TypeFilterLevel=Full就不会产生反序列化攻击(默认就是安全的)。后续笔者将陆续推出高质量的.NET反序列化漏洞文章,欢迎大伙持续关注,交流,更多的.NET安全和技巧可关注实验室公众号。
*本文作者:Ivan1ee@360云影实验室,转载请注明来自FreeBuf.COM
来源:freebuf.com 2019-03-26 11:30:35 by: 云影实验室











