lovekurdt / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Windows: Silo Object Object Root Directory Elevation of Privilege #459

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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.

Original issue reported on code.google.com by fors...@google.com on 23 Jun 2015 at 1:40

Attachments:

GoogleCodeExporter commented 8 years ago
Assigned MSRC case number 30502

Original comment by fors...@google.com on 23 Jun 2015 at 4:54

GoogleCodeExporter commented 8 years ago
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. 

Original comment by fors...@google.com on 1 Jul 2015 at 10:07

GoogleCodeExporter commented 8 years ago
Removed view restriction.

Original comment by fors...@google.com on 8 Sep 2015 at 2:57