Meterpreter’s getsystem command is taken for granted. Type getsystem and magically Meterpreter elevates you from a local administrator to the SYSTEM user. What’s really happening though?

The getsystem command has three techniques. The first two rely on named pipe impersonation. The last one relies on token duplication.

meterpreter > getsystem -h
Usage: getsystem [options]

Attempt to elevate your privilege to that of local system.


-h        Help Banner.
-t   The technique to use. (Default to '0').
0 : All techniques available
1 : Service - Named Pipe Impersonation (In Memory/Admin)
2 : Service - Named Pipe Impersonation (Dropper/Admin)
3 : Service - Token Duplication (In Memory/Admin)

Let’s go through them:

Technique 1 creates a named pipe from Meterpreter. It also creates and runs a service that runs cmd.exe /c echo “some data” >\\.\pipe\[random pipe here]. When the spawned cmd.exe connects to Meterpreter’s named pipe, Meterpreter has the opportunity to impersonate that security context. Impersonation of clients is a named pipes feature. The context of the service is SYSTEM, so when you impersonate it, you become SYSTEM.

Technique 2 is like technique 1. It creates a named pipe and impersonates the security context of the first client to connect to it. To create a client with the SYSTEM user context, this technique drops a DLL to disk(!) and schedules rundll32.exe as a service to run the DLL as SYSTEM. The DLL connects to the named pipe and that’s it. Look at elevate_via_service_namedpipe2 in Meterpreter’s source to see this technique.

As the help information states, this technique drops a file to disk. This is an opportunity for an anti-virus product to catch you. If you’re worried about anti-virus or leaving forensic evidence, I’d avoid getsystem –t 0 (which tries every technique) and I’d avoid getsystem –t 2.

Technique 3 is a little different. This technique assumes you have SeDebugPrivileges—something getprivs can help with. It loops through all open services to find one that is running as SYSTEM and that you have permissions to inject into. It uses reflective DLL injection to run its elevator.dll in the memory space of the service it finds. This technique also passes the current thread id (from Meterpreter) to elevator.dll. When run, elevator.dll gets the SYSTEM token, opens the primary thread in Meterpreter, and tries to apply the SYSTEM token to it.

This technique’s implementation limits itself to x86 environments only. On the bright side, it does not require spawning a new process and it takes place entirely in memory.

Let’s say techniques 1-3 fail. You can always fall back to getting system by hand. All of these techniques rely on your ability, as a privileged user, to create or inject into a service. If these techniques fail, generate an executable for your payload and use sc or at to run it as SYSTEM. There you go, you’ve got system.

Interested in Trying Cobalt Strike?