{"action":"created","issue":{"url":"https://api.github.com/repos/chrsmith/google-security-research/issues/198","labels_url":"https://api.github.com/repos/chrsmith/google-security-research/issues/198/labels{/name}","comments_url":"https://api.github.com/repos/chrsmith/google-security-research/issues/198/comments","events_url":"https://api.github.com/repos/chrsmith/google-security-research/issues/198/events","html_url":"https://github.com/chrsmith/google-security-research/issues/198","id":58937182,"number":198,"title":"Windows: CreateProcessAsUser Impersonation Token Bypass","user":{"login":"GoogleCodeExporter","id":9614759,"avatar_url":"https://avatars.githubusercontent.com/u/9614759?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCodeExporter","html_url":"https://github.com/GoogleCodeExporter","followers_url":"https://api.github.com/users/GoogleCodeExporter/followers","following_url":"https://api.github.com/users/GoogleCodeExporter/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCodeExporter/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCodeExporter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCodeExporter/subscriptions","organizations_url":"https://api.github.com/users/GoogleCodeExporter/orgs","repos_url":"https://api.github.com/users/GoogleCodeExporter/repos","events_url":"https://api.github.com/users/GoogleCodeExporter/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCodeExporter/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/auto-migrated","name":"auto-migrated","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/CCProjectZeroMembers","name":"CCProjectZeroMembers","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/CVE-2015-0062","name":"CVE-2015-0062","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Deadline-90","name":"Deadline-90","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Finder-forshaw","name":"Finder-forshaw","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Fixed-2015-Feb-10","name":"Fixed-2015-Feb-10","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/MSRC-21092","name":"MSRC-21092","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Product-Windows-Kernel","name":"Product-Windows-Kernel","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Reported-2014-Nov-25","name":"Reported-2014-Nov-25","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Severity-Medium","name":"Severity-Medium","color":"ededed"},{"url":"https://api.github.com/repos/chrsmith/google-security-research/labels/Vendor-Microsoft","name":"Vendor-Microsoft","color":"ededed"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-02-25T17:17:36Z","updated_at":"2015-02-25T17:17:37Z","closed_at":"2015-02-25T17:17:36Z","body":"```\nWindows: CreateProcessAsUser Impersonation Token Bypass\nPlatform: Windows 8.1 Update, 2012, 2008, 7\nClass: Security Bypass/Elevation of Privilege\n\nThe CreateProcessAsUser function is implemented by passing a token handle via a \nspecial Attribute (value 0x60002) to the underlying NtCreateUserProcess system \ncall. All documentation indicates that this handle should be a primary token, \nthe CreateProcessAsUser function will attempt to duplicate the token if \nnecessary to make a primary token. The particular issue in this case is the \nNtCreateUserProcess and the functions it calls, such as \nPspReferenceTokenForNewProcess and SeAssignPrimaryToken never verify that it is \na primary token. The only requirement on the token is the handle is opened with \nTOKEN_ASSIGN_PRIMARY_TOKEN privilege, which any impersonation token is granted.\n\nThis behaviour might be by design, however it runs contrary to both \ndocumentation and behaviour of similar functions. For example calling \nNtDuplicateToken on an impersonation token with Identification level to get a \nprimary token gives a STATUS_BAD_IMPERSONATION_LEVEL error. Also calling \nNtSetInformationProcess with the ProcessAccessToken class does an explicit \ncheck before assignment, so that couldn’t be used either. \n\nThis can be exploited in certain circumstances to elevate privileges where \nimpersonation wouldn't allow it. For example if a LocalService or \nNetworkService service has SeAssignPrimaryTokenPrivilege (which they do by \ndefault) it can capture an impersonation token at identification level and \nconvert that implicitly to a primary token just by calling CreateProcessAsUser. \nThis allows service accounts to elevate to system or other user on the local \nsystem. This also affects things like the IIS worker processes (even when \nrunning in an AppPool) and probably SQL server as well. As this requires a \nprivilege in order to work I wouldn’t have considered it a security issue, \nhowever considering the fixes done for “Token Kidnapping”, this is \neffectively the same thing with a different privilege requirement. It also \neffectively breaks some of the hardening done to the OS (such as limiting \nlocalsystem security level when making RPC calls) which with just impersonate \nprivilege would not lead to elevation of privilege. \n\nFor IIS on Windows 2012 I was also successful in using Kerberos S4U locally to \ncreate an impersonation token at identification level for any user on the \nsystem (and presumably kerberos users, so perhaps domain admins). This token \ncan then be applied to a new process. Of course this wouldn’t be a valid \nlogin session but it would be enough to elevate to local administrator \nprivileges. I couldn’t seem to get this to work on Windows 7/2008 (the APIs \ngave me invalid parameter errors) nor could I get it work in LocalService \naccount (it did work with NetworkService), possibly because they’re not \nreally logged in users so the LsaLogonUser function failed. Still for IIS it \nwould be a trivial privilege escalation in a shared hosting environment if \ndefault AppPools or NetworkService were in use. Just like the original “Token \nKidnapping” scenarios. In other scenarios getting hold of the local system \ntoken isn’t that hard.\n\nIn theory this might be exploitable for IE EPM escapes or restricted token \nescapes as you are allowed to assign any token which is at the same IL as you, \nis either a child (the token’s parent ID matches your primary token) or is a \nsibling (parent ID and auth ID match), and is running in the same session. This \napplies to restricted and appcontainer, although there might be other checks \nthat I didn’t see which would cause this to fail. Also it is reliant on being \nable to lower the IL of a captured token, which I’ve not tested. \n\nSome services on a Windows which could be abused (if you could get code to run \nin them) are:\n\nTerminalServices\nCOM+\nWinHTTP Web Proxy Auto-Discover\nUser-mode Driver Framework Hosting Process\nIIS\nSQL Server\n\nProvided is a PoC which exploits the issue on Windows Server 2012 R2 with IIS \n7.5.\n\nInstall IIS 7.5 and ASP.NET with support for .NET version 4\nInstall the supplied PoC as an application with using the default AppPool user \nor as NetworkService. Only LocalSystem elevation will work as LocalService.\nBrowse to the application, fill in a command line to execute (or leave as \nnotepad.exe) and the local user to impersonate which must be enabled and \nallowed to logon. You can leave as LocalSystem which will attempt to steal an \nimpersonation token from the BITS service. Alternative use a different local \nuser which will use S4U to get the token (note as IIS doesn’t have TCB \nprivilege this logon will be identification only, so this isn't a direct \nelevation route via impersonation)\nClick the button and observe the output. It should print success and you should \nfind a new process running under the expected user account. \n\nExpected result: \nAccess would be denied to create a new process running as an arbitrary user\nObserved result:\nThe LogonS4U process creates an impersonation token then is able to convert \nthat to a primary token leading to elevation of privilege\n\nThis bug is subject to a 90 day disclosure deadline. If 90 days elapse\nwithout a broadly available patch, then the bug report will automatically\nbecome visible to the public.\n\n\n```\n\n-----\nOriginal issue reported on code.google.com by `fors...@google.com` on 25 Nov 2014 at 7:29\n\nAttachments:\n* [poc.zip](https://storage.googleapis.com/google-code-attachments/google-security-research/issue-198/comment-0/poc.zip)\n"},"comment":{"url":"https://api.github.com/repos/chrsmith/google-security-research/issues/comments/76007424","html_url":"https://github.com/chrsmith/google-security-research/issues/198#issuecomment-76007424","issue_url":"https://api.github.com/repos/chrsmith/google-security-research/issues/198","id":76007424,"user":{"login":"GoogleCodeExporter","id":9614759,"avatar_url":"https://avatars.githubusercontent.com/u/9614759?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCodeExporter","html_url":"https://github.com/GoogleCodeExporter","followers_url":"https://api.github.com/users/GoogleCodeExporter/followers","following_url":"https://api.github.com/users/GoogleCodeExporter/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCodeExporter/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCodeExporter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCodeExporter/subscriptions","organizations_url":"https://api.github.com/users/GoogleCodeExporter/orgs","repos_url":"https://api.github.com/users/GoogleCodeExporter/repos","events_url":"https://api.github.com/users/GoogleCodeExporter/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCodeExporter/received_events","type":"User","site_admin":false},"created_at":"2015-02-25T17:17:37Z","updated_at":"2015-02-25T17:17:37Z","body":"\n\n-----\nOriginal comment by `fors...@google.com` on 26 Nov 2014 at 2:14\n* Added labels: **MSRC-21092**"}}