Tokenvator Release 3 Written by Alexander Polce Leary | July 22, 2021 Tokenvator Release 3 Is a Long Overdue Update That Includes a Major Overhaul to the Tool
Total Page:16
File Type:pdf, Size:1020Kb
Tokenvator Release 3 written by Alexander Polce Leary | July 22, 2021 Tokenvator Release 3 is a long overdue update that includes a major overhaul to the tool. From the user interface, it will be mostly familiar with some command line tweaks. Under the surface, large portions of the code base have been reworked, and parts of the base have had some updates. In this series, we will go over some of the changes and new features added. Teaser Alert: Adding Privileges & Creating Tokens Improvements First and foremost, the user interface. Historically, every action had a series of positional arguments that were clunky and generally difficult to remember. They were also not very flexible, and as the commands started to have more, and additional optional arguments, they became completely unwieldy. These have been replaced with flags that will auto complete. For instance, to list and enable privileges: This also works in the non-interactive mode (though it won’t tab complete – sorry, it’s Windows): Additionally, the scroll back function was improved and numerous bugs were resolved. For instance, now when you press up you will always go to the last command issued. A printable command history has also been added if you want to copy and paste instead or keep a log of your actions. The info functionality was improved again, removing many bugs and adding additional information, such as impersonation contexts: (Tokens) > whoami [*] Operating as NT AUTHORITY\SYSTEM (Tokens) > info [*] Primary Token [+] User: S-1-5-21-258464558-1780981397-2849438727-1001 DESKTOP- J5KC1AR\0xbadjuju [*] Impersonation Tokens [*] Primary Token Groups [+] Enumerated 15 Groups: S-1-5-21-258464558-1780981397-2849438727-513 DESKTOP- J5KC1AR\None S-1-1-0 Everyone S-1-5-114 NT AUTHORITY\Local account and member of Administrators group S-1-5-32-544 BUILTIN\Administrators S-1-5-32-559 BUILTIN\Performance Log Users S-1-5-32-545 BUILTIN\Users S-1-5-4 NT AUTHORITY\INTERACTIVE S-1-2-1 CONSOLE LOGON S-1-5-11 NT AUTHORITY\Authenticated Users S-1-5-15 NT AUTHORITY\This Organization S-1-5-113 NT AUTHORITY\Local account S-1-5-5-0-870189 Some or all identity references could not be translated. S-1-2-0 LOCAL S-1-5-64-10 NT AUTHORITY\NTLM Authentication S-1-16-12288 Some or all identity references could not be translated. Now, you have the option to get additional information by using the /all flag. (Tokens) > info /all Option Value ------ ----- all [*] Primary Token [+] User: S-1-5-21-258464558-1780981397-2849438727-1001 DESKTOP- J5KC1AR\0xbadjuju [*] Impersonation Tokens [*] Thread ID: 5820 [+] User: S-1-5-18 NT AUTHORITY\SYSTEM [*] Thread ID: 1120 [*] Thread ID: 7108 [*] Thread ID: 9180 [*] Thread ID: 1152 [*] Thread ID: 8592 [*] Thread ID: 8076 [*] Primary Token Groups [+] Enumerated 15 Groups: S-1-5-21-258464558-1780981397-2849438727-513 DESKTOP- J5KC1AR\None S-1-1-0 Everyone S-1-5-114 NT AUTHORITY\Local account and member of Administrators group S-1-5-32-544 BUILTIN\Administrators S-1-5-32-559 BUILTIN\Performance Log Users S-1-5-32-545 BUILTIN\Users S-1-5-4 NT AUTHORITY\INTERACTIVE S-1-2-1 CONSOLE LOGON S-1-5-11 NT AUTHORITY\Authenticated Users S-1-5-15 NT AUTHORITY\This Organization S-1-5-113 NT AUTHORITY\Local account S-1-5-5-0-870189 Some or all identity references could not be translated. S-1-2-0 LOCAL S-1-5-64-10 NT AUTHORITY\NTLM Authentication S-1-16-12288 Some or all identity references could not be translated. [+] Source: User32 [*] Enumerating Token Privileges [*] GetTokenInformation - Pass 1 [*] GetTokenInformation - Pass 2 [+] Enumerated 24 Privileges Privilege Name Enabled -------------- ------- SeIncreaseQuotaPrivilege False SeSecurityPrivilege False SeTakeOwnershipPrivilege False SeLoadDriverPrivilege False SeSystemProfilePrivilege False SeSystemtimePrivilege False SeProfileSingleProcessPrivilege False SeIncreaseBasePriorityPrivilege False SeCreatePagefilePrivilege False SeBackupPrivilege False SeRestorePrivilege False SeShutdownPrivilege False SeDebugPrivilege True SeSystemEnvironmentPrivilege False SeChangeNotifyPrivilege True SeRemoteShutdownPrivilege False SeUndockPrivilege False SeManageVolumePrivilege False SeImpersonatePrivilege True SeCreateGlobalPrivilege True SeIncreaseWorkingSetPrivilege False SeTimeZonePrivilege False SeCreateSymbolicLinkPrivilege False SeDelegateSessionUserImpersonatePrivilege False [+] Owner: S-1-5-32-544 BUILTIN\Administrators [+] Primary Group: S-1-5-21-258464558-1780981397-2849438727-513 DESKTOP- J5KC1AR\None [+] ACL Count: 572 [+] Primary Token [+] TokenElevationTypeFull [*] Token: Split [+] ProcessIntegrity: High Impersonation Tokens Previously, I had glossed over Impersonation (Thread) Tokens in the Tokenvator tool. When you impersonate a token, it doesn’t replace your primary token in your process. What it does is place the token in the calling thread. In this tool, this is typically the primary thread. Going forward, I will use Thread Token and Impersonation Token interchangeably. In the following example, we show the privileges on our primary token (List_Privileges), impersonate the SYSTEM account (GetSystem), list the privileges on our primary token again to show it hasn’t been altered (List_Privileges), and finally list the privileges for the SYSTEM token we are impersonating (List_Privileges /Impersonation). In this second, more complex example, we show: The privileges on our primary token (List_Privileges) Impersonate the SYSTEM account (GetSystem) List the privileges for the SYSTEM token we are impersonating (List_Privileges /Impersonation) We then: Disable the SeAssignPrimaryTokenPrivilege on the Thread Token for SYSTEM (Disable_Privilege /Privilege:SeAssignPrimaryTokenPrivilege /Impersonation) List the thread token privileges again (List_Privileges /Impersonation) Re-enable the privilege on the token (Enable_Privilege /Privilege:SeAssignPrimaryTokenPrivilege /Impersonation) List the privileges one last time (List_Privileges /Impersonation) to show that it has been reenabled This could all be done against a remote process as well by passing /ProcessID:<ID> flag. Similarly, Thread Tokens can be impersonated with the Steal_Token command by specifying the /Thread Flag. Now for the Cool Stuff The number one request I’ve gotten has been, “Can I add a privilege with this tool?” Until now, that issue has been open on GitHub. I can happily say, I can finally close this issue. Like Morpheus said, some of these rules can be bent others can be broken. To change the privileges on the token, I’ve historically used advapi32!AdjustTokenPrivileges. This allows for privileges to be enabled, disabled, or removed. As far as I’ve been able to tell, this does not allow for adding privileges onto a token. But because that doesn’t work, it doesn’t mean that there are no other options. It’s time to enter the world of the kernel. Exploring the Kernel To look at the Windows kernel, you will probably need WinDbg. It involves installing several development kits from Microsoft (https://docs.microsoft.com/en-us/windows-hardware/drivers/deb ugger/getting-started-with-windbg–kernel-mode-). A local instance of the debugger can be started from an elevated command prompt: “C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\kd.exe” -kl From here we can start exploring. Opaque Structures As expansive as Microsoft Developer Network (MSDN) is, it is not all-encompassing. There are things that are intentionally not documented as they are not intended to be used. Among these is the EPROCESS structure. https://docs.microsoft.com/en-us/windows-hardware/driver s/kernel/eprocess Part of this is that this structure can change without notice from Microsoft. I can personally confirm that this happened. While it may be difficult to track down the layout of this structure online, we can easily view it with WinDbg. Using the dt command in WinDbg we can view each instance of it. Exploring with windbg Let’s look at the process structure of an elevated Tokenvator instance: It’s running with process ID of 8140, converted to hex it is 1FCC. Examining that process shows: The line we are looking for is: PROCESS ffff9a890b963080 The EPROCESS structure can be found at is at address ffff9a890b963080. Querying for the EPROCESS structure: It’s mostly truncated here, but it’s big. Really big. Excluding the KPROCESS structure which takes up the address 0x000 – 0x438 it has 238 entries. dt nt!_EPROCESS ffff9a890b963080 +0x000 Pcb : _KPROCESS … +0x460 PrimaryTokenFrozen : Pos 15, 1 Bit … +0x4b8 Token : _EX_FAST_REF … +0xa10 DynamicEnforcedCetCompatibleRanges : _PS_DYNAMIC_ENFORCED_ADDRESS_RANGES But in this structure, there is a field called Token which references the _EX_FAST_REF structure. Querying the _EX_FAST_REF structure for the Token field shows the following. If we were query that address for a _TOKEN structure it wouldn’t work but looking the verbose process information with the command. I didn’t immediately realize why the addresses were different. Fortunately, the ired.team was able to provide a useful insight:. they realized a bitwise AND (&) would correct the address. Evaluate expression: -65372684652448 = ffffc48b`3c5a7060 Querying that address for the token we see a structure where the privileges are stored. Querying that field reveals a structure that contains the present field where a bitwise or for each privilege can detect if it is present. AND’ing that field can allow us to put privileges back on the token. Pulling it All Together We’ve found what needs to be changed in the kernel, so how do we do that? Well, that involves creating a kernel mode driver that