New issue
Advanced search Search tips
Starred by 3 users
Status: Fixed
Owner:
Closed: Jan 2015
Cc:



Sign in to add a comment
Windows: Limited Bypass of Traverse Permissions in Kernel Object Manager
Project Member Reported by forshaw@google.com, Dec 2 2014 Back to list
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.
 
poc.zip
46.8 KB Download
Project Member Comment 1 by forshaw@google.com, Dec 2 2014
Labels: MSRC-21132
Project Member Comment 2 by forshaw@google.com, Jan 16 2015
Labels: -Restrict-View-Commit PublicOn-2015-Jan-16
Status: WontFix
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. 
Comment 3 Deleted
Project Member Comment 4 by forshaw@google.com, Nov 30 2016
Labels: -Severity-Low Severity-low
Status: Fixed
Interestingly this seems to now be fixed at least in the latest few major builds of Windows 10 (10586+ at least). Turns out it was really a bug in SeCreateAccessState after all.

SeFastTraverseCheck is doing a check for the TOKEN_IS_RESTRICTED flag and failing early (which would lead to a bypass of traversal privileges for Chrome etc.) however SeCreateAccessState was never setting that flag in the ACCESS_STATE Flags member which means that the check was bypassed.

Quite what prompted Microsoft to fix it I don't know, but on the whole it's good. Though one wonders what else this "mistake" broke :-)
Project Member Comment 5 by forshaw@google.com, Nov 30 2016
For anyone who's wondering if this is unusual for Microsoft that they fixed it so long after reporting, not really. If MSRC and by inference the product team do not consider the issue to meet their bar for a security bulletin (as mentioned in comment #2) then they'll tend to not fix it in a patch. However they do leave themselves open to fixing it a later update of the platform, which for Win10 is becoming more frequent. In this case the fix occurred (and has not been backported AFAIK). It's possible it might have been fixed inadvertently as effectively SeCreateAccessState had a bug which might have affected other user's of the API.

The trouble with this approach is there's never any credit or notification for the fix and so I was under the impression that this issue still existed.
Comment 6 by chrco...@gmail.com, Dec 1 2016
Why do you guys consider it fixed when its not fixed in win8.1 and7?

There seems to be no pressure o nmicrosoft to fix things on those 2 OS versions which by the way are not EOL.
Sign in to add a comment