How can I temporarily impersonate a higher-privilege process? RRS feed

  • Question

  • I'm writing a program that runs at Medium integrity level.  (Or High if UAC is disabled.)  I want to spawn off a child process that accesses untrusted servers on the Internet, and thus want to have this process use Low integrity in case it gets exploited.

    However, during its startup, this child process needs to access data that is inaccessible by Low-integrity processes.  Once it has loaded these files, it can drop its privilege to Low.

    My current attempt to accomplish this is to have the parent process create a SecurityDelegation impersonation token of itself, then DuplicateHandle the token into the child process.  The child process then calls ImpersonateLoggedOnUser with the impersonation token from the parent process.  When the child process is done accessing the higher-privileged objects, it calls RevertToSelf and CloseHandle.  With the handle closed and the token reverted, the child process would be permanently locked down to the lower privilege.

    The problem is that this doesn't work: the first time the child process tries to access anything, ERROR_BAD_IMPERSONATION_LEVEL is returned.  Specifically, it gets that error trying to open a DLL from the Windows\SysWOW64 directory for reading.  If I GetTokenInformation(TokenImpersonationLevel), the value returned is still SecurityDelegation.  All the API calls return success up until the CryptAcquireContextW that fails trying to load a Windows DLL.

    According to the documentation of ImpersonateLoggedOnUser, SeImpersonatePrivilege is not required if "the authenticated identity is the same as the caller".  GetTokenInformation(TokenUser) returns the same SID, so they are in fact the same authenticated identity.

    The problem still occurs even if the parent process is the one triggering the impersonation; i.e. using SetThreadToken on the child process's main thread.

    Saturday, February 9, 2013 2:33 AM

All replies

  • Giving a low-integrity process temporary access to a medium-integrity token seems unsafe.  If another low-integrity process such as Internet Explorer is already being exploited, it may be able to DuplicateHandle the token from your low-integrity process before your process closes the token handle.

    I don't know whether Microsoft intends to let low-integrity processes impersonate medium-integrity tokens of the same user, but I wouldn't be surprised if they had intentionally blocked this.  I see neither "authenticated identity" nor "identity" in the Security Glossary, but I suspect it is the same as "security context", which includes more than just the user SID.

    Instead of using impersonation, you could make the medium-integrity process open the initialization data files and forward the necessary information to the low-integrity process via a pipe.  Or even duplicate the file handles into the low-integrity process if the medium-integrity process opened the files read-only and you know the files don't contain anything confidential.

    Monday, February 11, 2013 4:23 PM
  • You have a point about low-integrity processes being able to attack one another.

    The trouble here is that the files are being read by a third-party DLL directly, using CreateFileW and FindFirstFileW.

    Monday, February 11, 2013 8:10 PM