Tokenvator: A Tool to Elevate Privilege using Windows Tokens
WheresMyImplant is a mini red team toolkit that I have been developing over the past year in .NET. While developing and using it, I found that I consistently needed to alter my process access token to do such things as SYSTEM permissions or add debug privileges to my process. The library used for this expanded to the point where it was as useful as an independent toolkit. This is why I created Tokenvator. It is a simple tool I wrote in .NET that can be used to elevate to the appropriate permissions on Windows. It works by impersonating or altering authentication tokens in processes that the executing process has the appropriate level of permissions to.
Tokenvator can be run in an interactive prompt, or commands can be provided as command line arguments. In the interactive mode, base commands will tab complete, with double tabs providing context specific help.
While most of the screenshots will show commands running from an interactive (Tokens) > prompt, it is possible to run all commands as an argument.
Steal_Token
At it’s most basic level, Tokenvator is used to access and manipulate Windows authentication tokens. To appropriate the token of another process, we can run the Steal_Token command with the target process’s PID.
We can also optionally add a command to be run that will be launched with the new access token.
(Tokens) > Steal_Token 7384 powershell.exe
[*] Adjusting Token Privilege
[+] Received luid
[*] AdjustTokenPrivilege
[+] Adjusted Token to: SeDebugPrivilege
[+] Recieved Handle for: (7384)
[+] Process Handle: 860
[+] Primary Token Handle: 864
[+] Duplicate Token Handle: 860
[*] CreateProcessWithTokenW
[+] Created process: 14524
[+] Created thread: 18784
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:WINDOWSsystem32> whoami
labbackup
PS C:WINDOWSsystem32> $pid
14524
GetSystem
The most common token I need to steal is for the NT AUTHORITYSYSTEM account. The GetSystem command was created as a wrapper for Steal_Token to automatically find and access SYSTEM tokens. It works with the same syntax as Steal_Token. Note: This needs to be run from an elevated context.
(Tokens) > GetSystem
[*] Adjusting Token Privilege
[+] Received luid
[*] AdjustTokenPrivilege
[+] Adjusted Token to: SeDebugPrivilege
[*] Searching for NT AUTHORITYSYSTEM
[*] Examining 344 processes
[*] Discovered 118 processes
[*] Impersonating 5488
[+] Recieved Handle for: (5488)
[+] Process Handle: 888
[*] Impersonating 4444
[+] Recieved Handle for: (4444)
[+] Process Handle: 868
[+] Primary Token Handle: 904
[+] Duplicate Token Handle: 868
(Tokens) > WhoAmI
[*] Operating as NT AUTHORITYSYSTEM
(Tokens) > RevertToSelf
[*] Reverted token to labbadjuju
I’ve discovered that I am unable to directly access the token of certain processes unless I’ve first elevated to SYSTEM. Examples of the are the NT SERVICE accounts such as a local SQL service process. This might be necessary if the local SYSTEM account doesn’t have SYSADMIN privileges on the database. Scott Sutherland talks more about this in this blog.
GetTrustedInstaller
It is common for the files in the SYSTEM32 folder or parts of the registry to be owned by the TRUSTEDINSTALLER group. To manipulate the contents of these locations, we can either take ownership or get an access token that has membership in the TRUSTEDINSTALLER group. Similar to GetSystem, GetTrustedInstaller is a wrapper for Steal_Token that starts the TrustedInstaller service and appropriates it’s token.
List_Privileges and Set_Privilege
Sometimes our process doesn’t have the particular access right that we need in order to complete a task. For instance, to access a process that your current user doesn’t own, the SeDebugPrivilege is required. Shown below is a split token in a high integrity process (UAC Elevated – TokenElevationTypeFull)
And here we can see the default privileges assigned to a split token in a medium integrity process (UAC Not Elevated – TokenElevationTypeLimited)
For this functionality, we are not limited to just our own process Let’s examine what notepad.exe’s token looks like when run as administrator. Note: To access a process not owned by your current user, the SeDebugPrivilege must be enabled on your current process.
Having examined notepad.exe’s token, we can remotely alter the privileges on it. Let’s add SeLoadDriverPrivilege to that token and see what happens. Note: Privilege names are case sensitive.
Sure enough, notepad.exe can now load a driver, for whatever interesting use case that might require that. In the future the ability to remove privileges will be added.
BypassUAC
UAC bypasses have become plentiful that this point, however one of the more interesting ones comes from manipulating tokens. FuzzySecurity has done some very interesting work on a UAC bypass method utilizing Windows tokens. Tokenvator includes an implementation of the technique he published. Below, our unprivileged token can be used to access an elevated process our current user owns and spawn an elevated shell.
While this method likely will not be patched in the near future, it is not without its limitations. As can be seen below, while the process is high integrity, the privileges assigned to the token are still limited.
Finding User Processes
For finding a user on a system there are multiple methods for identification. Firstly, we can look at registered session on the system.
One feature that I’ve wanted is the ability to have a summary view of user processes to get a sample of users and a process that they own. This is what the List_Processes command accomplishes.
(Tokens) > List_Processes
User Process ID Process Name
---- ---------- ------------
labbadjuju 4000 conhost
List_Processes takes advantage of the native API’s on the host and is quite fast at listing a summary of processes and owners. As of now, it will not be able to function properly unless run from an elevated context. Because of this, List_Processes_WMI has been included. As the name might imply, this operates via WMI. While not as quick as List_Processes, it can provide a more thorough view from a non-elevated context.
(Tokens) > List_Processes_WMI
[*] Examining 102 processes
User Process ID Process Name
---- ---------- ------------
0 Idle
LABBADJUJU 448 taskhost
LOCAL XBADJUJU 1568 cmd
Or we can poll the system for for all processes running under the context of a particular user. Note: as of the initial release, the full username is required.
Similarly to List_Processes a mechanism to accomplish the same task has been included via WMI. This will also work in an unelevated context.
(Tokens) > Find_User_Processes_WMI LOCAL xBADJUJU
[*] Examining 102 processes
[*] Discovered 31 processes
Process ID Process Name
---------- ------------
1568 cmd.exe
2108 conhost.exe
1936 procexp64.exe
3544 cmd.exe
3608 conhost.exe
3892 x64dbg.exe
I made this program for myself and the NetSPI team, but hopefully it will be useful to others. If you have any bugs, commits, or feature requests let me know. All are welcome.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
Name
Domain
Purpose
Expiry
Type
YSC
youtube.com
YouTube session cookie.
52 years
HTTP
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Name
Domain
Purpose
Expiry
Type
VISITOR_INFO1_LIVE
youtube.com
YouTube cookie.
6 months
HTTP
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
We do not use cookies of this type.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
We do not use cookies of this type.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
We do not use cookies of this type.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.