Analysis on the vulnerability of CVE-2014-1806. NET Remoting Services
0x00 Introduction
Microsoft. NET Remoting is a distributed processing method that provides a framework that allows an object to interact with another object through an application domain. A few days ago, James Forshaw released the CVE-2014-1806. NET Remoting Services Vulnerability exploitation program, which took some time to perform a simple debugging analysis.
First install the. NET Framework v4.0.30319 that contains the vulnerability and run the poc code. You can see that the program is successfully executed.
0x01 analysis
After analyzing the poc code, you can see the following code: CreateRemoteClass. The MakeCall template function builds the request data sent to the server based on the parameter information and obtains the server execution result. The static object SendRequest (object o, bool remote) functions are used to serialize objects, construct and send protocol data packets, and parse execution results.
For example, MakeCall (_ Uri. AbsolutePath, GetStaticMethod (typeof (Path), "GetTempPath") is used to call the GetTempPath method of the Path object on the remote server and return the execution result. The code in Poc is used to upload and compile RemoteClass on the remote server. cs, IRemoteClass. cs, InstallClass. the cs file obtains the Installer. dll, and then install Installer. dll to create the object entity of IRemoteClass. After obtaining the IRemoteClass object, you can call its method to execute any command.
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(); }}
You can use WireShark to capture packets to verify the entire data interaction process, including File Upload. The Installer. dll is also generated in the % TEMP % directory of the server.
To understand the data processing process of the server, set a breakpoint for CreateProcessW through windbg, and observe the program's managed code call stack through the sos. dll extension.
The System. Runtime. Remoting. dll is analyzed by hosting the Code call stack and using. NET Reflector.
The System. runtime. remoting. channels. tcp. tcpServerTransportSink. the ServiceRequest method uses ITransportHeaders requestHeaders = handler. readHeaders () and Stream requestStream = handler. getRequestStream () obtains the stream information of the protocol header and the requested object.
Then call System. runtime. remoting. channels. binaryServerFormatterSink. processMessage method, which uses requestMsg = CoreChannel. deserializeBinaryRequestMessage (uRI, requestStream, this. _ strictBinding, this. typeFilterLevel) deserializes the requested object stream. After successful deserialization, the System is called. runtime. remoting. channels. dispatchChannelSink. processMessage.
After simple judgment in System. Runtime. Remoting. Channels. DispatchChannelSink. ProcessMessage, ChannelServices. DispatchMessage (sinkStack, requestMsg, out responseMsg) is called directly to send messages.
In DispatchMessage, IsMethodReallyPublic (methodBase) and RemotingServices. IsMethodAllowedRemotely (methodBase) determine whether remote call methods are allowed. If conditions are met, further processing is performed and the method is called.
The remote identity is not validated throughout the process, remoting provides remote methods to obtain the CodeDomProvider object on the server through CreateInstance, compile the source code through the CompileAssemblyFromSource method of CodeDomProvider, and install the Installer. dll, and finally create an IRemoteClass class object to execute commands.
0x02 patch
Microsoft Security advisories MS14-026 mentions that security updates to this vulnerability are ensured by helping. NET Framework correctly enforces security controls for the application memory to solve the vulnerability, that is, it adopts a work und that only allows authenticated clients to interact with vulnerable servers.
By patching win7 sp1with ndp40-kb2931365-x86.exe, compare the System. Runtime. Remoting. dll System. Runtime. Remoting. Channels. BinaryServerFormatterSink. ProcessMessage method before and after the patch, you can see more code.
When you run the previous poc code, an exception is thrown on the server. The message is not processed because the value of allowTransparentProxyMessageValue is false, which is consistent with the one described in the Security Bulletin. If the value of allowTransparentProxyMessageValue is true, the process of the program is the same as that when no patch is installed.