codenote / google-security-research

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

Windows: CreateProcessAsUser Impersonation Token Bypass #198

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Windows: CreateProcessAsUser Impersonation Token Bypass
Platform: Windows 8.1 Update, 2012, 2008, 7
Class: Security Bypass/Elevation of Privilege

The CreateProcessAsUser function is implemented by passing a token handle via a 
special Attribute (value 0x60002) to the underlying NtCreateUserProcess system 
call. All documentation indicates that this handle should be a primary token, 
the CreateProcessAsUser function will attempt to duplicate the token if 
necessary to make a primary token. The particular issue in this case is the 
NtCreateUserProcess and the functions it calls, such as 
PspReferenceTokenForNewProcess and SeAssignPrimaryToken never verify that it is 
a primary token. The only requirement on the token is the handle is opened with 
TOKEN_ASSIGN_PRIMARY_TOKEN privilege, which any impersonation token is granted.

This behaviour might be by design, however it runs contrary to both 
documentation and behaviour of similar functions. For example calling 
NtDuplicateToken on an impersonation token with Identification level to get a 
primary token gives a STATUS_BAD_IMPERSONATION_LEVEL error. Also calling 
NtSetInformationProcess with the ProcessAccessToken class does an explicit 
check before assignment, so that couldn’t be used either. 

This can be exploited in certain circumstances to elevate privileges where 
impersonation wouldn't allow it. For example if a LocalService or 
NetworkService service has SeAssignPrimaryTokenPrivilege (which they do by 
default) it can capture an impersonation token at identification level and 
convert that implicitly to a primary token just by calling CreateProcessAsUser. 
This allows service accounts to elevate to system or other user on the local 
system. This also affects things like the IIS worker processes (even when 
running in an AppPool) and probably SQL server as well. As this requires a 
privilege in order to work I wouldn’t have considered it a security issue, 
however considering the fixes done for “Token Kidnapping”, this is 
effectively the same thing with a different privilege requirement. It also 
effectively breaks some of the hardening done to the OS (such as limiting 
localsystem security level when making RPC calls) which with just impersonate 
privilege would not lead to elevation of privilege. 

For IIS on Windows 2012 I was also successful in using Kerberos S4U locally to 
create an impersonation token at identification level for any user on the 
system (and presumably kerberos users, so perhaps domain admins). This token 
can then be applied to a new process. Of course this wouldn’t be a valid 
login session but it would be enough to elevate to local administrator 
privileges. I couldn’t seem to get this to work on Windows 7/2008 (the APIs 
gave me invalid parameter errors) nor could I get it work in LocalService 
account (it did work with NetworkService), possibly because they’re not 
really logged in users so the LsaLogonUser function failed. Still for IIS it 
would be a trivial privilege escalation in a shared hosting environment if 
default AppPools or NetworkService were in use. Just like the original “Token 
Kidnapping” scenarios. In other scenarios getting hold of the local system 
token isn’t that hard.

In theory this might be exploitable for IE EPM escapes or restricted token 
escapes as you are allowed to assign any token which is at the same IL as you, 
is either a child (the token’s parent ID matches your primary token) or is a 
sibling (parent ID and auth ID match), and is running in the same session. This 
applies to restricted and appcontainer, although there might be other checks 
that I didn’t see which would cause this to fail. Also it is reliant on being 
able to lower the IL of a captured token, which I’ve not tested. 

Some services on a Windows which could be abused (if you could get code to run 
in them) are:

TerminalServices
COM+
WinHTTP Web Proxy Auto-Discover
User-mode Driver Framework Hosting Process
IIS
SQL Server

Provided is a PoC which exploits the issue on Windows Server 2012 R2 with IIS 
7.5.

Install IIS 7.5 and ASP.NET with support for .NET version 4
Install the supplied PoC as an application with using the default AppPool user 
or as NetworkService. Only LocalSystem elevation will work as LocalService.
Browse to the application, fill in a command line to execute (or leave as 
notepad.exe) and the local user to impersonate which must be enabled and 
allowed to logon. You can leave as LocalSystem which will attempt to steal an 
impersonation token from the BITS service. Alternative use a different local 
user which will use S4U to get the token (note as IIS doesn’t have TCB 
privilege this logon will be identification only, so this isn't a direct 
elevation route via impersonation)
Click the button and observe the output. It should print success and you should 
find a new process running under the expected user account. 

Expected result: 
Access would be denied to create a new process running as an arbitrary user
Observed result:
The LogonS4U process creates an impersonation token then is able to convert 
that to a primary token leading to elevation of privilege

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 25 Nov 2014 at 7:29

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by fors...@google.com on 26 Nov 2014 at 2:14

GoogleCodeExporter commented 9 years ago
Update on IE EPM. I've managed to test it out and it seems it does work to 
create a new process running with the normal user token, except with a Low IL 
(that's a requirement of the vulnerability). Effectively this allows you to go 
from EPM to the equivalent of PM, which from MS perspective is _not a security 
boundary_ therefore I would class that as a sandbox escape. 

This doesn't work on restricted tokens however due to the differences in how 
restricted tokens are implemented. When creating a lowbox token the token is 
duplicated and then all the lowbox data is added additional to the token. This 
leaves the Token ParentID LUID the same as the original token, which is 
probably the logon token in most cases. In restricted tokens the ParentID LUID 
is set to the original token's ID so capturing the logon token doesn't help 
because it will fail the sibling check. It could be used to impersonate a 
slightly higher privileged token in limited circumstances if it was a token 
which was _less_ restrictive than the original. For example between chrome 
renderer and gpu processes which are generated from the same parent token. 

I've attached a PoC for the IE EPM sandbox "escape" which uses 
https://code.google.com/p/google-security-research/issues/detail?id=189 to get 
a callback on a named pipe to acquire the impersonation token. 

Original comment by fors...@google.com on 28 Nov 2014 at 4:56

Attachments:

GoogleCodeExporter commented 9 years ago

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

GoogleCodeExporter commented 9 years ago
Bulletin: https://technet.microsoft.com/library/security/MS15-015

Original comment by cev...@google.com on 10 Feb 2015 at 7:11

GoogleCodeExporter commented 9 years ago
Remove view restriction

Original comment by fors...@google.com on 18 Feb 2015 at 8:29