Continuing on the path to Windows kernel exploitation…
Thanks to the previous post, we now have a working lab for easily (and in a reasonably fast manner) debug Windows kernel.
Let’s skip ahead for a minute and assume we control PC using some vulnerability in kernel land (next post), then we may want to jump back into a user allocated buffer to execute a control shellcode. So where do we go from now? How to transform this controlled PC in the kernel-land into a privileged process in user-land?
The classic technique is to steal the
System process token and copy it into the
structure of our targeted arbitrary (but unprivileged) process (say
Note: our target here will the Modern.IE Windows 8.1 x64 we created in the
that we’ll interact with using
kd via Network debugging. Refer to previous
post if you need to set it up.
Stealing SYSTEM token using
of WinDBG provides a structured display of one or all the processes.
This leaks the address of the
_EPROCESS structure in the kernel, of the proces
dt will provide a lot more info (here, massively
truncated to what interests us):
nt!_EPROCESS.Token (+0x348) we get the process token, which holds a pointer to an
“Executive Fast Reference” structure.
If we nullify the last nibble of the address (i.e. AND with -0xf on x64, -7 on
x86), we end up having the
System token’s address:
Note: the WinDBG extension
a more detailed (and parsed) output. You might to refer to it instead whenever
you are analyzing tokens.
So basically, if we create a process (say
cmd.exe), and overwrite its token
System token value we found (0xffffc0002f405590), our process will be
System. Let’s try!
We search our process using
Overwrite the offset 0x348 with the
SYSTEM token pointer (0xffffc0002f405590).
And tada …
Now we know how to transform any unprivileged process into a privileged one
Shellcoding our way to SYSTEM
So the basic idea now, to reproduce the same steps that we did in the last part, but from our shellcode. So we need:
- A pointer to
EPROCESSstructure, and save the token (located at offset +0x348)
- Look up for the current process
- Overwrite its token with
Getting the current process structure address
Pointers to process structures on Windows are stored in a doubly linked list (see the
If we have the address to one process, we can “scroll” back and forward to discover the
others. But first, we need to get the address of at the least one process in the
This is exactly the purpose of the routine
since we can’t call it directly (thank you ASLR), we can still check what is it
doing under the hood:
mov rax, qword ptr gs:[188h] returns a pointer to an
_ETHREAD structure (more
specifically the kernel thread (KTHREAD)
nt!KiInitialThread). If we check the content of
this structure at the offset 0xb8, we find the structure to the current process:
So now we know where our current process resides in the kernel (just like
gave us using
!process 0 0 cmd.exe earlier), and therefore the first of our
Browsing through the process list to reach
The processes are stored in the
ActiveProcessLinks (offset 0x2e8) of the
nt!_EPROCESS structure, via a
_LIST_ENTRY, which is a doubly linked list in
its simplest form:
Since we know that
System process ID is 4, we can write a very small loop in
assembly, whose pseudo-C code would be:
Which builds the second part of our shellcode:
Overwrite the current process token field with
This is the third and final part of our shellcode, and the easiest since everything was done in the steps above:
The final shellcode
We add a few extra instructions to correctly save and restore the context, and make sure we exit cleanly:
We can now simply use any assembler (NASM, YASM) - but I have a personal preference for Keystone-Engine - to generate a bytecode version of our shellcode.
Once copied into an executable location, this shellcode will grant the current
process with all
Until then, take care!
- A Guide to Kernel Exploitation - Attacking The Core
- Introduction To Windows Shellcode Development
- x64 Kernel Privilege Escalation
- Well-Known Security IDentifiers
- Understanding Windows Shellcode
Share this post: