---
description: >-
  Token theft in kernel exploitation refers to the act of acquiring and
  impersonating the access token of a privileged process or user. Here, we will
  manually assign tokens in the debugger.
---

# Token Theft

In the Windows OS, Access Tokens are stored in the kernel's Non-Paged Pool memory. The Non-Paged Pool is a region of memory that is always kept in physical memory and not paged out to disk, ensuring fast and consistent access.

Access Tokens contain information about the security context of a user or process, including user account information, group memberships, privileges, and more.

These tokens are created and managed by the Windows security subsystem and are stored in the kernel's memory space for efficient access and enforcement of security policies.

The `_EPROCESS` structure, part of the kernel's representation of a process, contains a pointer to a token at offset `0x385` (this may vary on versions of Windows):

<div align="left"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FUFNvsfSOSBQv4yNJKOU0%2Flow-priv-token.png?alt=media&#x26;token=1c07c387-d3b0-492c-a5b1-bd6eb3791934" alt="" width="563"><figcaption><p>Low Privilege Token</p></figcaption></figure></div>

The System process always has a PID (process ID) of `4`. This is helpful to us. If we can exploit the kernel we can essentially enumerate the System process find out the address of the token it is pointing to, copy the address and assign it to the token pointer in an arbitrary process:

<div align="left"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FybwhVhe4QcO5OMdE0ueE%2Fhigh-priv-token.png?alt=media&#x26;token=506d4efc-05b8-4653-96da-eaa25c180024" alt="" width="563"><figcaption><p>High Privilege Token</p></figcaption></figure></div>

This would be carried out in shellcode as part of a privilege escalation exploit. To understand how this works we can also do it manually by using the debugger.

## System Process Context

Make sure Windbg Preview is connected to the Windows 10 host.

On the debugger, break into the kernel and locate the System process:

```
0: kd> !process 0 0 System
```

Use the process address to set the process context:

```
0: kd> .process ffffad8309e1f040
Implicit process is now ffffad83`09e1f040
WARNING: .cache forcedecodeuser is not enabled
```

**Note:** the process address will differ on your host.

We can view the `_EPROCESS` object associated with the System process by using the `?? @&proc` command.

When the structure is displayed, locate the `Token` property. This is located at `+0x358`. Click on this property:

**Note:** if you cannot click on the `Token` property, you may have Debugger Markup Language (DML) disabled; enable it by typing `.prefer_dml 1`.

{% code overflow="wrap" %}
```
0: kd> dx -id 0,0,ffffad8309e1f040 -r1 (*((ntkrnlmp!_EX_FAST_REF *)0xffffad8309e1f398))
(*((ntkrnlmp!_EX_FAST_REF *)0xffffad8309e1f398))                 [Type: _EX_FAST_REF]
    [+0x000] Object           : 0xffff970947417044 [Type: void *]
    [+0x000 ( 3: 0)] RefCnt           : 0x4 [Type: unsigned __int64]
    [+0x000] Value            : 0xffff970947417044 [Type: unsigned __int64]
```
{% endcode %}

This indicates that the token pointer is located at `0xffffad8309e1f398`. We can find what the address is of the System context token:

```
0: kd> dq 0xffffad8309e1f398 L1
ffffad83`09e1f398  ffff9709`47417044
```

The token is located at address `ffff970947417044`. We should keep a note of this for later (again this will differ on your host).

## Low Privileged Process

Issue the `g` command, then go to the target machine and run a new `cmd.exe` process in a low privileged context.

Issue the `whoami` command in the command console:

<div align="left"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FGdENmz5RVYIXflPhFqv3%2Flow-priv-account.png?alt=media&#x26;token=13bb7822-5e24-4ddf-b824-a2ed40591dff" alt="" width="563"><figcaption><p>Low Privileges</p></figcaption></figure></div>

We can now go back to the debugger and pause the target host and find the address of the new process:

```
0: kd> !process 0 0 cmd.exe

[ommitted for brevity]

0: kd> .process ffffad8309eea080
Implicit process is now ffffad83`09eea080
WARNING: .cache forcedecodeuser is not enabled
```

We can view the `_EPROCESS` object associated with the new process by using the `?? @&proc` command.

Again we can locate the `Token` property, this time we are going to overwrite the token it points to:

{% code overflow="wrap" %}
```
0: kd> dx -id 0,0,ffffad8309eea080 -r1 (*((ntkrnlmp!_EX_FAST_REF *)0xffffad8309eea3d8))
(*((ntkrnlmp!_EX_FAST_REF *)0xffffad8309eea3d8))                 [Type: _EX_FAST_REF]
    [+0x000] Object           : 0xffff97094e221066 [Type: void *]
    [+0x000 ( 3: 0)] RefCnt           : 0x6 [Type: unsigned __int64]
    [+0x000] Value            : 0xffff97094e221066 [Type: unsigned __int64]
```
{% endcode %}

Take the address of the privileged token and assign it to the command console process:

```
0: kd> eq 0xffffad8309eea3d8 ffff9709`47417044
```

Press `g` to continue the target host. In the command console issue the `whoami` command again and observe the change:

<div align="left"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FoloLig8JwgRqJsDj7ujK%2Fsystem-account.png?alt=media&#x26;token=a70fbf66-5a12-4197-a9f0-92692c3e1c4b" alt="" width="563"><figcaption><p>System Privileges</p></figcaption></figure></div>

This section showed how we can use the debugger to assign the System privileged token to other processes. Whilst this is interesting and insightful, leveraging this technique using shellcode is a bit more involved. This will be discussed in a later section.

## Demo

**Work in progress**
