New issue
Advanced search Search tips
Starred by 2 users
Status: Invalid
Owner:
Closed: Jul 2015
Cc:



Sign in to add a comment
Windows: Silo Object Object Root Directory Elevation of Privilege
Project Member Reported by forshaw@google.com, Jun 23 2015 Back to list
Windows: Silo Object Object Root Directory Elevation of Privilege
Platform: Windows 10 build 10130, only tested 32 bit
Class: Elevation of Privilege

Summary:
The Silo Object functionality allows an unprivileged user to assign an arbitrary object manager root directory to a process, this can be used to trick kernel code into incorrectly accessing privileged resources leading to elevation of privilege. 

Description:

NOTE: This was tested on the latest available build on Windows 10. I don’t know if the final version will change the functionality to fix this vulnerability. 

Windows 10 has a new process isolation feature, Silos which are accessible through NtCreateSiloObject and you can then assign a process to that silo. One feature that silos give you is the ability to set an arbitrary root directory for the object manager for that process. This in itself doesn’t sound a major issue, however the issue is that kernel code must honour this root directory even when accessing normally secured resources such as the registry. A lot of kernel code makes assumptions that the root directory is not writeable by a normal user and also some components such as \Registry can’t be replaced, this assumption is broken with the ability to set an arbitrary root directory. 

Now it would seem that replacing the root object directory would prevent the process being able to access and modify existing object directories as you can’t cross link directories into a new path hierarchy (that I know of). However what you can do is create directories using NtCreateObjectDirectoryEx which takes a handle to a shadow directory. So you can create \myroot\Device which actually shadows the real \Device. Or you can create \DummyRoot which shadows the real root and gain access to everything you need. You only need QUERY/TRAVERSE privileges on the shadow directory to do this. However this only seems to work for read access, trying to write through to the shadow directory seems to cause it to try and ignore the shadow (which makes some sense). Therefore a different trick is needed for writing, in this case we can use the ProcessDeviceMap class for NtSetInformationProcess to set \??\ to be an arbitrary directory object, this does allow us to write to it. 

Now it’s just a case of finding some kernel code which you can abuse. Typical things to look for is any call to Zw* functions in the kernel such as ZwCreateFile or ZwCreateKey, there are a few places in the kernel you can use. I’m sure if you expanded out to drivers as well there would be even more. This must be in process so of special interest would be function calls and device object handling. So here’s a few:

1. NtGetNlsSectionPtr allows you to create an arbitrary named section (by using a symlink) to an arbitrary file. This only allows for read access but still could be useful. 
2. NtImpersonateAnonymousToken reads whether the token is allowed to have the everyone group or not from the registry each time you call this system call. So you can spoof the registry path (using symlinks again) to open an arbitrary key which gives the token everyone privilege. Probably not massively useful. 
3. ImageFileExecutionOptions when creating a new process you can specify arbitrary imagefile execution options again with registry spoofing (probably not that useful).
4.  SeGetTokenDeviceMap if the current token doesn’t have a device map associated with it when accessing \??\ it will create a new object directory in \Sessions\0\DosDevice with the LUID. By abusing S4U we can create a new token for the current user and get this to create an arbitrary object directory with permissions we control. The only real problem is it seems you’d need to exploit a race condition as you’d have to switch off impersonation to access the process device map but you’d have to do it quickly otherwise the entire machine locks up and bluescreens as it ends up in a loop and causes a stack overflow.
5. condrv.sys creates a new conhost.exe process so you could redirect the creation to another executable file you wouldn’t normally have access to bypassing executable permissions. 

I’ll admit it would be a shame if this functionality was locked down as I could see a use for it in the Chrome sandbox. 

Proof of Concept:

The PoC demonstrates the vulnerability by using the NtGetNlsSectionPtr issue. It’s been tested on 32 bit Windows 10 build 10130. It should work on 64 bit, but I’ve not checked. The password for the archive is ‘password’. 

1) Copy the PoC to a location on a local hard disk
2) Execute PoC as a normal user
3) If successful there should be a new section in \KnownDlls call ‘test’

Expected Result:
The kernel shouldn’t allow changing the dos device directory.

Observed Result:
A new section called test is created in a protected location

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.7z
58.4 KB Download
Project Member Comment 1 by forshaw@google.com, Jun 23 2015
Labels: MSRC-30502
Assigned MSRC case number 30502
Project Member Comment 2 by forshaw@google.com, Jul 1 2015
Status: Invalid
This functionality has been fixed in build 10158. The silo objects have been merged into job objects and a TCB privilege check placed around the setting of the root directory. However until it can be determined how to use this functionality we can't say for certain that it's not possible for a user application to ask for a silo'ed process to be created and the directory object isn't secure. 

Marking as Invalid but not opened yet until verified that the final RTM build is definitely not vulnerable. 
Project Member Comment 3 by forshaw@google.com, Sep 8 2015
Labels: -Restrict-View-Commit
Removed view restriction.
Sign in to add a comment