New issue
Advanced search Search tips
Starred by 5 users

Issue metadata

Status: Fixed
Owner:
Closed: Jul 2015
Cc:



Sign in to add a comment

Windows: DCOM DCE/RPC Local NTLM Reflection Elevation of Privilege

Project Member Reported by forshaw@google.com, Apr 9 2015 Back to list

Issue description

Windows: DCOM DCE/RPC Local NTLM Reflection Elevation of Privilege
Platform: Windows 8.1 Update (not tested on Windows 7, 10)
Class: Elevation of Privilege

Summary:
Local DCOM DCE/RPC connections can be reflected back to a listening TCP socket allowing access to an NTLM authentication challenge for LocalSystem user which can be replayed to the local DCOM activation service to elevate privileges. 

Description:

Note, before we start I realize that you didn’t fix the WebDAV => SMB one, you might conclude that this is a won’t fix as well but I couldn’t find good documentation on how to improve the security situation with DCOM-DCE/RPC to mitigate it (at least anything which seemed to work). Also the behaviour is slightly different. I did point out in the original report that WebDAV wasn’t necessarily the only way of getting an NTLM authentication challenge, with DCE/RPC being a specific example. Anyway on to the description. 

When a DCOM object is passed to an out of process COM server the object reference is marshalled in an OBJREF stream. For marshal-by-reference this results in an OBJREF_STANDARD stream being generated which provides enough information to the server to locate the original object and bind to it. Along with the identity for the object is a list of RPC binding strings (containing a TowerId and a string). This can be abused to connect to an arbitrary TCP port when an unmarshal occurs by specifying the tower as NCACN_IP_TCP and a string in the form “host[port]”. When the object resolver tries to bind the RPC port it will make a TCP connection to the specified address and if needed will try and do authentication based on the security bindings.

If we specify the NTLM authentication service in the bindings then the authentication will use basic NTLM. We just need to get a privileged COM service to unmarshal the object, we could do this on a per-service basis by finding an appropriate DCOM call which takes an object, however we can do it generically by abusing the activation service which takes a marshalled IStorage object and do it against any system service (such as BITS). So this gets us a reflected NTLM authentication challenge, but what to do with it? There are at least 3 uses for this:

1) Use the NTLM for reflection back to the local SMB service (as per the WebDAV version) but of course this is considered mitigated. 
2) Locally negotiate the NTLM which will give you back a full impersonation level token for LocalSystem (even done as a normal user). This is of most use for escaping Local Service/Network Service because you can combine this with SeImpersonatePrivilege for token kidnapping.
3) Reflect the NTLM back to a local RPC TCP endpoint, this is what we’ll do for a proof-of-concept. 

It turns out that a number of RPC endpoints over TCP enforce at least RPC_C_AUTHN_LEVEL_CALL or RPC_C_AUTHN_LEVEL_PKT level security on the RPC channel. This, like SMB signing, makes it difficult to do reflection attacks. However not all services do, for example the DCOM IRemoteSCMActivator service doesn’t seem to enforce signing for the call (only requires RPC_C_AUTHN_LEVEL_CONNECT). While by default it does require authentication as an administrator we get that from the LocalSystem NTLM reflection. This allows us to create any out-of-process COM object locally as LocalSystem (unless it’s already a COM service where it uses the identity of the service). 

While you can create the object there’s a problem, you can’t typically communicate with the object afterwards. Services such as WMI listen on TCP so can be accessed using the NTLM reflection afterwards however this enforces signing so any calls will fail. You can request a NCALRPC binding from the activation but this will be limited by the ability of the current user to bind to it. It turns out that our answer to this problem has already been used once, we can abuse the same IStorage marshalling in the activation process to initialize an object through IPersistFile or IPersistStorage before returning back to the caller. As long as you can find an object which runs out of process, can be initialized through one those interfaces and does something exploitable during initialization we can use it to elevate privileges.

