How to impersonate the Windows system account in an application

During the research of my previous post, I wanted to find out if it’s possible to impersonate the system account in an application (NT AUTHORITY\SYSTEM). Apparently, and much to my surprise, it’s a bit more powerful than the administrator account. The short answer is that there’s no clean, reliable, non-intrusive and portable way to do that, and in most cases, there are much better solutions. But if you really want the impersonation, then here are the possibilities that I found on my Windows 7 system.

So why would anyone want to impersonate SYSTEM anyway? Because it can do some things more easily than an administrator. The benefits include impersonating any local account without the need for their password, also acting as the machine account in a domain, and there are directories which only this account can access by default (like System Volume Information in my previous post). An administrator can impersonate SYSTEM, so effectively, an administrator does have all these privileges, but actually using them takes extra efforts. It’s not breaking the security system, it’s just overcoming some deliberate obstacles that exist for administrators.

Most websites offer two command-line tricks. It’s a developer blog, so let’s see how these work from a developer’s perspective.

The first trick is the tool called PsExec. What it does is install a service that runs as LocalSystem, and then tells the service to execute a command that the user specified. This seems like a very stable method, but it’s also very intrusive. It’s easily reproducible with the service API. It’s inconvenient because it’s not a method you call but a service: you either need a separate puppet service application (PsExec contains one named psexesvc.exe) or you can make an application that works as a console/Windows application and as a service, too.

The second trick is the task scheduler. You tell it to run an interactive command prompt in the next few seconds with system privileges. It has the same problems as the previous method, and additionally I wouldn’t even call it reliable: either you specify a big delay and wait a lot, or you specify a low delay and you’re risking not running your task at all. Anyway, there’s a task scheduler API, too.

The usual, direct impersonation with LogonUser doesn’t work because it always needs a password, and SYSTEM doesn’t have one. Services impersonate users by creating security tokens directly, with undocumented API’s like NtCreateToken or ZwCreateToken. These functions require special privileges (SeTcbPrivilege - act as part of the operating system, SeCreateToken - create a token object, see here). SYSTEM has these privileges, the administrator doesn’t, but the administrator can give them to itself with the group policy editor. It doesn’t seem dangerous, but it’s not recommended, and again, it’s intrusive.

And the last method I found is “stealing” tokens with functions like OpenProcessToken or ImpersonateLoggedOnUser. I didn’t expect that an administrator could get a SYSTEM token, but much to my surprise, OpenProcessToken worked, at least on most processes, but not all, which makes it quite unreliable. Also, who knows if some security settings or some antivirus software disable this. It’s a shame, because it’s the only non-intrusive method that I found.

So my advice is that if you want to impersonate SYSTEM in an application, then think again, and find another way :) . Like I said in the first paragraphs, these methods are not suitable from a developer’s perspective. Additional methods are welcome, though.

Leave a Reply