Shellcoding in the Upsidedown

Good ol’ shellcoding….shellcoding in the Land o’ Kernel.

So there are readily available payloads that you are able to use in HackSysTeam’s repo which you can find here; but what fun is that if you’re just going to copy and paste?! Roll up the sleeves because it’s. About. To. Go. Down.

Functions used:

  1. CreateFile
  2. DeviceIoControl
  3. VirtualAlloc
  4. CodeMachines Catalog is nice

Manually Stealing ze Token

So here is the coolest thing…visualizing how it works using WinDBG by doing it manually.

First thing that needs to be done is to find the System process and get its address.

PROCESS points to an _EPROCESS structure that holds the System’s token, among many other things.

Let’s first get familiar with the EPROCESS structure. This is where everything you need to steal the token is going to be at. You will also notice ActiveProcessLinks and UniqueProcessId being in here. Take a mental snapshot of this as we will be coming back to this shortly. More importantly, this is where our Token structure is going to be at.

As a side note, you mayyyy want to take note of these offsets as you will need these later as well 😉

Notice it is at offset 0x0f8 and also notice it is a _EX_FAST_REF structure. Let’s take a quick peep here on how this is structured:

In Windows, the address of the token is always going to have the last n bits zeroed out that way the address can be aligned. In 32 bit, the last three bits will be zeroed and in 64 bit, the last four bits will be zeroed. You can see those values by looking at the RefCnt field. Let’s take a look at our System’s token by using it’s address and offset.

So there is our lovely, somewhat System token. Here is where the whole last three bits come into play. To get the actual token, you can AND it with a 0xfffffff8 mask.

As a side note, you would use 0xfffffff0 as your mask for 64 bit systems

Voila! Here is our fine cut diamond! We can now make whatever application we want as NT! I’m looking at YOU cmd…

We get the address for cmd as we did for System. Since we know that the System’s token lies at offset 0x0f8 of the _EPROCESS structure,  we can call it directly and easily overwrite it with our new token.

Lo and behold, we are now greeted with the great NT Authority/System 🙂

Constructing the Payload

So where do we start off at? We can base it off of the payload that has been provided. No need to reinvent the wheel, but it’s always good to flex dem muscles 😉 Let’s break it down and see how to do it because there may or may not be a point in time when we will need to create our own!

To start, we can’t just call _EPROCESS like we did before. We have to find it. Just how we did for getting the Token, we will need to do that for _EPROCESS as well.

First thing is start by calling on the Kernel Processor Control Region, or KPCR. The KPCR will always be held at fs:[0] on 32 bit systems.

As a side note, the KPCR will always be held at gs:[0] for 64 bit systems

The address for _KPCR is at 0x807c9000. Let’s see what this has to offer us…

What we are interested in is the Kernel Processor Control Block, or _KPRCB, structure as this is going to have what we need. This is located at offset 0x120. Let’s see what this structure has in store for us…

Look at that last entry! That’s a lot of items in that structure!! Anyway, what we are looking for now is our _KTHREAD. More importantly, we want the CurrentThread, which is located at offset 0x004 pointing at 0x85e9b3c0. Let’s take a look at what _KTHREAD has to offer us…

Alas! We have now found our _EPROCE-wait a minute… I would imagine we are looking for _EPROCESS, but it’s not called _EPROCESS! What gives??

So we are in the _KPROCESS structure where Process is located at offset 0x150. _KPROCESS is actually part of the _EPROCESS structure. In fact, it’s the first entry of it! Take a look at its structure:

One thing you may also notice is that at offset 0x040, ApcState/_KAPC_STATE is there which is used by the payloads that are provided for us. You’ll also notice that Process/_KPROCESS is there. I chose the latter just to see if it makes a difference; I didn’t see anything different. Anywho…

Now that we have what we need, how does this look like in assembly? Let’s start building…

Next thing to do is to iterate through the running processes and check if we found the System’s PID. You’ll know when it’s System because the PID will be 4. You can view this in your Task Manager. Reboot a couple times as well, it’ll still be 4.

Translating this to assembly, I get the following:

After the token is found, we need to replace our current token to become NT Authority. Once that is done, the registers get restored to their original state and EAX gets zeroed for NT STATUS_SUCCESS.

 

Lastly, we restore code execution back to it’s normal state to avoid any pretty bluescreens!

Excuse my French, but how the HECK do you get POP EBP and RET 8?

When you overwrite your registers, you’ll notice that RETN 8 is the instruction in _TriggerStackOverflow.

You can see that by placing a breakpoint on the RETN 8 instruction and single step to the next instruction.

Now if you send a smaller buffer, you’ll notice that it leads you to POP EBP and RET 8.

Following those two instructions leads us to the end of the _IrpDeviceIoCtlHandler. So since we hijacked code execution, we restore what it was expecting and all is well!

Putting it all together, we get the following:

All that’s left to do is to compile it and dump the shellcode and there we have it! The shellcode broken down and how it was made 🙂

Lots of interesting and weird WinDBG commands and numbers and assembly, oh my!! But wait!! There’s more…Exploitation >:)

FINISH HIM!!!

In my last post, we had stopped once we had gotten control of our registers. Now it’s time to continue where we left out.

So with our newfound shellcode, we need a place to put it! We can easily accomplish this by using VirtualAlloc to allocate an executable space for our shellcode:

The next few lines are pretty self explanatory so I’ll be quick with it. We copy our shellcode into my executable space and insert the address of our shellcode into EIP:

Once we run our PoC, we are presented with the loveliest name of them all…NT Authority/System… <3

That was one hell of a ride! If you made it this far, you are one badass trooper and love the pain just as much as I do! Give this driver a shot and see how fun it is! There are quite a bit of vulnerabilities in this driver and I will be doing them all. I foresee many more rabbit holes and frustration in my future though…but I’m only doing it to myself 😉

Below is the final PoC for this exploit:

Now for our Python brethren:

Leave a Reply

Your email address will not be published. Required fields are marked *