A good example is everyone’s favourite COM object, the OLE Packager. As shown by various researchers, specifically Haifei Li (see https://blogs.mcafee.com/mcafee-labs/dropping-files-temp-folder-raises-security-concerns). This will drop arbitrary files to the user’s temporary folder during IPersistStorage initialization. The temporary folder for localsystem is %windir%\temp which is writable by normal authenticated users. Also while it’s a DLL server it is registered with an AppId supported DllSurrogate so we can create it out-of-process. 

Due to the way the target path during initialization is created it doesn’t look obvious how you’d exploit this, especially as we can’t create file level symbolic links as a normal user. One attack we can do is as we control the filename we can use the $INDEX_ALLOCATION trick to convert a directory junction to a file level symbolic link. However that leaves you with a timing issue as a call is made to PathFileExists which will then fall back into generating the temporary file. Considering the packager, if it fails to initialize causes heap corruption in Dllhost (seriously) this isn’t a good approach. 

Instead we can abuse the operation of PathFindFileName which has odd behaviour if the path ends with a slash, specifically it assumes the last component is the name plus the tailing slash, it doesn’t remove it. You also have to use forward slash otherwise it doesn’t work (you get an invalid name when generating the temporary file). So if we use the path, c:\path\somefile/ in the package it first checks %windir%\temp\somefile to see if it exists. We can drop a directory at that location so that the check continues to generate the temporary file. The code will then try %windir%\temp\somefile/ (2) which as Win32 handles both slashes tries to create a file inside a directory we control, which we set as a junction to a system directory (we can change the file name as well but that’s left as an exercise for the reader). 

Proof of Concept:

I’ve provided a PoC which creates an arbitrary file at local system privileges. In the PoC the file is typically called ‘ (2)’ or similar, however through combined junction/object manager symlink attacks this can be created with any name you like (just the PoC doesn’t bother to do so). 

The PoC has only been tested on 64 bit Windows 8.1 update.

1) Extract the PoC to a location on a local harddisk which is writable by a normal user
2) Execute Poc_DCERPCNTLMReflection_EoP.exe file as a normal user
3) There should be a ‘ (2)’ file created in the c:\windows directory with arbitrary content.

Expected Result:
The NTLM reflection should fail

Observed Result:
The NTLM reflection succeeds and an arbitrary file is created as a privileged user

Known Issues with the PoC:
1) If an existing instance of the package class is running as local system it will not reinitialize the object and the exploit will not work.
2) Sometimes the exploit fails completely during the reflection attack, this is typically indicated by a lot of error output being display to the console. Re-running the poc usually fixes this. 


This bug is subject to a 90 day disclosure deadline. If 90 days elapse without a broadly available patch, then the bug report will automatically become visible to the public.

 
poc.zip
107 KB Download
Project Member

Comment 1 by forshaw@google.com, Apr 9 2015

Labels: Id-21878
Project Member

Comment 2 by forshaw@google.com, Jul 7 2015

Correspondence Date: 7 July 2015

> Informed Microsoft that the deadline is about to be exceeded and asking if they want to use the grace period. 
Project Member

Comment 3 by forshaw@google.com, Jul 7 2015

Mitigations:

As with  issue 222  (https://code.google.com/p/google-security-research/issues/detail?id=222) which exploited a similar type of issue (and is currently unfixed) the exploitability of this for local privilege escalation is based on access to the network stack and in getting a local user to initiate the NTLM authentication. Mitigations technologies such as AppContainer (when not using the Local Network capability) or heavy sandboxing in general would make it very difficult to exploit. 

In the described PoC the attacker would also need to have permissions to write to Windows\Temp which removes any restrictive sandbox including IE PM, however there's not reason to believe another attack vector couldn't be used. 

While theoretically this could be exposed to remote attackers they would need to MITM a suitable NTLM authentication and find an exploitable object they could access after creation. Also it's not clear if the behaviour of the DCOM activator is due to it being communicated with via localhost rather than from a remote endpoint. 
Project Member

Comment 4 by hawkes@google.com, Jul 8 2015

Labels: -Restrict-View-Commit
Deadline exceeded -- automatically derestricting.
Project Member

Comment 5 by forshaw@google.com, Jul 8 2015

Labels: Deadline-Exceeded
No correspondence from MSRC was received about the use of the grace period. Also no other communication was received on this issue after the case number was issued on the 9th April.
Project Member

Comment 6 by forshaw@google.com, Jul 9 2015

Labels: Deadline-Grace Restrict-View-Commit
Re-restricted for the grace period at the request of Microsoft. 
Project Member

Comment 7 by forshaw@google.com, Jul 14 2015

Labels: -Id-21878 -Restrict-View-Commit MSRC-21878
Status: Fixed
Fixed in https://technet.microsoft.com/en-us/library/security/MS15-076

Sign in to add a comment