Search code examples
c#windowsaccess-tokennamed-pipesimpersonation

How does Meterpreter execute cmd commands as System after using getsystem's technique 1: Service - Named Pipe Impersonation


Im trying to figure out how does Meterpreter execute cmd commands as System after impersonating the security context of that account (NT AUTHORITY\System) using the getsystem's technique 1: Service - Named Pipe Impersonation (In Memory/Admin).

For that, I've wrote a small C# code that creates a named pipe A , generates a new service B running as System and then forces the service B to write some data on A, which allows me to impersonate the client through the client impersonation funcionality for named pipes.

Now, once the impersonation is done, what I do have is a process whose primary token points to a local admin user (the user who is running the c# code, let's say its the user Administrator) and one thread of this process with an impersonation token that points to the System account. The activities executed by the thread that is impersonanting System obviously run under the security context of the impersonnated account, but if I want to execute a cmd command (let's say a trivial one like whoami) I need to spawn a new process in order to run cmd.exe. At that moment, the primary token for the new process is the primary token of my initial process and not the impersonation token from the thread impersonating System, therefore the output for the command whoami is Administrator instead of System.

I guess Meterpreter is not using CreateProcessAsUser since A) It only has an impersonation token, not a primary token (is there any way to turn an impersonation token into a primary token) and B) Some special privileges are required in order to use that function and I haved checked that none of the users of my computer have that privileges granted, despite that I have been able to elevate my privileges using this technique through Meterpreter.

So this leads me to the main question: How does Meterpreter execute cmd commands as System after using getsystem's technique 1?


Solution

  • After some (more) research, I think I got the answer for this question.

    Although you need SE_INCREASE_QUOTA_NAME and SE_ASSIGNPRIMARYTOKEN_NAME in order to use CreateProcessAsUser (and noone of my user had granted that privileges), you can use the function CreateProcessWithTokenW which only requires SE_IMPERSONATE_NAME. I guess Meterpreter is using this one because this is actually a privilege that some of my users have granted and it seems a less restrictive function. I've been able to reproduces the getsystem behaviour using this API call through C#.

    In the other hand, you can turn impersonation tokens into primary tokens (it also works in the other direction) by using DuplicateToken function.