Windows Kernel Exploitation Tutorial Part 6: Uninitialized Stack Variable

Overview

In the previous part, we looked into a simple NULL Pointer Dereference vulnerability. In this part, we’ll discuss about another vulnerability, Uninitialized Stack Variable. This vulnerability arises when the developer defines a variable in the code, but doesn’t initialize it. So, during runtime, the variable would have some value, albeit an unpredictable one. How this issue could be exploited by an attacker, we’d see in this part.

Again, huge thanks to @hacksysteam for the driver.


Analysis

Let’s analyze the UninitializedStackVariable.c file:

The issue is clearly mentioned, as the UninitializedStackVariable in the insecure version is not initialized to a value as in the Secure version. But that’s not the only problem here. The uninitialized variable is then called in the callback() function, which leads to this vulnerability.

Analyzing this vulnerability in IDA makes things a little more clearer:

We can see that if our comparison fails with our **Magic** value, the execution lands up in our vulnerable function, with a call to our callback at some offset from our ebp.

So, if we can control what’s there under the callback address, we should reliably be able to direct the flow to our shellcode. With that in mind, let’s jump onto the exploitation then.


Exploitation

Let’s start with our skeleton script:

We see no crash, and execution completes normally.

Now, let’s change our **Magic** value to something else and analyze what happens.

This triggers our vulnerable function with the callback call. Now, as we discussed earlier, we somehow need to control the callback value to our shellcode’s pointer, so as when the call is made to this address, it actually initializes our shellcode.

To do this, the steps we need to follow:

  • Find the kernel stack init address
  • Find the offset of our callback from this init address
  • Spray the Kernel Stack with User controlled input from the user mode. (Good read about it can be found here by j00ru).

To find the kernel stack init address, run the !thread command, and then subtract the callback address from the stack init address to find the offset.

We get an offset of 0x524. You can confirm if this offset remains same through multiple runs. This won’t matter that much though as we’d be spraying the whole stack upto a certain length with our shellcode address using NtMapUserPhysicalPages function:

Not exactly the same function on MSDN, but the basic layout for the parameters is similar. More information about this function is found in the article above by j00ru.

Using this API, we can spray upto 1024*sizeof(ULONG_PTR), enough to cover our offset easily. Let’s spray our kernel stack with 0x41414141 and put a breakpoint at the end of NtMapUserPhysicalPages to analyze our spray:

Awesome, our desired address contains our sprayed value.

Now, just include our shellcode from our previous post, and spray the address onto the kernel stack.

Final exploit would look like:

One thought on “Windows Kernel Exploitation Tutorial Part 6: Uninitialized Stack Variable

Leave a Reply

Your e-mail address will not be published. Required fields are marked *