Windows: Constrained Impersonation Capability EoP
Platform: Windows 10 1703/1709 (not tested earlier versions)
Class: Elevation of Privilege
Summary: Itâs possible to use the constrained impersonation capability added in Windows 10 to impersonate a lowbox SYSTEM token leading to EoP.
Description:
Windows 10 added a new security check during impersonation of a token which relies on an AppContainer capability Constrained Impersonation which allows a LowBox process to impersonate another LowBox token, even if itâs for a different user, as long as it meets certain requirements. Specifically:
- The impersonation tokenâs session ID is the same as the current processâ session ID
- The impersonation token has the same AC package SID as the processâ
- The impersonation tokenâs capability sids are a subset of the processes
Iâd assume that the thoughts around the security of this constrained impersonation capability is preventing an exist lowbox process gaining that capability. However this can be abused from a normal user privilege level by creating a new AC process with the capability. As a normal user itâs possible to create a new lowbox token from an existing one which has any capabilities you like and the package SID can be arbitrary.
The only limiting factor is getting hold of a suitable token which has the same session ID. This is easy for example in UAC scenarios (including OTS elevation) but of course thatâs a UAC bypass. Thereâs various tricks to get a SYSTEM token but most of the services run in Session 0. However there are a few processes running as SYSTEM but in the same session on a default install of Windows including CSRSS and Winlogon. Thereâs also the consent process which is part of UAC which is spawned in the user session. Therefore one way to get the token is to try and elevate a process running on a WebDAV share (hosted on localhost) and negotiate the NTLM/Negotiate auth in a similar way to previous issues Iâve reported (e.g. cases 21243 and 21878).
With a SYSTEM token handle itâs now possible to impersonate it as a lowbox from a normal user account. Of course this isnât a direct privilege escalation as you canât access administrator resources, however you can find system services which do the wrong thing. One example is code which just checks the Authentication ID of the token and assumes if itâs the SYSTEM ID then itâs trusted. A second example are AC processes which either run as SYSTEM or have tried to lock down themselves, a good example is the UMFD process, resources created by this process have access to SYSTEM as well as the package SID so you could inject code through hijacking a thread or one of the processes named resources. The final example are services which increase the IL of the caller, such as the print spooler bug I reported in case 41850, which you could get an arbitrary write as SYSTEM which gives you direct EoP.
Proof of Concept:
Iâve provided a PoC as a C# project. It implements a WebDAV server on localhost which will require authentication. Any user which tries to open a file on the share will have its token captured. It then uses UAC consent to get a call to the WebDAV server as a system token in the current session. Note that although Iâm abusing UAC itâs not a UAC bypass, itâs just a convenient way of getting the token. This would still work in OTS UAC as the token happens before the process is actually executed (which means the password doesnât have to be entered) so itâs still an issue. Once a suitable token has been captured the PoC spawns a new process in an AC and impersonates the system token on the main thread. It then abuses some functionality which was âfixedâ in MS15-10, that itâs possible to open a service with SERVICE_STATUS access rights as long as the caller is SYSTEM. Admittedly this seemed to be a bogus fix as impersonation shouldnât work like that in RPC, but in this case it doesnât really matter as we can actually impersonate a SYSTEM token. The PoC stops at the point of getting a valid handle to the service, Iâve not worked out what you can usefully do with that handle, maybe start/stop a service you wouldnât normally be able to?
1) Compile the C# project. It will need to grab the NtApiDotNet from NuGet to work.
2) In an admin command prompt run the command ânetsh http add urlacl url=http://127.0.0.1:4444/WebDAV user=Everyoneâ this is to just allow the PoC to use the HttpListener class which saves me from writing my own HTTP server implementation. You could do it entirely manually and not require this step but itâs just an issue with the listener classes that you need to add an acl for it, I was just too lazy to write my own.
3) Run the NtlmAuth PoC, it should setup the WebDAV server, start the WebClient service and then start an UAC elevation on the WebDAV server to capture the token. Itâll then run the test binary to open the service.
4) Cancel the UAC elevation prompt. You should now see a message box on the desktop from the test binary saying Success.
Expected Result:
Impersonating the SYSTEM token in a LowBox shouldnât be possible.
Observed Result:
The test binary is running while impersonating the SYSTEM token. Itâs opened a handle to the WebClient service with SERVICE_STATUS access rights.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/44149.zipData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation