2

I have recently been doing some research into kernel exploitation on X86_64. A problem I have run into is that I have found Intel's SMEP to be killing my contrived example of a kernel NULL pointer dereference which I have been working on.

Can you/how do you disable SMEP on linux? I have managed to remove SMAP (Security Mode Access Protection) on Linux kernel 3.8.x by disabling the functionality in the .config file but my problem still persists. I assume SMEP must be disabled differently from SMAP, given that after disabling it, execution of my mapped NULL page is still instantly killed as soon as execution is diverted within kernel-space.

I have already set mmap_min_addr to 0 so please no comments telling me to alter this value in /proc/sys/vm :).

4

SMEP is activated by bit 20 of control register CR4 while SMAP is bit 21. Disabling it can therefore be done, at least, by patching the kernel code in order to remove the setting of this bit.

The relevant code seems to be in file arch/x86/kernel/cpu/common.c, around line 269:

    if (cpu_has(c, X86_FEATURE_SMEP))
            set_in_cr4(X86_CR4_SMEP);

Just comment that out, recompile, reboot. (I have not tested it.)

  • Thats interesting, I had read that it was controlled by that bit but wasn't sure whether there was a .config file option for disabling it (as with SMAP). I will give this a try and if it works I'll mark your response as correct :). Cheers, A. – A.Smith Oct 28 '13 at 11:28
  • Have just found a nice easy way to get around this issue without editing/recompiling the kernel. Will post it as soon as my 8 hours are up :) – A.Smith Oct 28 '13 at 14:24
3

It seems SMEP can be disabled (on linux) using a boot parameter. While I am certain that the suggestion above works (disabling the kernel-land code is an obvious choice I wish I had done sooner :P) the following may be an easier way of achieving the same end result.

I found information here regarding how to do this.

It seems that by adding the kernel boot parameter nosmep to the boot parameters as explained in the link above, SMEP can be disabled. I have also found by looking at this link to the kernel.org documentation that there are other parameters which can be used to turn off other various protection mechanisms such as NX or apparmour.

To confirm if SMEP has been disabled you can type the following command into your terminal:

cat /proc/cpuinfo | grep smep

This command prints the contents of the /proc/cpuinfo file and pipes the output into grep to try and find the flag smep in the output.

If the command returns a value (most likely smep will be the returned value, if enabled) then SMEP is enabled, otherwise if no value is returned (i.e grep returns nothing back to the terminal), SMEP has been successfully disabled.

Hope this helps anyone else in my position. I intend to do a write-up on my blog regarding the specifics of SMEP and how to bypass/disable it. I will post the link here after I have written the post :).

Thanks to all that helped!

A.

0

You could disable SMEP by using an in-kernel ROP chain, which was not told by the other answerers here. No need to patch or recompile or reboot. Just search the kernel binary for ROP gadgets. An example of code that would disable SMEP would be: (I think it would be easy to find variations of this on all kernels) (Warning, Intel Syntax)

mov eax , cr4
and eax , 0xfff ; This disables both SMAP and SMEP, as the higher 20 bits are cleared
mov cr4 , eax

An example of an ROP chain I found on a real kernel (I leveraged this to jump to userland):

0xaddr1: mov eax, cr4 ; pop ebp ; ret
0xaddr2: and eax, 0xfff ; ret
0xaddr3: mov cr4, eax ; pop ebp ; ret

There are lots of resources on Google.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.