In your red teaming or pentesting activities escalating to SYSTEM on a Windows box is always the desired objective. The SYSTEM user is a special operating system user with the highest privilege, many post exploitation techniques require this type of access.
Of course, in order to get SYSTEM you have be part of the administrators group or use some particular token stealing/impersonation techniques (example: The lonely potato) or just exploit some unptached vulnerabilties…
If you have administrator access, there are a plenty of techniques or tools to help you elevating the privilege. The most common is the well known utility “psexec” from Sysinternals, but there are also other tools which rely on named pipe or token impersonation. I guess everyone of you has used the “getsystem” command from a meterpreter console 😉
In this article I will show you how to use the “parent process” technique. Of course, nothing new, but I just wanted to keep everything in a single powershell script as small as possible. (you know how important it is).
First a little bit of theory. Normally, when a process launches a child process, it becomes the parent of the child process. However starting form Windows Vista it is possible to alter this behaviour. If we create a new process setting also the parent process property, the child process will inherit the token of the specified parent process and impersonate this one. So if we create a new process, setting the parent PID the process owned by SYSTEM, we did it!
Of course, we need to have elevated rights in order to create a process from the parent process handle, typically seDebugPrivilege which administrators have (note: if a regular user has this privilege too, he has the keys for the kingdom!). Keep in mind that this privilege is available only from an elevated command prompt. Just check it with the following command:
This was the theory, now we have to play with the Windows API in order to achieve our mission.
First we will need to create an attribute in the STARTUPINFO structure, get the parent SYSTEM process handle and instruct the CreateProcess() call to use these additional informations.
Doing this in C++ or C# is relatively easy but in powershell could be a tricky task, so I decided to embed C # in my .ps1 script. As you already know, it is possible to execute C# code from powershell and viceversa.
The script can be found here: https://github.com/decoder-it/psgetsystem
To excecute it, from an elevated Powershell prompt launch:
PS> . .\psgetsys.ps1 PS> [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>)
We could also add the “auto invoke” at the end of the script:
Add-Type -TypeDefinition $mycode [MyProcess]::CreateProcessFromParent($args,$args)
And invoke it:
.\psgetsys.ps1 808 c:\windows\system32\cmd.exe
Las but not least, what if SeDebugPrivilege is present but not enabled? Well would not be that hard to insert the appropriate instructions in the C# .. isn’t it?
That’s all 😉