codenote / google-security-research

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

Windows: Limited Bypass of Traverse Permissions in Kernel Object Manager #206

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Windows: Limited Bypass of Traverse Permissions in Kernel Object Manager
Platform: Windows 7 32/64 bit, Windows 8+
Class: Security Bypass

Windows has the concept of traversal permission which allows a user to open 
resources under a directory where they don't have read permissions on the 
directory itself, this can be expressed using the FILE_TRAVERSE permission or 
DIRECTORY_TRAVERSE permissions for the file system or object manager. Most 
tokens  have the SeChangeNotifyPrivilege available which is used to always 
grant traverse permissions regardless of the actual DACL on the object.

When a token doesn't have this privilege (say the Anonymous token, or something 
like the heavily restricted Chrome sandbox token) it falls back to the access 
check. However there's some unusual behaviour in the SeFastTraverseCheck method 
which could grant traverse permissions to tokens which wouldn't normally be 
able to get it. 

The SeFastTraverseCheck enumerates a directory's DACL for any access allowed 
ACE granting the Everyone group traverse permissions. It doesn't take into 
account whether the caller actually has the Everyone group enabled. If this 
check succeeds then it doesn't perform the full access check. This can give a 
very limited token traverse permissions to parts of the object manager, for 
example the root directory, \Devices, \RPC Control etc.

At least in the development of the Chrome sandbox there was an assumption that 
the traverse permission is enforced consistently, certainly when running with a 
restricted token (which blocks NULL DACL access for example). However because 
of this limitation it's possible for low privilege chrome code to access some 
device objects where it shouldn't be possible even determine they exist. 

Looking at the implementation of SeFastAccessCheck it does check the Access 
State flags for the flag 0x10 and fails if it's set. This might correspond to 
the Token flag TOKEN_IS_RESTRICTED however looking at SeCreateAccessState this 
flag is never set so it isn't clear what its purpose is. 

I don't really expect this will be considered a bulletin class issue, if it's 
considered an issue at all. It's possible it's by design however I'm reporting 
as it does cause minor security impact for Chrome and it's in a security 
related area. If I were to guess this code is probably a relic of when tokens 
typically had the Everyone group (including the Anonymous token) which is no 
longer a safe assumption to make.

Attached is a simple PoC which demonstrates the issue for execution on Windows 
7/8. Just execute the file and observe the displayed output. I've verified that 
the bypass occurs due to success in the SeFastAccessCheck method. 

Expected Result:
Both calls to open an non-existent name should return ERROR_ACCESS_DENIED (5)

Observed Result:
First check fails with ERROR_ACCESS_DENIED while second fails with 
ERROR_FILE_NOT_FOUND (2) indicating that traversal permissions were granted.

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 2 Dec 2014 at 2:27

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by fors...@google.com on 2 Dec 2014 at 5:53

GoogleCodeExporter commented 9 years ago
Correspondance Date: 16 Jan 2015

< Microsoft have responded to indicate they do not consider this issue meets 
the bar of a security bulletin. 

This was the expected response. Marking as WontFix and removing view 
restriction. 

Original comment by fors...@google.com on 16 Jan 2015 at 7:58